Let's say we want to have input for our favorite foods and we want to show it on the page.
First, we should prepare two variables, one for the food list, and another for a list of the selected food which is empty by default.
this.state = {
foods: [
{
id: 1,
name: '🍕'
},
{
id: 2,
name: '🍙'
},
{
id: 3,
name: '🍰'
},
],
selected: [],
}
Now we make the form and show the selected
state.
<form>
<p>
{ JSON.stringify(this.state.selected) }
</p>
<p>Foods</p>
{
this.state.foods.map(item => {
return (
<label key={ item.id }>
<input type="checkbox"></input>
<span>{ item.name }</span>
</label>
)
})
}
</form>
For checkbox input, we need to add selected
and the usual onChange
attributes.
<input type="checkbox"
onChange={ () => this.onChange(item.id) }
selected={ this.state.selected.includes(item.id) }
></input>
The selected
attribute accepts a boolean value that specifies if the input should be 'pre-selected' (checked) or not. And the onChange
attribute will be triggered each time the input is checked and unchecked.
So because of this behavior, we have to put a function on the onChange
attribute.
onChange(id) {
let selected = this.state.selected
let find = selected.indexOf(id)
if(find > -1) {
selected.splice(find, 1)
} else {
selected.push(id)
}
this.setState({ selected })
}
find
is a variable that checks whether the checked item is in the selected
array or not. find > -1 means that the item exists in the selected variable and it is checked so we want to remove it from the selected list while find == -1 means the opposite. The item doesn't exist in the selected array so we want to add it to the array.
Now it should look like this
Beyond IDs
If you want to keep the whole object (not only the id), we can change the way we find the index and push the item to the selected array
onChange(id) {
let selected = this.state.selected
// instead of using indexOf, we can use findIndex to look through array of objects
let find = selected.findIndex(item => item.id === id)
if(find > -1) {
selected.splice(find, 1)
} else {
// We can use find to get the item based on its id
selected.push(this.state.foods.find(item => item.id === id))
}
this.setState({ selected })
}
Now it should look like this
Sorting
And finally, basically the selected array has no specific order so if you want to keep the order you can add some sorting method before we use the setState
.
// sort by id in ascending order
selected.sort((a, b) => a.id - b.id)
Top comments (2)
Hey Thank you So Much,
I got inspiration for the WordPress Gutenberg block....
You're welcome!