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

  1. Add data-select-all to a checkbox, with the value set to a CSS selector matching the target checkboxes
  2. The init script scopes targets to the nearest <table>, <form>, <fieldset>, or [data-select-all-scope] ancestor — falling back to document
  3. Toggling the master checks/unchecks all targets and dispatches change events on each
  4. Toggling any individual target syncs the master: all checked = checked, some checked = indeterminate, none checked = unchecked
  5. A select-all-change custom 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.

// Dynamically added select-all checkboxes are auto-enhanced via MutationObserver const master = document.createElement('input'); master.type = 'checkbox'; master.dataset.selectAll = '.dynamic-check'; document.body.appendChild(master); // master is ready to use — no manual init needed

Accessibility

  • Uses the native indeterminate property on the master checkbox, which is announced by screen readers as "mixed"
  • Each target checkbox receives a real change event when toggled by the master, ensuring form validation and other listeners fire correctly
  • Works with any focusable checkbox element, preserving keyboard accessibility
  • Add aria-label="Select all" to the master checkbox when it lacks a visible label (e.g., in a table header)
  • Without JavaScript, checkboxes remain functional — progressive enhancement