Skip to content

Searchable multi-select

Preview Available in release assets

Filter and submit multiple server-authoritative options through Datastar fragments while preserving an ordinary multi-value form fallback. The primary fixture uses a checkbox group; a native multiple-select is a separate alternative, not a second control model in the same fixture.

Server contract

Use .thin-searchable-select on a real form with a stable results id. Bind the query and call a pinned Datastar 1.0.2 GET endpoint. The primary fixture submits repeated name=topics checkbox values from a fieldset plus hidden selected values in the selections list. A native select[multiple] is a separate alternative authoring variant and is not present in the primary fixture. The server owns available options, selected IDs, permissions, validation, and returned fragments.

Without Datastar or JavaScript, the primary fixture's query, checked checkbox values, and remove submit buttons use ordinary form submission. A native select[multiple] may be authored as a separate alternative control; it is not combined with the checkbox group. Author the receiving endpoint to return the complete page with options, selections, and errors.

Searchable multi-select primary example

Show code
<form class="thin-searchable-select" id="topic-select" action="/api/advanced/multiselect" method="get" data-signals="{q: ''}" data-on:input__debounce.250ms="@get('/api/advanced/multiselect')">
  <label class="thin-field" for="topic-query">Find topics<input class="thin-input" id="topic-query" name="q" type="search" data-bind:q aria-describedby="topic-status" />
</label>
<section id="topic-results">
  <p class="thin-searchable-select-status" id="topic-status" aria-live="polite">3 available topics.</p>
  <ul class="thin-searchable-select-selections" aria-label="Selected topics">
    <li class="thin-searchable-select-selection">Accessibility <button type="submit" name="remove" value="accessibility" aria-label="Remove Accessibility">×</button>
    <input type="hidden" name="topics" value="accessibility">
  </li>
</ul>
<fieldset class="thin-searchable-select-options">
  <legend>Available topics</legend>
  <label>
    <input type="checkbox" name="topics" value="css"> CSS</label>
    <label>
      <input type="checkbox" name="topics" value="html"> HTML</label>
      <label>
        <input type="checkbox" name="topics" value="performance"> Web performance with an intentionally long localized label</label>
      </fieldset>
    </section>
    <button class="thin-button" type="submit">Apply topics</button>
  </form>

Anatomy

  • Native search field
  • Server result/status fragment
  • Selected-value list with hidden values
  • Checkbox group (primary fixture)
  • Accessible remove submit buttons
  • Apply submit button

Variants and sizes

  • Checkbox group (primary fixture)
  • Native multiple-select (alternative)
  • Datastar-filtered checkbox group

Gallery coverage: No structured variant fixtures are published yet; the primary example above is the only verified production markup.

Rendered fixtures exercise authored content and constrained layouts with the same production assets.

  • Initial options
  • Query
  • Pending
  • Selected values
  • Empty results
  • Server error
  • Invalid selection
  • Long labels
  • Reconnected fragment

Structured state fixtures are not published for this item yet.

Interaction and keyboard behavior

Typing sends a debounced Datastar GET and the server replaces the stable results fragment. In the primary fixture, checking the checkbox group, removing a selected value, and applying submit ordinary named values; the server validates identifiers and returns the complete authoritative selection. A native multiple-select is an alternative native control model, not part of the primary checkbox-group fixture. Pending, empty, and error responses remain server-authored. Reconnection requests the current query and selected values again.

Accessibility

The primary fixture uses a visible search label, a fieldset and legend for its checkbox group, and a polite status after completed searches. If an application adds a pending indicator, set aria-busy only while a request is pending. Every remove button must name the value it removes. Applications that morph results should preserve focus when possible, return validation errors in text, and never make chips the only submitted controls.

Contract
NATIVE
Basis
Native search input and checkbox group; deliberately not a listbox because options are controls and must not be nested in a listbox
Behavior guarantees
  • Remains a native checkbox or multiple-select form; it is never treated as a listbox.
Evidence
  • tests/unit/library/searchable-multiselect.test.ts
  • tests/unit/library/advanced-component-contracts.test.ts

API

Use .thin-searchable-select on a real form with a stable results id. Bind the query and call a pinned Datastar 1.0.2 GET endpoint. The primary fixture submits repeated name=topics checkbox values from a fieldset plus hidden selected values in the selections list. A native select[multiple] is a separate alternative authoring variant and is not present in the primary fixture. The server owns available options, selected IDs, permissions, validation, and returned fragments.

Behavior tier: datastar-required

Structured host, property, and example tables are not authored for this item yet. Use the summary above and the primary example.

Fallback

Without Datastar or JavaScript, the primary fixture's query, checked checkbox values, and remove submit buttons use ordinary form submission. A native select[multiple] may be authored as a separate alternative control; it is not combined with the checkbox group. Author the receiving endpoint to return the complete page with options, selections, and errors.

Assets and dependencies

  • /components.css

Dependencies: datastar@1.0.2

Source: packages/ui/src/items/searchable-select/style.ts

Composition

Derived from the examples and style specs, not authored.

Composes