Grouped Options
Checkboxes live inside labeled fieldsets. Changes stage in a draft set and only commit when the user clicks Apply, so rapid toggling never churns the outer state.
Built-in Features
Any .nds-multiselect on the page wires up on load. The inner dropmenu boots itself so the trigger, panel, and keyboard flow work without extra JS.
Checkbox toggles stage into a draft set and only commit when the user clicks Apply. Closing the panel without applying discards the draft, so rapid exploration never churns the chips or change events.
Applied values render as chips inside the form-control. Clicking a chip drops the value and fires a change event immediately, no need to reopen the panel.
Applied values ship as <input type="hidden" name="field[]"> entries inside the form-control, so wrapping the field in a <form> posts the selection as an array without extra wiring.
Arrow keys walk the checkboxes, Space toggles, Enter triggers Apply, and Escape closes the panel and returns focus to the trigger. A visible focus ring follows each option.
Every field exposes an instance on the DOM node with apply(), reset(), and removeValue(). Listen for nds:multiselect:change to react to committed selections.
Usage Guidelines
Best Practices
- Use multiselect for form fields where users pick several values from a list of ten or more options and benefit from seeing the applied set as chips they can remove individually
- Group related options inside
<fieldset>elements with a<legend>. Groups make long lists scannable and let assistive technology announce the category - For a short, flat list (three to six options) without a category axis, reach for a plain Checkbox Group instead. Multiselect's overhead (dropmenu trigger, Apply button, chip track) adds friction when the options fit inline
- For a single-value choice, use Radio Button or the select-mode of Dropmenu. Multiselect's draft/apply pattern is wasted on single-pick fields
- Set
data-multiselect-namewhen the field lives inside a<form>. Without it, no hidden inputs are rendered and the selection does not post - Set a meaningful
data-labelon each checkbox so chip text stays readable when the surrounding label changes, wraps, or contains extra markup - Keep the placeholder short (two to four words). It shares the row with chips once any are applied, so a long placeholder fights for space
- Add a
<hr class="nds-divider">between fieldsets in the panel to make the grouping visually clear, matching the provided markup contract - When the number of selections carries meaning (quota, pricing tier), listen for
nds:multiselect:changeand show a count or validation hint outside the field rather than overloading the placeholder
Data Attributes
| Attribute | Description |
|---|---|
data-multiselect-name | Set on .nds-multiselect. Name used for hidden form inputs, posted as name[]. Omit to opt out of form submission |
data-chip-class | Set on .nds-multiselect. Classes applied to generated chips. Defaults to nds-primary nds-sm |
data-multiselect-dropmenu | Marks the wrapping .nds-form-action.nds-prefix.nds-dropmenu as the host of the options panel |
data-multiselect-chips | Marks the container that receives rendered chips. Required inside .nds-form-control |
data-multiselect-action | Set on footer buttons. Values: apply commits the draft and fires nds:multiselect:change; reset clears the draft without touching the applied set |
data-label | Set on each checkbox input. Overrides the visible label text when rendering chips, useful when the visible label contains extra markup or context |
data-no-auto-close | Set on the checkbox fieldset and the Reset button so the dropmenu stays open while the user toggles options or clears the draft |
JavaScript API
The NDS.Multiselect namespace initializes all .nds-multiselect fields on load. Each instance lives on its DOM node as element.ndsMultiselect and exposes methods for programmatic control. Listen for nds:multiselect:change to react to committed selections.