Creating a master checkbox in a header cell
The article instructs how to create a master checkbox for a column with checkboxes with the following behaviour:
- when all cells in a column are checked, a master checkbox in a header becomes checked as well
- checking/unchecking a master checkbox checks/unchecks all cells in a column
More about custom cell content you can find here.
Adding a checkbox to a table cell
We assume that we have data items with the checked
field, where the boolean value is stored. You can use either an HTML checkbox or import Checkbox from @svar-ui/svelte-core library to render the column value. Use $props
to access row and column data as well as Grid api.
Then we update row data by calling the update-cell
action when the checkbox value is changed:
<script>
import { Checkbox } from "@svar-ui/svelte-core";
let { row, column, api } = $props();
function onChange(ev) {
const { value } = ev;
//execute update action
api.exec("update-cell", {
id: row.id,
column: column.id,
value,
});
}
</script>
<Checkbox value={row[col.id]} onchange={onChange} />
And finally we apply a checkbox component to a Grid column by using the cell
property of a column element in the columns
array:
<script>
import { Grid } from "@svar-ui/svelte-grid";
import { getData } from "../data";
import { CheckboxCell } from "../custom/CheckboxCell.svelte";
const data = getData();
const columns = [
{
id: "checked",
cell: CheckboxCell,
header: "", // master checkbox will be rendered here in the next step
width: 36,
}
];
</script>
<Grid {data} {columns} />
Adding a checkbox to a header cell
Ready-made components are added to the header/footer cells in the same way as to column cells. We use $props
to access Grid api and the onaction
property to send a custom callback event to Grid. The event is sent each time a master checkbox changes its state either from manual clicks or data changes (when all rows are checked or one of them gets unchecked):
<script>
import { Checkbox } from "@svar-ui/svelte-core";
let { api, onaction } = $props();
let value = $state(false);
api.getReactiveState().data.subscribe(data => onCellCheck(data));
function onCellCheck(data) {
if (!data) ({ data } = api.getState());
const checked = data.every(d => d.checked === true);
// all rows are checked / unchecked
if (value !== checked) {
onaction &&
onaction({
action: "custom-header-check",
data: { value: checked },
});
value = checked;
}
}
function onChange(ev) {
const { value } = ev;
// manual click on a checkbox
onaction &&
onaction({
action: "custom-header-check",
// add eventSource to differentiate it from subscription to data
data: { value, eventSource:"click" },
});
}
</script>
<Checkbox bind:value onchange={onChange} />
Now you can import this component to Grid and apply it to a header cell by adding its name as the value of the cell
parameter of the header
element in the columns
array. To handle clicks on a master checkbox, you need to handle the custom event it sends.
When the header checkbox is clicked, the action
function is invoked with the argument "header-checkbox", which then triggers the checkHeader
function. In the checkHeader
function, the state of all checkboxes in the column is updated based on the value of the header checkbox.
<script>
import { Grid } from "@svar-ui/svelte-grid";
import { getData } from "../data";
import CheckboxCell from "../custom/CheckboxCell.svelte";
import HeaderCheckboxCell from "../custom/HeaderCheckboxCell.svelte";
let { data } = $state(getData());
let api = $state();
const columns = [
{
id: "checked",
cell: CheckboxCell,
header: [{ cell: HeaderCheckboxCell }], //master checkbox
width: 36,
},
];
// update all `checked` fields when header checkbox is clicked
function onHeaderCheck(ev) {
const { value, eventSource } = ev;
// ensure that the event source is "click"
// meaning it's a manual change (not from subscription to data)
if (eventSource == "click") {
data = api.getState().data.map(d => {
d.checked = value;
return d;
});
}
}
</script>
<Grid
{data}
{columns}
oncustomheadercheck={ev => onHeaderCheck(ev)} // Handle clicks on master checkbox
/>
Related articles: Adding custom content to cells