How do I set the head checkbox state when cell checkboxes change?
This article explains about working with the Syncfusion checkbox component, particularly within a grid or list where a header checkbox is used to control the state of the cell checkboxes. It’s important to ensure that the header checkbox reflects the correct state based on the individual selections of the cell checkboxes. This article will guide you through the process of setting the state of the header checkbox dynamically as the cell checkboxes are checked or unchecked.
Overview
The functionality involves a collection of checkboxes and a header checkbox to control the overall selection:
- The header checkbox should select or deselect all checkboxes.
- The header checkbox should reflect an indeterminate state when some, but not all, checkboxes are selected.
Step-by-Step Implementation
1. Define Your State
Initialize your individual checkboxes and a separate state for the header checkbox.
const [checkboxes, setCheckboxes] = useState([
{ id: 1, label: 'CheckBox 1', isChecked: false },
{ id: 2, label: 'CheckBox 2', isChecked: false },
{ id: 3, label: 'CheckBox 3', isChecked: false },
]);
const [headerCheckboxState, setHeaderCheckboxState] = useState({
checked: false,
intermediate: false,
});
2. Synchronize the State
Use the useEffect hook to update the header checkbox’s state based on changes to the individual checkboxes.
useEffect(() => {
const checkedCount = checkboxes.filter((checkbox) => checkbox.isChecked).length;
const allChecked = checkedCount === checkboxes.length;
const someChecked = checkedCount > 0 && checkedCount < checkboxes.length;
setHeaderCheckboxState({
checked: allChecked,
intermediate: someChecked && !allChecked,
});
// Optional DOM manipulation for setting the indeterminate property
const headerCheckbox = document.getElementById('headerCheckboxId');
if (headerCheckbox) {
headerCheckbox.checked = allChecked;
headerCheckbox.indeterminate = someChecked && !allChecked;
}
}, [checkboxes]);
3. Render the Checkboxes
return (
<div className='control-pane'>
<div className='control-section'>
<div className='checkbox-control'>
{/* Master Checkbox */}
<div className='row'>
<CheckBoxComponent
id="headerCheckboxId"
label='Header'
checked={headerCheckboxState.checked}
onChange={handleHeaderChange}
/>
</div>
{/* Individual Checkboxes */}
{checkboxes.map((checkbox) => (
<div key={checkbox.id} className='row'>
<CheckBoxComponent
label={checkbox.label}
checked={checkbox.isChecked}
onChange={() => handleCheckboxChange(checkbox.id)}
/>
</div>
))}
</div>
</div>
</div>
);
4. Create Handler Functions
Define functions to handle the selection changes for both the individual checkboxes and the header checkbox.
const handleHeaderChange = () => {
const allChecked = checkboxes.every((checkbox) => checkbox.isChecked);
const updatedCheckboxes = checkboxes.map((checkbox) => ({
...checkbox,
isChecked: !allChecked,
}));
setCheckboxes(updatedCheckboxes);
};
const handleCheckboxChange = (checkboxId) => {
const updatedCheckboxes = checkboxes.map((checkbox) =>
checkbox.id === checkboxId
? { ...checkbox, isChecked: !checkbox.isChecked }
: checkbox
);
setCheckboxes(updatedCheckboxes);
};
Demo Sample Link
Refer to the working sample for additional details and implementation: Syncfusion CheckBox Example.
Output:
Additional References
- Syncfusion CheckBox Documentation: Syncfusion CheckBox Component
- React State and Lifecycle: React Docs - State and Lifecycle
- React useEffect Hook: React Docs - Using the Effect Hook