data-select-all
Master checkbox for bulk selection. Add data-select-all to a checkbox to control a group of related checkboxes with indeterminate state and count display.
Overview
The data-select-all attribute enhances a checkbox to act as a master toggle for a group of target checkboxes. When toggled, all targets check or uncheck together. When individual targets are changed, the master reflects an indeterminate state if some (but not all) are selected.
<table> <thead> <tr> <th><input type="checkbox" data-select-all=".row-select" aria-label="Select all"></th> <th>Name</th> <th>Email</th> </tr> </thead> <tbody> <tr> <td><input type="checkbox" class="row-select"></td> <td>Alice Johnson</td> <td>alice@example.com</td> </tr> <tr> <td><input type="checkbox" class="row-select"></td> <td>Bob Smith</td> <td>bob@example.com</td> </tr> <tr> <td><input type="checkbox" class="row-select"></td> <td>Carol White</td> <td>carol@example.com</td> </tr> </tbody></table>
How It Works
- Add
data-select-allto a checkbox, with the value set to a CSS selector matching the target checkboxes - The init script scopes targets to the nearest
<table>,<form>,<fieldset>, or[data-select-all-scope]ancestor — falling back todocument - Toggling the master checks/unchecks all targets and dispatches
changeevents on each - Toggling any individual target syncs the master: all checked = checked, some checked = indeterminate, none checked = unchecked
- A
select-all:changecustom event is dispatched on every state change
Attributes
| Attribute | Type | Description |
|---|---|---|
data-select-all |
string | CSS selector for the target checkboxes (e.g., .row-select). |
data-selected-count |
boolean | Place on a separate element to display the number of selected items. Updated automatically. |
data-select-all-scope |
boolean | Place on an ancestor element to scope the master/target relationship. Useful when the same target selector appears in multiple groups. |
data-select-all-init |
boolean | Set automatically to prevent double-binding. Do not set manually. |
Selected Count Display
Add data-selected-count to any element within the same scope to show a live count of selected items.
<p>Selected: <strong data-selected-count>0</strong> items</p> <table> <thead> <tr> <th><input type="checkbox" data-select-all=".row-select" aria-label="Select all"></th> <th>Name</th> </tr> </thead> <tbody> <tr> <td><input type="checkbox" class="row-select"></td> <td>Alice</td> </tr> <tr> <td><input type="checkbox" class="row-select"></td> <td>Bob</td> </tr> </tbody></table>
The count element's textContent is updated on every state change, including the initial sync.
Checkbox List
Works with any checkbox group, not just tables. Use a <fieldset> with data-select-all-scope to scope the group:
<fieldset data-select-all-scope> <legend> <label> <input type="checkbox" data-select-all=".option-check"> Select all options </label> </legend> <label><input type="checkbox" class="option-check"> Option A</label> <label><input type="checkbox" class="option-check"> Option B</label> <label><input type="checkbox" class="option-check"> Option C</label> <label><input type="checkbox" class="option-check"> Option D</label></fieldset>
Scoping
The master checkbox automatically scopes its target lookup to the nearest ancestor that is a <table>, <form>, <fieldset>, or an element with [data-select-all-scope]. This allows multiple independent select-all groups on the same page, even with the same CSS selector for targets.
<!-- Scoping to a fieldset --><fieldset data-select-all-scope> <legend> <label> <input type="checkbox" data-select-all=".item"> Select all in this group </label> </legend> <label><input type="checkbox" class="item"> Item 1</label> <label><input type="checkbox" class="item"> Item 2</label></fieldset> <!-- Another group with the same selector, scoped separately --><fieldset data-select-all-scope> <legend> <label> <input type="checkbox" data-select-all=".item"> Select all in this group </label> </legend> <label><input type="checkbox" class="item"> Item 3</label> <label><input type="checkbox" class="item"> Item 4</label></fieldset>
Events
The master checkbox dispatches a select-all:change event on every state change (master toggle or individual target change).
| Event | Detail | Description |
|---|---|---|
select-all:change |
{ checked: number, total: number, selected: Element[] } |
Fired on every state change. checked is the count of selected targets, total is the total target count, and selected is an array of checked target elements. |
const master = document.querySelector('[data-select-all]'); master.addEventListener('select-all:change', (e) => { console.log('Checked:', e.detail.checked); console.log('Total:', e.detail.total); console.log('Selected elements:', e.detail.selected);});
Dynamic Elements
Select-all checkboxes added to the DOM after page load are automatically enhanced via a MutationObserver. No manual initialization is needed.
<section> <h2>Accessibility</h2> <ul> <li>Uses the native <code>indeterminate</code> property on the master checkbox, which is announced by screen readers as "mixed"</li> <li>Each target checkbox receives a real <code>change</code> event when toggled by the master, ensuring form validation and other listeners fire correctly</li> <li>Works with any focusable checkbox element, preserving keyboard accessibility</li> <li>Add <code>aria-label="Select all"</code> to the master checkbox when it lacks a visible label (e.g., in a table header)</li> <li>Without JavaScript, checkboxes remain functional — progressive enhancement</li> </ul> </section>