I have an array state for some checkboxes where I am catching the labels for those that are true (checked). Must ignore the false.
I am able to generate a list of checked checkboxes thanks to some of you in another thread. But I'm hitting another wall with the select all toggle.
const handleSwitch = (e) => {
if(e.target.checked) {
setActive(true);
const updatedCheckedState = checkedState.map(element => element.checked = true);
setCheckedState([...updatedCheckedState]);
} else {
setActive(false)
const updatedCheckedState = checkedState.map(element => element.checked = false);
setCheckedState([...updatedCheckedState]);
}
}
This function above in particular. Likewise, if I manually check all of the checkboxes inside, it needs to know that all are selescted and make the active state = true. If I can get help with at least the first part, I'm confident I can solve the other part myself.
Here's a sandbox if you want to mess around with it. Thanks
CodePudding user response:
Your sandbox is quite broken. The way you are tracking checked state is internally inconsistent.)
The main culprits (in Filter.js) are:
- on line 119, you treat checkedState like a dictionary, but in
handleSwitch
andhandleOnChange
you treat it like an array (but the logic inside is still non-functional for the array approach as far as I can tell.- if you want it to be an array, let it be a string-valued "checkedLabels" array, and set
checked
on your checkbox component tocheckedLabels.includes(item.label)
- if you want it to be a dictionary:
handleOnChange
needs to simply toggle the currently clicked element, like so[e.target.name]: !checkedState[e.target.name]
handleSwitch
needs to add an entry for every element indata
, set totrue
orfalse
as appropriate.
- if you want it to be an array, let it be a string-valued "checkedLabels" array, and set
Example (codesandbox):
const handleSwitch = (e) => {
if (e.target.checked) {
setActive(true);
setCheckedState(
Object.fromEntries(data.map((item) => [item.label.toLowerCase(), true]))
);
} else {
setActive(false);
setCheckedState({});
}
};
const handleOnChange = (e) => {
setCheckedState({
...checkedState,
[e.target.name]: !checkedState[e.target.name]
});
};
<CustomCheckbox
size="small"
name={item.label.toLowerCase()}
checked={checkedState[item.label.toLowerCase()] ?? false}
onChange={handleOnChange}
/>
CodePudding user response:
Adding to @JohnPaulR answer. You can add useEffect hoot to achieve additional requirements you have.
if I manually check all of the checkboxes inside, it needs to know that all are selected and make the active state = true.
useEffect(() => {
const checkedTotal = Object.keys(checkedState).reduce((count, key) => {
if (checkedState[key]) {
return count 1;
}
}, 0);
setActive(data.length === checkedTotal);
}, [checkedState]);
A full working example https://codesandbox.io/s/still-water-btyoly