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 wx-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 "wx-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 "wx-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 "wx-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 "wx-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