Web Component for interdependent <select> form elements, where the available options in a dependent selection list are based on the selection in a parent or control list. This pattern is also known as "dependent select" (a subform of the generic "input-dependent input") or "cascading dropdowns".
npm install @webfactoryde/cascading-select
The <cascading-select> Web Component is a lightweight wrapper for standard form markup. If offers complete flexibility in regard to the use of <fieldset>, <legend>, <label> and other elements or attributes (i. e. class) needed for layout and styling, as long as two <select> elements with the necessary (data-) attributes are present.
The second, dependent <select> should initially be hidden (via a hidden attribute). This way, in case there are JavaScript errors, the parent <select> does still offer high-level filtering and only the progressive enhancement of the secondary filter level is missing.
- The JS file "cascading-select.js" must be loaded. Depending on browser support requirements, transpilation for older browsers is recommended.
- Two
<select>elements must be output within the Web Component. - The parent
<select>requires adata-dependent-idattribute that contains theidof the dependent<select>as its value to link the two fields. - The
<option>s of the parent<select>that have a sub-selection at the second level require adata-dependent-optionsattribute with a JSON-formatted array of objects, each containing alabelandvalue. Empty placeholder options must also be listed. - The dependent
<select>requires anidattribute with matches the value used fordata-dependent-idon the parent. - The dependent
<select>should initially have ahiddenattribute; this will be removed by the Web Component as needed, but serves as a no-JS fallback in case the Web Component does not initialize correctly.
Web Components support common HTML attributes but can also receive custom parameters.
| Option | Type | Default | Description |
|---|---|---|---|
| always-show-dependent | boolean | false | Controls initial display of the second ("dependent") <select> when no selection is made in the first ("parent") or an option without sub-selection possibilities is selected. Default: the second field is hidden. When the parameter is present, it is displayed and marked with aria-disabled (assuming it has no meaningful interactivity until a selection is made in the "parent", but should still be visible to visually indicate the functional pattern). |
<cascading-select>
<fieldset>
<legend>Where do you want to go bouldering?</legend>
<div>
<label for="town">City</label>
<select id="town" name="town" data-dependent-id="gym">
<option value="">Please choose a city</option>
<option
value="1"
data-dependent-options='[
{ "value": "", "label": "Please choose a gym" },
{ "value": "d11", "label": "Boulders Habitat Bonn" },
{ "value": "d12", "label": "Boulders Habitat Beuel" }
]'
>
Bonn
</option>
<option
value="2"
data-dependent-options='[
{ "value": "", "label": "Please choose a gym" },
{ "value": "d21", "label": "Boulderplanet" },
{ "value": "d22", "label": "Stuntwerk Köln" },
{ "value": "d23", "label": "Kletterfabrik" },
{ "value": "d24", "label": "K11" }
]'
>
Köln
</option>
<option
value="3"
data-dependent-options='[
{ "value": "", "label": "Please choose a gym" },
{ "value": "d31", "label": "Monolith" },
{ "value": "d32", "label": "Boulderfactory" },
{ "value": "d33", "label": "KletterBar" }
]'
>
Münster
</option>
</select>
</div>
<div>
<label for="gym">Gym</label>
<select id="gym" class="form-control"></select>
</div>
</fieldset>
</cascading-select>