Choice & selection

AppMultiSelect

Pick several values from one list — each choice shows as a removable chip in the field.

<app-multi-select label="Skills" name="skills">…</app-multi-select>

A multi-select lets a user choose several values from one list — skills on a profile, tags on a record, filters on a report. Every choice shows as a removable chip inside the field, so the current selection is always visible without opening the dropdown.

Its look and behaviour come from the shared @webority/theme and the underlying <wui-multiselect> element, so the Razor <app-multi-select> and the React <AppMultiSelect> render identically on every Webority surface.

Playground

Every attribute, live. Each change re-renders the real tag helper on the server, so the markup underneath is the exact call that produced the field above it. The starting selection overflows a single row on purpose, so collapse-chips is easy to compare — add or remove chips by using the control itself.

Lightning protection Risk assessment Bonding Earthing Surge protection Site survey IEC 62305 Reporting
<app-multi-select label="Skills" name="skills-playground">…</app-multi-select>
No max-selections limit or clearable resetNeither surface caps the selection count or offers a "clear all" affordance — <wui-multiselect> has no max or clearable attribute (unlike <app-select>, which does support clearable). An app that needs a cap enforces it itself, e.g. surfacing error once the posted selection passes the limit.
Menu open motion product-wide via data-wui-menu-motion — pick one, then open the menus below

Selected as chips

values is an array of the chosen option values; onChange hands you the new array. Each selected value renders as a chip you can remove without reopening the list.

Chosen values shown as chips
Seed the field by marking <app-option selected>; removing a chip or picking a new option updates the posted value.
Risk assessment Lightning protection Surge protection Earthing Bonding Site survey IEC 62305 Reporting
2 selected
Show code
<app-multi-select label="Skills" name="skills" placeholder="Add skills…">
    <app-option value="iec-62305" selected="true">IEC 62305</app-option>
    <app-option value="earthing" selected="true">Earthing</app-option>
    <app-option value="bonding">Bonding</app-option>
    <!-- … -->
</app-multi-select>

Sizes

size takes sm or lg (md is the default), matching AppInput and AppSelect. The control keeps its min-height but still grows as chips wrap to a second row.

Small, medium, large
Earthing Bonding IEC 62305
Earthing Bonding IEC 62305
Earthing Bonding IEC 62305
Show code
<app-multi-select label="Small" name="s" size="sm">…</app-multi-select>
<app-multi-select label="Medium (default)" name="s">…</app-multi-select>
<app-multi-select label="Large" name="s" size="lg">…</app-multi-select>

Collapse to a count

By default chips wrap to as many rows as needed. Set collapse-chips to keep them on a single row the width of the control — whatever doesn't fit folds into a +N counter.

Chips fold into +N
Lightning protection Risk assessment Bonding Earthing Surge protection Site survey
Show code
<app-multi-select label="Skills" name="skills" collapse-chips>
    <app-option value="lightning-protection" selected>Lightning protection</app-option>
    <!-- … -->
</app-multi-select>
One row, plus an overflow countGood when the field sits in a tight row and you want a predictable height — the full selection is always one click away in the dropdown.

Searchable checklist

The dropdown is a checklist with a search box on top, so a long option list stays usable — type to filter, tick to add.

Type to filter, tick to add
searchable is on by default; the field starts empty and fills as the user picks.
Risk assessment Lightning protection Surge protection Earthing Bonding Site survey IEC 62305 Reporting
Show code
<app-multi-select label="Tags" name="tags" placeholder="Select tags…">
    <app-option value="earthing">Earthing</app-option>
    <app-option value="bonding">Bonding</app-option>
    <!-- … -->
</app-multi-select>
Chips summarise, the checklist editsThe field shows the current picks as chips; the dropdown is where you add or remove them. That split keeps a big selection readable — the user scans chips for what's chosen and only opens the searchable checklist to change it.

Leading icon

icon adds a leading Bootstrap Icons glyph before the chips — a visual cue for what the field collects.

Multi-select with a leading icon
Earthing Bonding IEC 62305
Show code
<app-multi-select label="Skills" name="skills" icon="tag">
    <app-option value="earthing" selected>Earthing</app-option>
    <!-- … -->
</app-multi-select>

Option icons

Each option can carry an icon (a Bootstrap Icons name); it shows on the checklist row and on the chip once picked.

An icon per option
Email SMS Push WhatsApp
Show code
<app-multi-select label="Notify via" name="channels">
    <app-option value="email" icon="mail" selected>Email</app-option>
    <app-option value="push" icon="bell" selected>Push</app-option>
    <!-- … -->
</app-multi-select>

Rich rows

An option can carry a description (a second line, also matched by the search), an avatar image URL and/or initials, and disabled with a short disabled-hint. A disabled row stays in the list, readable and reachable by the arrow keys, but cannot be picked.

People with a secondary line and some rows unavailable
Asha Rao Ben Das Chitra Iyer Dev Mehta
Show code
<app-multi-select label="Reviewers" name="reviewers">
    <app-option value="asha@example.com" description="asha@example.com" initials="AR">Asha Rao</app-option>
    <app-option value="ben@example.com" description="ben@example.com" initials="BD"
                disabled="true" disabled-hint="Already a member">Ben Das</app-option>
    <!-- … -->
</app-multi-select>
Show why a row is unavailable, do not hide itA person the user expects to find but cannot see reads as a bug. Keep the row and say why it cannot be chosen; the hint is part of the row's accessible name, so a screen reader hears it too.

Free entry

allow-custom puts a text input after the chips. Typing filters the list; Enter or comma with no highlighted row, leaving the field, or pasting a list commits what was typed as its own chip. custom-pattern decides what a typed entry may be; a refusal keeps the text and says why under the control.

