Select and Select2 Fields
.c-select + .js-select2 (optional)
Select fields are used to select a single value from a list of options. This documentation covers the styling of the native select element as well as the styling and functionality of the Select2 dropdown.
- New select fields are always embedded in a Float Container.
- See Input Groups Molecule for combinations of Select Fields, Inputs, Font Awesome Icons, Buttons or Checkboxes.
- Related: Old Select Field
Select vs. Select2
Native Select
Use the class c-select on a select element to get the default styling:.c-float-container.-has-select > .c-select
Show Code
<div class="c-float-container -has-select">
<label class="c-label" for="style-select">Select Box without Select2</label>
<select class="c-select" id="style-select" name="opts">
<option value='0'></option>
<option value='1'>First item</option>
<option value='2'>Second item</option>
<option value='3'>Third item</option>
<option value='4'>Lorem Ipsum</option>
<option value='5'>lorem ipsum dolor sit amet consectetur adipisici elit</option>
<option value='6'>lorem ipsum dolor sit amet consectetur adipisici elit</option>
<option value='7'>adipisici elit</option>
<option value='8'>Last item</option>
</select>
</div>With Select2
Use the class js-select2 on a select element if you want to initialize Select2 (Version4.1.0-rc.0).
.c-float-container.-has-select > .c-select.js-select2
Show Code
<div class="c-float-container -has-select">
<label class="c-label" for="default-select">Select Box with Floating Label</label>
<select class="js-select2" id="default-select" name="default-select">
<option value='1'>First item</option>
<option value='2'>Second item</option>
<option value='3'>Third item</option>
<option value='4'>Lorem Ipsum</option>
<option value='5'>lorem ipsum dolor sit amet consectetur adipisici elit</option>
<option value='6'>lorem ipsum dolor sit amet consectetur adipisici elit</option>
<option value='7'>Just an item</option>
<option value='8'>Last item</option>
</select>
</div>Light Version
.c-float-container.-has-select.-light > .c-select.-light
Show Code
<div class="h-highlight-block">
<div class="c-float-container">
<label class="c-label" for="light">Light Select Dropdown</label>
<select class="js-select2" id="light" name="light-select" data-additional-classes="-light">
<option value="0"></option>
<option value='1'>First item</option>
<option value='2'>Second item</option>
<option value='3'>Third item</option>
</select>
</div>
</div>Disabled Select
.c-select[disabled]
Show Code
<div class="c-float-container -has-select -is-disabled">
<label class="c-label" for="disabled-box">Disabled Select Box</label>
<select class="js-select2" disabled id="disabled-box" name="opts">
<option value='1'>First item</option>
<option value='2'>Second item</option>
<option value='3'>Third item</option>
<option value='4'>Lorem Ipsum</option>
<option value='5'>lorem ipsum dolor sit amet consectetur adipisici elit</option>
<option value='6'>lorem ipsum dolor sit amet consectetur adipisici elit</option>
<option value='7'>Just an item</option>
<option value='8'>Last item</option>
</select>
</div>
<select class="m-t-xl js-select2" disabled name="disabled-link-select" data-additional-classes="-is-link">
<option value="1" class="js-option-lager">selected item</option>
<option value="0" class="js-option-no-lager">item</option>
</select>
<select class="m-t-xl js-select2" disabled name="disabled-link-select-small" data-additional-classes="-is-link -small">
<option value="1" class="js-option-lager">selected item</option>
<option value="0" class="js-option-no-lager">item</option>
</select>Select2 with Search Field
The search field in the dropdown is hidden per default, add the attribute data-search to enable it: .js-select2[data-search]
Show Code
<div class="c-float-container -has-select m-b-m">
<label class="c-label" for="select-search">Select Box with Search Field</label>
<select class="js-select2" data-search id="select-search">
<option value='1'>First item</option>
<option value='2'>Second item</option>
<option value='3'>Third item</option>
<option value='4'>Lorem Ipsum</option>
</select>
</div>Select2 with Multiple Choices
(not in use yet)
<select class="js-select2" multiple ..
Show Code
<div class="c-float-container -has-select -is-active m-b-m">
<label class="c-label" for="multiple-select">Multiple Select</label>
<select class="js-select2" multiple id="multiple-select" name="multiple" data-additional-classes="">
<option selected value='1'>First item with longer name</option>
<option value='2'>Second item</option>
<option value='3'>Third item</option>
<option value='4'>Lorem Ipsum Dolor</option>
<option value='5'> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</option>
<option selected value='6'> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</option>
</select>
</div>Select2 Option Groups
optgroup > option ..
Show Code
<div class="c-float-container -has-select m-b-m">
<label class="c-label" for="option-groups">With Option Groups</label>
<select class="js-select2" data-search id="option-groups">
<optgroup label="Group Name">
<option>Nested option 1</option>
<option>Nested option 2</option>
</optgroup>
<optgroup label="Group Name 2">
<option>Nested option 1</option>
<option>Nested option 2</option>
</optgroup>
</select>
</div>Disabled Options
Add the attribute disabled to disable options in the dropdown:<option value='...' disabled>
Show Code
<div class="c-float-container -has-select">
<label class="c-label" for="diss">Select Box with Disabled Options</label>
<select class="js-select2" id="diss" name="disabled-options1">
<option value='1'>First item</option>
<option value='2' disabled>Second item</option>
<option value='3'>Third item</option>
<option value='4' disabled>Last item</option>
</select>
</div>Hide Disabled Options
Add the attribute data-hide-disabled to hide disabled options in the dropdown: .js-select2[data-hide-disabled]
Show Code
<div class="c-float-container -has-select">
<label class="c-label" for="hide-disabled-opts">Select Box with Hidden Disabled Options</label>
<select class="js-select2" data-hide-disabled id="hide-disabled-opts" >
<option value='1'>First item</option>
<option value='2' disabled>Second item</option>
<option value='3'>Third item</option>
<option value='4' disabled>Last item</option>
</select>
</div>Custom Option Tags
If you want to allow custom options tags, add the attribute data-custom-options
Select2 Link Styling
Add the class .-is-link to the select element to get a link-style select field:.js-select2.c-select.-is-link[.-small]
Show Code
<div class="h-flex h-space-around">
<div class="h-width-40">
<select class="js-select2 demo-link-example" name="link-select" data-additional-classes="-is-link -has-icons">
<option value="1" class="js-option-lager">✓</option>
<option value="0" class="js-option-no-lager">✕</option>
</select>
</div>
<div class="h-width-40">
<select class="js-select2 demo-link-example" name="link-select-small" id="link-select-small" data-additional-classes="-is-link -small">
<option value="1" class="js-option-lager">✓</option>
<option value="0" class="js-option-no-lager">✕</option>
</select>
</div>
</div>Select2 with Icon and Tooltip
.c-float-container.-has-select.-icon-right > .c-float-container__icon
See Tooltips for more information.
Show Code
<div class="c-float-container -has-select -icon-right">
<label class="c-label" for="select-info">Floating Label</label>
<select class="js-select2" id="select-info" name="select-info-name" data-additional-classes="-icon">
<option value='1'>First item</option>
<option value='2'>Second item</option>
<option value='3'>Third item</option>
<option value='4'>Last item</option>
</select>
<div class="c-float-container__icon -right js-tooltip" data-title="Prüfzertifikat löschen"
data-placement="left">
<span class="fa fa-info-circle" aria-hidden="true"></span>
</div>
</div>AJAX Example (with Search and Clear-Button)
TIP
- allowClear needs a placeholder and placeholder need a corresponding option value (which cannot be an empty string, but can be a single space)
- Select2 AJAX support: See select2.org/data-sources/ajax
Show Code for AJAX Example
import {Select} from "./Select";
Select.init();
const $select = $(".js-example");
const mergedSelectOptions = $.extend(true, {}, Select.getOptionsWithTags("Unbekannter Bestandteil"), {
ajax: {
url: "https://jsonplaceholder.typicode.com/posts/", // aktuell Dummy-API, gerne auch andere Endpunkte ausprobieren!
dataType: "json",
allowClear: true, // always use in combination with data-placeholder attribute on element
processResults: function (data) {
/**
* Wir setzen "text" (also den Text in der Zeile) hier auf den Namen des Elements.
* Siehe https://select2.org/data-sources/formats
* Da die Elemente von der Dummy-API ohnehin schon ein Attribut "id" haben, müssen wir das nicht extra setzen.
*/
data.forEach(resultObj => {
resultObj.info = resultObj.body;
resultObj.text = resultObj.title;
Select.addOptionTagsIfNotExists($select, resultObj);
}
);
return {
results: data
};
}
}
});
$select.each(function () {
Select.apply($(this), mergedSelectOptions);
});Fake Select2
A simple div that is not initialized by Select2 but has the same look. It can be used to display read-only values.
.c-float-container.-has-select > .c-fake-select
Show Code
<div class="h-highlight-block">
<div class="c-float-container -is-active -has-select h-hover-pointer -light m-y-reset">
<span class="c-label">Sonder-PZN</span>
<div class="print-hide c-float-container__icon h-help-pointer c-tooltip__trigger -left -small">
<span class="fa fa-info-circle h-link-color" aria-hidden="true"></span>
<div data-cy="tooltip" class="c-tooltip h-always-on-top m-t-xxs -large m-l-s m-t-s">
Für die korrekte Erstellung von Z-Daten und Hash-Code ist die tatsächliche PZN Ihres Bestandteils anzugeben.
Hilfstaxen-PZN bzw. Sonder-PZN sind dann anzugeben, wenn Sie einen Bestandteil ohne tatsächliche PZN verwenden.
</div>
</div>
<div class="c-fake-select h-width-100 p-r-xxl p-l-xxl p-l-xl">
<div class="c-fake-select__content -m-l-s">09999005</div>
<span class="c-fake-select__arrow">
<b></b>
</span>
</div>
</div>
</div>Word Wrapping Demo
height: autoheight: autoShow Code
<div class="h-flex h-space-between">
<div class="h-width-30">
<code>height: auto</code><br/>
<div class="c-float-container -has-select -is-active">
<label class="c-label" for="multiline">Multiline (Default)</label>
<select class="js-select2" id="multiline" name="opts">
<option value='1'>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. </option>
<option value='2'>lorem ipsum dolor sit amet consectetur adipisici elit</option>
</select>
</div>
</div>
<div class="h-width-30">
<code>height: auto</code>
<select class="js-select2 demo-link-example"
data-additional-classes="-is-link -small"
name="link-select" id="link-select-small2">
<option value="1">loremipsumdolorsitametconsecteturadipisicielit</option>
<option value="0" class="js-option-no-lager">lorem ipsum dolor sit amet consectetur adipisici elit</option>
</select>
</div>
</div>Settings and API
Show API and Settings
Form.init()to activate Floating Labels. See Forms Module.Select.init()to apply default settings and initialize select2 on alljs-select2selects.
Use Select.apply($select, options); to apply your own options on a specific select-field. You can also extend the default options.
Available default options are:
Select.getDefaultOptions()@returns default settings for standard select-dropdownsSelect.getOptionsWithSearch()@returns extended settings for select-dropdowns with searchSelect.getOptionsWithTags(unknownTerm)@returns extended settings for select-dropdowns with search and custom tags, @param {String} unknownTerm - optional parameter that describes the type of the "unknown custom tag" that is added
Vue Component: Combobox
Overview
INFO
Combobox is a searchable, accessible select field implemented as a Vue component. It renders a trigger button styled exactly like the .c-select fields above, and a teleported dropdown panel with a search input and a keyboard-navigable option list — all interaction (open/close, search, keyboard navigation, positioning) is implemented in Vue, with no jQuery/select2.js dependency.
When to use
Use Combobox instead of .js-select2 whenever you're building a Vue app and need a searchable dropdown driven by reactive data — e.g. filtering options as the user types by reacting to the search event (the component itself doesn't filter, it just emits the raw search value so you can update :options yourself, which also covers server-side/AJAX search), or letting the user type a value that isn't in the list (customOptions). For static, non-Vue pages, keep using .js-select2 as documented above.
Quick Start
Import
import { Combobox } from '@pharma4u/patternlab/vue'Basic usage
<Combobox v-model="selectedItem" label="Item" :options="items" />Positioning
Combobox positions its dropdown with @floating-ui/vue (^1.1.11), which is a regular dependency of patternlab — it's installed transitively, you don't need to add it to your own project.
Live Examples
Search Filtering (client-side)
Combobox does not filter its own option list — it only emits search with the typed text. Here we filter allItems ourselves in a computed and feed the result back via :options. The same @search handler could instead call an API and pass back a loading state, which is how it's used for server-side/AJAX search in production (labxpert-abfuellung's useRemoteComboboxSearch).
Show Code
<script setup>
import { computed, ref } from 'vue'
import { Combobox } from '@pharma4u/patternlab/vue'
const value = ref(null)
const allItems = [
{ label: 'First item', value: '1' },
{ label: 'Second item', value: '2' },
{ label: 'Third item', value: '3' },
{ label: 'Fourth item', value: '4' },
{ label: 'Fifth item', value: '5' },
{ label: 'Sixth item', value: '6' },
{ label: 'Seventh item', value: '7' },
{ label: 'Eighth item', value: '8' },
{ label: 'Just an item', value: '9' },
{ label: 'Last item', value: '10' },
]
const filterTerm = ref('')
const filteredItems = computed(() => {
const term = filterTerm.value.trim().toLowerCase()
if (!term) return allItems
return allItems.filter((option) => option.label.toLowerCase().includes(term))
})
</script>
<template>
<Combobox
v-model="value"
label="Item (mit Filterung)"
:options="filteredItems"
no-results-text="Keine Einträge gefunden."
@search="filterTerm = $event" />
</template>Custom Options (free text)
With custom-options, typing a value that does not match any existing option adds it as a selectable "create new" entry.
Show Code
<template>
<Combobox
v-model="selectedCustomItem"
label="Item"
:options="customItems.map(i => ({ label: i, value: i }))"
custom-options
custom-option-name="Neues Item" />
</template>Error State
Show Code
<template>
<Combobox
v-model="value"
label="Pflichtfeld"
:options="items"
required
error="Bitte wählen Sie einen Eintrag aus." />
</template>Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | string | number | null | null | Selected value (v-model). |
options | SelectItem[] | Record<string, string> | — required | Flat options ({label, value}[]), grouped options ({label, options}[]), or a plain value→label map. |
selectedOptions | SelectItem[] | Record<string, string> | [] | Extra options used to resolve the display label for modelValue when it isn't present in options (e.g. lazily-loaded lists). |
label | string | — required | Field label (from BaseInputFieldWithIconsProps). |
placeholder | string | 'Bitte wählen ...' | Text shown in the trigger when nothing is selected. |
customOptions | boolean | false | When true, typing a search value with no match offers it as a selectable custom option. |
customOptionName | string | null | null | Label prefix shown for the generated custom option (also enables customOptions behavior on its own). |
loading | boolean | false | Shows a spinner in the search field and suppresses the custom-option / empty-state logic while true. |
noResultsText | string | 'Keine Übereinstimmungen gefunden.' | Text shown when options is empty. |
id | string | auto-generated | Custom ID for the trigger element. |
hint | string | undefined | Hint text rendered below the field. |
error | string | undefined | Error message. When set, also forces the error validation state. |
validationState | 'error' | 'warning' | 'success' | undefined | Explicit validation state when no error message is set. |
disabled | boolean | false | Disables the trigger. |
required | boolean | false | Shows the required marker (*) next to the label. |
light | boolean | false | Light visual variant of the field shell. |
hiddenLabel | boolean | false | Visually hides the label (still available to assistive tech). |
floatContainer | boolean | true | Wraps the field in the c-float-container layout. |
containerClass | string | string[] | Record<string, boolean> | '' | Extra class(es) for the field container. |
iconLeft / iconRight | string | '' | CSS class(es) for a left/right icon (ignored if the matching slot is used). |
hasSmallIcon | boolean | false | Renders the left icon in a smaller size. |
leftIconInteractive / rightIconInteractive | boolean | false | Renders the icon outside the pointer-events-disabled wrapper so it can have its own click handler. |
No built-in validation framework
Combobox does not integrate with any specific form/validation library. Drive error / validationState from whatever validation approach your app already uses.
Events
| Event | Payload | Description |
|---|---|---|
update:modelValue | string | number | null | Emitted on selection. Used by v-model. |
select-item | SelectOption | null | Emitted alongside update:modelValue with the full selected option (label + value). |
search | string | Emitted on every keystroke in the search field. |
open | — | Emitted when the dropdown opens. |
close | — | Emitted when the dropdown closes. |
Slots
| Slot | Props | Description |
|---|---|---|
leftIcon / rightIcon | — | Replace the icon markup generated from iconLeft / iconRight. |
empty | { noResultsText } | Replace the "no results" list item. |
option | { option, index, selected, highlighted, customLabel } | Replace the rendering of a single option row. |
Accessibility
- The trigger renders
role="combobox"witharia-expanded,aria-controls,aria-invalidandaria-describedby. - The dropdown list renders
role="listbox"/role="option"and keepsaria-selectedin sync with the highlighted/selected option. - Keyboard support:
ArrowDown/ArrowUpmove the highlight,Enterselects,Escapecloses. - The search input is auto-focused once the dropdown has finished positioning.
- Clicking outside the trigger and panel closes the dropdown (via a document-level
mousedownlistener that is added/removed with the open state).
Notes
- The dropdown panel is rendered via
<Teleport to="body">and positioned with@floating-ui/vue(flip+shift+autoUpdate), matching the trigger's width and flipping above it when there isn't enough room below. Comboboxis composed from smaller, individually exported pieces:BaseInputField(generic field shell),ComboboxPanel,ComboboxOptions,ComboboxSearch, and theuseComboboxOptionscomposable — all available from@pharma4u/patternlab/vueif you need to build a custom variant.