Skip to content

Tag input

A field that turns what people type into tags. Enter or a comma adds one; Backspace removes the last. It can suggest tags and stop at a limit.

CSS
css/components/tag-input.css
JS
js/components/tag-input.js (after form.js)

01 — Example

With suggestions and a limit

Type “D” to see a suggestion. Duplicates are rejected, and the field stops at data-max.

    Up to 5. Enter or comma adds; Backspace removes.

    02 — Behavior

    Script

    NameDetail
    Optionsdata-max, data-required, data-suggestions (a JSON list).
    ValueThe hidden input submits a JSON array of tags.
    jewel:tagschangeDetail { tags }.
    el.jewelTags.get(), .set([…]), .add(t), .remove(t), .setSuggestions([…]).

    03 — Usage

    Use it for

    • Free-form tags people make up as they go.

    Avoid

    • Picking from a fixed list. Use checkboxes or a filter.

    04 — Accessibility

    Notes

    • Each tag has a remove button labeled with its name. Adding and removing are announced.

    05 — Without Jewel’s JS

    What the script does

    The script turns typed text into chips, rejects duplicates, stops at the limit and writes the tags into the hidden input. The CSS reads only the markup below, so a framework can render the tags from its own state and leave out tag-input.js and data-component.

    StateSet thisNotes
    Tag<li class="chip"><span>Street</span><button class="chip__remove" type="button" aria-label="Remove tag Street">×</button></li>In .tag-input__list.
    Duplicateis-duplicate on the chip that’s already there, for about a secondFlashes its border.
    At the limitreadonly on .tag-input__text, with a placeholder such as “Limit of 5 reached”Typing stops until a tag is removed.
    SuggestionsAfter .tag-input, a div.tag-input__suggest holding <ul class="tag-input__suggestions" aria-label="Suggested tags"> of <button class="chip--suggest" type="button">+ Dayton</button>hidden on the row when there are none, or at the limit. The script puts a “Recent” .field__hint before the list.
    Erroraria-invalid="true" on .tag-input__textTurns the box red. Show the message as a field error (see Text field).
    ValueA JSON array of the tags in the hidden inputEmpty when there are none.

    Events and keyboard

    • Enter or a comma adds what’s typed, and so does leaving the box. Backspace in an empty box removes the last tag. Pasting “a, b, c” adds all three.
    • Duplicates are matched without case, and extra spaces are tidied.
    • After a remove or a suggestion, put focus back in the text box. A click on the box’s empty space focuses it too.
    • Announce “Added Street, 3 of 5” and “Removed Street” in a visually hidden polite live region.
    • jewel:tagschange doesn’t fire without the script.