Customizable Select Box & Input Field Enhancement Library – Choices.js
Great for creating multi-select tagging systems.
1. Install & download.
# Yarn $ yarn add choices.js # NPM $ npm i choices.js
2. Load the following JavaScript and Stylesheet in your document.
<link rel="stylesheet" href="/public/assets/styles/choices.min.css" /> <script src="/public/assets/scripts/choices.min.js"></script>
3. Create a simple tag input from a normal text field that
<input id="demo-1" type="text" value="tag-1,tag-2" placeholder="Enter something">
var firstElement = document.getElementById('demo-1');
var choices1 = new Choices(firstElement, {
delimiter: ',',
editItems: true,
maxItems: 5,
removeButton: true
}); 4. Create a multiple select input.
<select name="demo-2" id="demo-2" placeholder="This is a placeholder" multiple> <option value="Dropdown item 1">Dropdown item 1</option> <option value="Dropdown item 2">Dropdown item 2</option> <option value="Dropdown item 3" selected>Dropdown item 3</option> <option value="Dropdown item 4" disabled>Dropdown item 4</option> </select>
var secondElement = new Choices('#demo-2', { allowSearch: false }).setValue(['Set value 1', 'Set value 2']); 5. Create a multiple select input that loads remote data via AJAX.
<select name="demo-3" id="demo-3" data-choice placeholder="Pick an Arctic Monkeys record"></select>
var choicesAjax = new Choices('#demo-2').ajax((callback) => {
fetch('https://api.discogs.com/artists/391170/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW')
.then((response) => {
response.json().then(function(data) {
callback(data.releases, 'title', 'title');
});
})
.catch((error) => {
callback();
});
}) 6. All possible options and callbacks with default values.
// pre-selected items
// an array of strings
// or an array of objects
items: [],
/* add choices to select input
[{
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'
},
}]
*/choices: [],
// suppress console errors and warnings
silent: false,
// the amount of choices to be rendered within the dropdown list
renderChoiceLimit: -1,
// the amount of items a user can input/select
maxItemCount: -1,
// Control how the dropdown closes after making a selection for select-one or select-multiple.
// Boolean | 'auto'
closeDropdownOnSelect: 'auto',
// Make select-multiple with a max item count of 1 work similar to select-one does.
// Selecting an item will auto-close the dropdown and swap any existing item for the just selected choice.
// If applied to a select-one, it functions as above and not the standard select-one.
singleModeForMultiSelect: false,
// Whether a user can add choices dynamically.
addChoices: false,
// allows users to add new items
addItems: true,
// 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
addItemFilter: null,
// allows users to remove items
removeItems: true,
// shows remove button
removeItemButton: false,
// Align item remove button left vs right
removeItemButtonAlignLeft: false,
// allows users to edit items
editItems: false,
// allows to render HTML
allowHTML: true,
// Whether HTML should be escaped on input when addItems or addChoices is true.
// If false, user input will be treated as plain text.
// If true, this can be used to perform XSS scripting attacks if you load choices from a remote source.
allowHtmlUserInput: false,
// allows to duplicate inputted/chosen items
duplicateItemsAllowed: true,
// custom delimiter
delimiter: ',',
// allows copy & paste
paste: true,
// enable live search
searchEnabled: true,
// whether choices should be filtered by input or not
searchChoices: true,
// whether disabled choices should be included in search results.
searchDisabledChoices: false,
// the minimum length a search value should be before choices are searched
searchFloor: 1,
// the maximum amount of search results to show
searchResultLimit: 4,
// search fields
searchFields: 'label', 'value',
// or 'top', 'bottom'
position: 'auto',
// reset scroll position after new items have been added
resetScrollPosition: true,
// whether to sort choices and groups
shouldSort: true,
// whether to sort items
shouldSortItems: false,
/*
sorter: function(a, b) {
return b.label.length - a.label.length;
},
*/sorter: utils_1.sortByAlpha,
// You can pass along the shadowRoot from your application
shadowRoot: null,
// whether to show a placeholder
placeholder: true,
// placeholder value
placeholderValue: null,
// placeholder value for search field
searchPlaceholderValue: null,
// prepend a value to each item added/selected
prependValue: null,
// append a value to each item added/selected
appendValue: null,
// whether selected choices should be removed from the list
// or 'always'
renderSelectedChoices: 'auto',
// control whether selected choices appear in search results for select-multiple inputs.
searchRenderSelectedChoices: true,
appendGroupInSearch: false,
// custom messages
loadingText: 'Loading...',
noResultsText: 'No results found',
noChoicesText: 'No choices to choose from',
itemSelectText: 'Press to select',
uniqueItemText: 'Only unique values can be added',
customAddItemText: 'Only values matching specific conditions can be added',
// functions
addItemText: function (value) {
return "Press Enter to add <b>"".concat((0, utils_1.sanitise)(value), ""</b>");
},
maxItemText: function (maxItemCount) {
return "Only ".concat(maxItemCount, " values can be added");
},
removeItemIconText: () => `Remove item`,
removeItemLabelText: (value) => `Remove item: ${value}`,
valueComparer: function (value1, value2) {
return value1 === value2;
},
// fuse library options
// https://fusejs.io/api/options.html
fuseOptions: {
includeScore: true
},
// label ID to improve a11y
labelId: '',
// callbacks
callbackOnInit: function(e){
// ...
},
callbackOnCreateTemplates: : function(template){
// ...
},
// default CSS class names
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',
description: 'choices__description',
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',
notice: 'choices__notice',
addChoice: 'choices__item--selectable', 'add-choice',
noResults: 'has-no-results',
noChoices: 'has-no-choices',
} 7. API methods.
const intance = new Choices(element, {
// options here
});
// init
intance.init();
// destroy
intance.destroy();
// refresh
intance.refresh(withEvents: boolean = false, selectFirstOption: boolean = false);
// enable/disable
intance.enable();
intance.disable();
// highlight/unhighlight each chosen item
intance.highlightAll();
intance.unhighlightAll();
// remove items
intance.removeActiveItemsByValue(value);
intance.removeActiveItems(excludedId);
intance.removeHighlightedItems(runEvent?: boolean);
// show/hide the dropdown
intance.showDropdown();
intance.hideDropdown();
// set choices of select input via an array of objects (or function that returns array of object or promise of it), a value field name and a label field name.
intance.setChoices(choicesArrayOrFetcher?: (InputChoice | InputGroup)[] | ((instance: Choices) => (InputChoice | InputGroup)[] | Promise<(InputChoice | InputGroup)[]>), value?: string | null, label?: string, replaceChoices?: boolean): this | Promise;
// clear all choices
intance.clearChoices();
// get value(s)
intance.getValue(valueOnly)
// set value(s)
intance.setValue(items: string[] | InputChoice[]);
// set choice(s)
intance.setChoiceByValue(value: string | string[]);
// remove all items, choices and groups
intance.clearStore();
// clear input
intance.clearInput(); 8. Events.
element.addEventListener(
'change',
function(event) {
// each time an item is added & removed
console.log(event.detail.value);
},
false,
);
element.addEventListener(
'addItem',
function(event) {
// each time an item is added
console.log(event.detail.id);
console.log(event.detail.value);
console.log(event.detail.label);
console.log(event.detail.customProperties);
console.log(event.detail.groupValue);
console.log(event.detail.keyCode);
},
false,
);
element.addEventListener(
'removeItem',
function(event) {
// each time an item is removed
console.log(event.detail.id);
console.log(event.detail.value);
console.log(event.detail.label);
console.log(event.detail.customProperties);
console.log(event.detail.groupValue);
},
false,
);
element.addEventListener(
'highlightItem',
function(event) {
// each time an item is highlighted
console.log(event.detail.id);
console.log(event.detail.value);
console.log(event.detail.label);
console.log(event.detail.groupValue);
},
false,
);
element.addEventListener(
'unhighlightItem',
function(event) {
// each time an item is unhighlighted
console.log(event.detail.id);
console.log(event.detail.value);
console.log(event.detail.label);
console.log(event.detail.groupValue);
},
false,
);
element.addEventListener(
'choice',
function(event) {
// each time a choice is selected
console.log(event.detail.choice);
},
false,
);
element.addEventListener(
'highlightChoice',
function(event) {
// fired when a choice from the dropdown is highlighted
console.log(event.detail.el);
},
false,
);
element.addEventListener(
'search',
function(event) {
// fired when a user search choices
console.log(event.detail.value);
console.log(event.detail.resultCount);
},
false,
);
element.addEventListener(
'showDropdown',
function(event) {
// fired when the dropdown is shown
},
false,
);
element.addEventListener(
'hideDropdown',
function(event) {
// fired when the dropdown is hidden
},
false,
); v11.2.0 (01/09/2026)
v11.1.0 (03/14/2025)
v11.0.6 (02/27/2025)
v11.0.5 (02/26/2025)
v11.0.4 (02/23/2025)
v11.0.3 (12/28/2024)
v11.0.2 (09/08/2024)
v11.0.2 (09/08/2024)
v11.0.1 (08/29/2024)
v11.0.0 (08/27/2024)
v10.2.0 (11/30/2022)
v10.1.0 (02/17/2022)
v10.0.0 (01/03/2022)
v9.1.0 (12/20/2021)
v9.0.1 (11/18/2019)
v9.0.0 (11/15/2019)
v8.0.0 (11/03/2019)
v7.1.5 (10/24/2019)
v7.1.0 (10/22/2019)
v7.0.3 (10/22/2019)
02/23/2019
02/19/2019
02/13/2019
02/12/2019
01/25/2019
11/26/2018
11/25/2018
11/03/2018
10/31/2018
The post Customizable Select Box & Input Field Enhancement Library – Choices.js appeared first on CSS Script.
Full spoilers follow for For All Mankind Season 5, Episode 4, which is streaming on…
Border Beam Vanilla is a Vanilla JavaScript library that decorates DOM elements with animated traveling…
ctree.js is a fun little JavaScript library that generates a colorful Christmas tree right in…
A comprehensive review of browser privacy in 2026 reveals that Google Chrome remains highly vulnerable…
DETROIT, MI (WOWO) A competitive shift is underway on the Detroit River as the operator…
The European Commission’s newly launched Digital Age Verification App, unveiled on April 14, 2026, to…
This website uses cookies.