Comments (9)
boom! thanks for the help
https://github.com/crossfield/gutenblock/blob/master/plugin/src/notes/edit.js
https://github.com/crossfield/gutenblock/releases/tag/0.6.5
from gutenblock.
So the repeat field is currently meant to be used in the inspector, mainly because we have too many components to build to make a nice 100% inside gutenberg (without inspector) ui for editing and adding items. But making it work nicey like you want shouldn't take too much. The repeat component just expects to get two props, which the Inspector
component passes in: https://github.com/crossfield/gutenblock/blob/master/controls/src/base/inspector.js
If you pass attributes as a prop and an onChange prop, it will work where you want. The reason I made the Inspector component map through props and inject, is because when in the inspector it's not rendered as a child of the component, so i can't use context. Which is what i would have rather done, and it would work in the case of rendering normally, like you are trying to do.
I hope that makes sense but i might not have explained it well.
TLDR; pass in attributes as a prop to repeat when not using Inspector
around it and an onChange prop as seen in the Inspector above
const Edit = ({ attributes, setAttributes }) => {
return (
<Repeat
attributes={attributes}
onChange={(name, value) => setAttributes({ [name]: value })}
title="Notes"
max="50"
addNew="Add Field" attribute="notes"
>
{attributes.notes.map(tab => {
return <Input name="title" />
})}
</Repeat>)
};
from gutenblock.
Okay thanks for the insight - going to dig into your source code a bit so I understand better but I get the gist of what you're saying.
from gutenblock.
Noting this if others end up trying to do this:
Got this working but had to make changes to Repeat.js . Working now for Inspector + Editor.
@zackify Happy to submit a PR if you like.
Edit.js
const Edit = ({ attributes, setAttributes }) => {
return (
<div>
<Repeat
attributes={attributes}
onChange={(name, value) => setAttributes({ [name]: value })}
setAttributes={setAttributes}
title="Notes"
max="50"
addNew="Add Item" attribute="notes"
>
<Input name="title" />
</Repeat>
</div>
)
};
Repeat.js
//added this to push the new item to attributes without this local state gets out of sync
//i.e. getDerivedStateFromProps doesn't keep up with local state
add() {
let { attribute, attributes, setAttributes } = this.props;
let items =
attributes && attributes[attribute] ? attributes[attribute] : [];
setAttributes({ [attribute]: [...items, {}] })
}
//render
render() {
let { items } = this.state;
let { style, title, addNew, addItem, max, attribute } = this.props;
let repeats = [];
for (let item = 0; item < items; item++) {
repeats.push(this.renderChildren(item));
}
return (
<div style={style}>
<h1>{title}</h1>
<div>
{repeats}
<div style={{ marginTop: '10px' }}>
{max > items || !max ? (
<Button
isPrimary
onClick={() => {
this.setState(function (prevState, props) {
return { items: prevState.items + 1 }
}, () => {
this.props.setAttributes && this.add();
})
}}
>
{addNew}
</Button>
) : null}
</div>
</div>
</div>
);
}
from gutenblock.
I think there’s got to be a better way to make it work without ditching derivedstatefromprops. Otherwise I’d say go for the PR. I am going to copy in all your code and see what’s up and if I can simplify the repeat more for when inside of the editor :)
from gutenblock.
Still using getDerivedStateFromProps:
Added add() + calling from add item button click
import React from 'react';
const { Button } = wp.components;
export default class Repeat extends React.Component {
constructor({ attribute, attributes }) {
super();
this.update = this.update.bind(this);
this.delete = this.delete.bind(this);
this.add = this.add.bind(this);
let items =
attributes && attributes[attribute] ? attributes[attribute] : [];
this.state = { items: items.length };
}
static getDerivedStateFromProps({ attributes, attribute }, state) {
let items =
attributes && attributes[attribute] ? attributes[attribute] : [];
if (items.length !== state.items) return { items: items.length };
return null;
}
add() {
let { attribute, attributes, setAttributes } = this.props;
let items =
attributes && attributes[attribute] ? attributes[attribute] : [];
setAttributes({ [attribute]: [...items, {}] })
}
update(name, value, tabId, onChange) {
let { attribute, attributes } = this.props;
let currentAttributes = attributes[attribute] || [];
let foundAttribute = currentAttributes.find(
(attr, index) => index === tabId
);
let newAttributes;
if (!foundAttribute)
newAttributes = [...currentAttributes, { [name]: value }];
else
newAttributes = currentAttributes.map(
(attr, index) => (index === tabId ? { ...attr, [name]: value } : attr)
);
return onChange(attribute, newAttributes);
}
delete(tabId, onChange) {
let { attribute, attributes } = this.props;
let newAttributes = attributes[attribute].filter(
(attr, index) => index !== tabId
);
return onChange(attribute, newAttributes);
}
renderChildren(index) {
let {
attribute,
children,
setAttributes,
attributes,
onChange,
} = this.props;
return (
<div
style={{
marginLeft: '10px',
marginTop: '15px',
}}
>
{React.Children.map(children, child =>
React.cloneElement(child, {
key: index,
index,
setAttributes,
attributes:
attributes &&
attributes[attribute] &&
attributes[attribute][index]
? attributes[attribute][index]
: {},
onChange: (name, value) =>
this.update(name, value, index, onChange),
})
)}
<div onClick={() => this.delete(index, onChange)}>Delete item</div>
</div>
);
}
render() {
let { items } = this.state;
let { style, title, addNew, addItem, max, attribute } = this.props;
let repeats = [];
for (let item = 0; item < items; item++) {
repeats.push(this.renderChildren(item));
}
return (
<div style={style}>
<h1>{title}</h1>
<div>
{repeats}
<div style={{ marginTop: '10px' }}>
{max > items || !max ? (
<Button
isPrimary
onClick={() => {
this.setState(function (prevState, props) {
return { items: prevState.items + 1 }
}, () => {
this.props.setAttributes && this.add();
})
}}
>
{addNew}
</Button>
) : null}
</div>
</div>
</div>
);
}
}
from gutenblock.
from gutenblock.
No worries - just noting what I tracked down.
Here's what I'm seeing without my mods (kind of works than ... wipes out the inputs)
from gutenblock.
from gutenblock.
Related Issues (17)
- Repeat - Delete Button -> Add a class for styling HOT 2
- Add ability to change ports HOT 7
- How to add css or scss? HOT 11
- How to translate strings with wp.i18n HOT 2
- InspectorControls HOT 7
- Updating plugin in docker WP erases folder and fails HOT 1
- Child/attribute based repeating inputs HOT 1
- webpack-serve deprecated HOT 2
- Error in watch in windows HOT 1
- Use with npx? HOT 2
- Gutenburg 4.x support HOT 1
- Missing loader? HOT 7
- Uncaught Error: only one instance of @babel/polyfill is allowed HOT 9
- Fix project prefix HOT 1
- MySql error on starting Docker HOT 4
- WP Admin - Plugin update screen HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from gutenblock.