Invite by picking a person or typing any address
Typed text naming an option selects it; naming a disabled option is refused with its hint. Entries are de-duplicated ignoring case.
Asha Rao Ben Das Chitra Iyer Dev Mehta
Type an address and press Enter, or paste a list.
Show code
<app-multi-select label="Invite people" name="invite" allow-custom="true"
                 custom-pattern="[^@\s]+@[^@\s]+\.[^@\s]+"
                 custom-invalid-message="Enter an email address.">
    <app-option value="asha@example.com" description="asha@example.com" initials="AR" selected>Asha Rao</app-option>
    <!-- … -->
</app-multi-select>
validateCustom (React only)React can also pass a function for checks a pattern cannot express. Razor declares the rule with custom-pattern, anchored like the HTML pattern attribute.

States

Surface a validation message with error, and mark a mandatory field with required.

Required with an error
error replaces the hint and marks the field invalid; required renders the asterisk.
Earthing Bonding IEC 62305
Pick at least one skill.
Show code
<app-multi-select label="Skills" name="skills" required="true"
                 error="Pick at least one skill.">
    <app-option value="earthing">Earthing</app-option>
    <!-- … -->
</app-multi-select>

When to use

Use it when

  • The user can choose more than one value from a single list — skills, tags, categories.
  • The selection should stay visible as chips without reopening the dropdown.
  • The option list is long enough that a searchable checklist beats a row of checkboxes.

Reach for something else when

  • Only one value can ever apply. → AppSelect
  • There are a few independent on/off settings. → AppCheckbox
  • The list is remote and the user picks exactly one. → AppAutocomplete
  • You only need to display or remove tokens, not pick them. → AppChip

Best practices

Do
IEC 62305 Earthing Bonding Reporting
Many related values in one compact control; the current picks read back as chips.
Don't
A wall of checkboxes for the same multi-pick is slower to scan and hides the total selection.
Do
Earthing Bonding Reporting Site survey
A searchable checklist keeps a long list usable — the user filters instead of scrolling.
Don't
IEC 62305 Earthing Bonding
Only one value can ever apply here — a single-select dropdown says so; a multiselect invites over-picking.

Every option

The whole surface of the component, one cell per value — preselection, overflow, both booleans, every size and icon, and every combined state.

values (React) / value + selected app-option (Razor) — empty, one, many (overflow)

(no selection) — placeholder shown
Earthing Bonding IEC 62305
<app-option value="earthing" selected> — one chip
Earthing Bonding IEC 62305
6 selected options — wraps to a second row
Lightning protection Risk assessment Bonding Earthing Surge protection Site survey IEC 62305

collapse-chips

collapse-chips="false" (default) — wraps to as many rows as needed
Lightning protection Risk assessment Bonding Earthing Surge protection Site survey
collapse-chips — folds the overflow into a "+N" counter
Lightning protection Risk assessment Bonding Earthing Surge protection Site survey

searchable

searchable="true" (default) — search box above the checklist
Earthing Bonding
searchable="false" — plain checklist, no search box
Earthing Bonding

size — every size, with chips

(default) — md
Earthing Bonding
size="sm"
Earthing Bonding
size="lg"
Earthing Bonding

icon

(no icon)
Earthing
icon="tag"
Earthing

per-option icon

<app-option icon="…"> — shown on the row and the chip
Email SMS Push WhatsApp

state

disabled="true"
Earthing Bonding
required="true" — asterisk on the label
Earthing Bonding
required="true" error="…"
Earthing Bonding
Pick at least one skill.
hint="…" (no error)
Earthing
1 selected
help="…" — info tip beside the label
Earthing

Attributes

AttributeTypeDefaultDescription
asp-forModelExpression—Model property to bind to — supplies name, id, value, label and required from the model.
labelstring—Field label above the control.
namestring—Field name — posts the comma-joined selection; also the element id the label points at.
valuestring—Comma-joined selection seed (React values). With asp-for the bound model value is used instead, so a validation redisplay repopulates the selection.
placeholderstringSelect…Placeholder shown when nothing is selected.
search-placeholderstringSearch…Placeholder inside the checklist search box.
searchablebooltrueShows the search box on top of the checklist. Ignored with allow-custom, whose inline input is the search.
allow-customboolfalseAccept typed entries that are not options: Enter, comma, blur or a pasted list commits them as chips.
custom-patternstring—Regular expression a typed entry must match in full (anchored like the HTML pattern attribute). The declarative counterpart of React validateCustom.
custom-invalid-messagestringEnter a valid value.Message shown under the control when a typed entry is refused.
iconstring—Leading icon glyph before the chips, e.g. flag.
sizestring—Control size: sm / lg. Omit for the default (md).
collapse-chipsboolfalseKeep chips on one row; fold the overflow into a +N counter.
disabledboolfalseDisables the field.
requiredboolfalseRenders the required asterisk on the label.
errorstring—Validation message; replaces the hint and marks the field invalid.
hintstring—Helper text below the field when there is no error.
helpstring—Info-tip content shown beside the label.
help-labelstringMore informationaria-label for the info-tip button (React helpLabel).
<app-option>value, selected, icon, description, avatar, initials, disabled, disabled-hint—Child options — value attribute + label as inner content; selected seeds the initial picks. description is a second line (also searched), avatar an image URL and initials the face without it; disabled keeps the row visible but unselectable, with disabled-hint beside it.
classstring—Extra classes merged onto the .field wrapper (React fieldClassName).
input-classstring—Extra classes on the control itself (the wui-multiselect) — the React className counterpart. The plain class attribute merges onto the .field wrapper instead.