README
Choices.js 
A vanilla, lightweight (~19kb gzipped 🎉), configurable select box/text input plugin. Similar to Select2 and Selectize but without the jQuery dependency.
TL;DR
- Lightweight
- No jQuery dependency
- Configurable sorting
- Flexible styling
- Fast search/filtering
- Clean API
- Right-to-left support
- Custom templates
Installation
With NPM:
npm install choices.js
With Yarn:
yarn add choices.js
From a CDN:
Note: There is sometimes a delay before the latest version of Choices is reflected on the CDN.
<!-- Include base CSS (optional) -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/choices.js/dist/styles/base.min.css"
/>
<!-- Or versioned -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/choices.js@9.0.1/dist/styles/base.min.css"
/>
<!-- Include Choices CSS -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/choices.js/dist/styles/choices.min.css"
/>
<!-- Or versioned -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/choices.js@9.0.1/dist/styles/choices.min.css"
/>
<!-- Include Choices JavaScript (latest) -->
<script src="https://cdn.jsdelivr.net/npm/choices.js/dist/scripts/choices.min.js"></script>
<!-- Or versioned -->
<script src="https://cdn.jsdelivr.net/npm/choices.js@9.0.1/dist/scripts/choices.min.js"></script>
Or include Choices directly:
<!-- Include base CSS (optional) -->
<link rel="stylesheet" href="dist/styles/base.min.css" />
<!-- Include Choices CSS -->
<link rel="stylesheet" href="dist/styles/choices.min.css" />
<!-- Include Choices JavaScript -->
<script src="/dist/scripts/choices.min.js"></script>
Setup
Note: If you pass a selector which targets multiple elements, the first matching element will be used. Versions prior to 8.x.x would return multiple Choices instances.
// Pass single element
const element = document.querySelector('.js-choice');
const choices = new Choices(element);
// Pass reference
const choices = new Choices('[data-trigger]');
const choices = new Choices('.js-choice');
// Pass jQuery element
const choices = new Choices($('.js-choice')[0]);
// Passing options (with default options)
const choices = new Choices(element, {
silent: false,
items: [],
choices: [],
renderChoiceLimit: -1,
maxItemCount: -1,
addItems: true,
addItemFilter: null,
removeItems: true,
removeItemButton: false,
editItems: false,
duplicateItemsAllowed: true,
delimiter: ',',
paste: true,
searchEnabled: true,
searchChoices: true,
searchFloor: 1,
searchResultLimit: 4,
searchFields: ['label', 'value'],
position: 'auto',
resetScrollPosition: true,
shouldSort: true,
shouldSortItems: false,
sorter: () => {...},
placeholder: true,
placeholderValue: null,
searchPlaceholderValue: null,
prependValue: null,
appendValue: null,
renderSelectedChoices: 'auto',
loadingText: 'Loading...',
noResultsText: 'No results found',
noChoicesText: 'No choices to choose from',
itemSelectText: 'Press to select',
addItemText: (value) => {
return `Press Enter to add <b>"${value}"</b>`;
},
maxItemText: (maxItemCount) => {
return `Only ${maxItemCount} values can be added`;
},
valueComparer: (value1, value2) => {
return value1 === value2;
},
classNames: {
containerOuter: 'choices',
containerInner: 'choices__inner',
input: 'choices__input',
inputCloned: 'choices__input--cloned',
list: 'choices__list',
listItems: 'choices__list--multiple',
listSingle: 'choices__list--single',
listDropdown: 'choices__list--dropdown',
item: 'choices__item',
itemSelectable: 'choices__item--selectable',
itemDisabled: 'choices__item--disabled',
itemChoice: 'choices__item--choice',
placeholder: 'choices__placeholder',
group: 'choices__group',
groupHeading: 'choices__heading',
button: 'choices__button',
activeState: 'is-active',
focusState: 'is-focused',
openState: 'is-open',
disabledState: 'is-disabled',
highlightedState: 'is-highlighted',
selectedState: 'is-selected',
flippedState: 'is-flipped',
loadingState: 'is-loading',
noResults: 'has-no-results',
noChoices: 'has-no-choices'
},
// Choices uses the great Fuse library for searching. You
// can find more options here: https://github.com/krisk/Fuse#options
fuseOptions: {
include: 'score'
},
callbackOnInit: null,
callbackOnCreateTemplates: null
});
Terminology
| Word | Definition |
|---|---|
| Choice | A choice is a value a user can select. A choice would be equivalent to the <option></option> element within a select input. |
| Group | A group is a collection of choices. A group should be seen as equivalent to a <optgroup></optgroup> element within a select input. |
| Item | An item is an inputted value (text input) or a selected choice (select element). In the context of a select element, an item is equivalent to a selected option element: <option value="Hello" selected></option> whereas in the context of a text input an item is equivalent to <input type="text" value="Hello"> |
Configuration options
silent
Type: Boolean Default: false
Input types affected: text, select-single, select-multiple
Usage: Optionally suppress console errors and warnings.
items
Type: Array Default: []
Input types affected: text
Usage: Add pre-selected items (see terminology) to text input.
Pass an array of strings:
['value 1', 'value 2', 'value 3']
Pass an array of objects:
[{
value: 'Value 1',
label: 'Label 1',
id: 1
},
{
value: 'Value 2',
label: 'Label 2',
id: 2,
customProperties: {
random: 'I am a custom property'
}
}]
choices
Type: Array Default: []
Input types affected: select-one, select-multiple
Usage: Add choices (see terminology) to select input.
Pass an array of objects:
[{
value: 'Option 1',
label: 'Option 1',
selected: true,
disabled: false,
},
{
value: 'Option 2',
label: 'Option 2',
selected: false,
disabled: true,
customProperties: {
description: 'Custom description about Option 2',
random: 'Another random custom property'
},
}]
renderChoiceLimit
Type: Number Default: -1
Input types affected: select-one, select-multiple
Usage: The amount of choices to be rendered within the dropdown list ("-1" indicates no limit). This is useful if you have a lot of choices where it is easier for a user to use the search area to find a choice.
maxItemCount
Type: Number Default: -1
Input types affected: text, select-multiple
Usage: The amount of items a user can input/select ("-1" indicates no limit).
addItems
Type: Boolean Default: true
Input types affected: text
Usage: Whether a user can add items.
removeItems
Type: Boolean Default: true
Input types affected: text, select-multiple
Usage: Whether a user can remove items.
removeItemButton
Type: Boolean Default: false
Input types affected: text, select-one, select-multiple
Usage: Whether each item should have a remove button.
editItems
Type: Boolean Default: false
Input types affected: text
Usage: Whether a user can edit items. An item's value can be edited by pressing the backspace.
duplicateItemsAllowed
Type: Boolean Default: true
Input types affected: text, select-multiple
Usage: Whether duplicate inputted/chosen items are allowed
delimiter
Type: String Default: ,
Input types affected: text
Usage: What divides each value. The default delimiter separates each value with a comma: "Value 1, Value 2, Value 3".
paste
Type: Boolean Default: true
Input types affected: text, select-multiple
Usage: Whether a user can paste into the input.
searchEnabled
Type: Boolean Default: true
Input types affected: select-one
Usage: Whether a search area should be shown. Note: Multiple select boxes will always show search areas.
searchChoices
Type: Boolean Default: true
Input types affected: select-one
Usage: Whether choices should be filtered by input or not. If false, the search event will still emit, but choices will not be filtered.
searchFields
Type: Array/String Default: ['label', 'value']
Input types affected:select-one, select-multiple
Usage: Specify which fields should be used when a user is searching. If you have added custom properties to your choices, you can add these values thus: ['label', 'value', 'customProperties.example'].
searchFloor
Type: Number Default: 1
Input types affected: select-one, select-multiple
Usage: The minimum length a search value should be before choices are searched.
searchResultLimit: 4,
Type: Number Default: 4
Input types affected: select-one, select-multiple
Usage: The maximum amount of search results to show.
position
Type: String Default: auto
Input types affected: select-one, select-multiple
Usage: Whether the dropdown should appear above (top) or below (bottom) the input. By default, if there is not enough space within the window the dropdown will appear above the input, otherwise below it.
resetScrollPosition
Type: Boolean Default: true
Input types affected: select-multiple
Usage: Whether the scroll position should reset after adding an item.
addItemFilter
Type: string | RegExp | Function Default: null
Input types affected: text
Usage: A RegExp or string (will be passed to RegExp constructor internally) or filter function that will need to return true for a user to successfully add an item.
Example:
// Only adds items matching the text test
new Choices(element, {
addItemFilter: (value) => {
return ['orange', 'apple', 'banana'].includes(value);
};
});
// only items ending to `-red`
new Choices(element, {
addItemFilter: '-red