
bootstrap-select is a vanilla JavaScript library that enhances Bootstrap’s <select> component with search, checkbox-based multiple selection, rich option content, and programmatic value management.
It builds the interactive control with Bootstrap Input and Dropdown components while keeping the original <select> synchronized with the selected values.
Features:
- Single and multiple selection modes.
- Type-to-filter search for long option lists.
- Case-insensitive and diacritic-insensitive matching.
- Checkbox selection for multi-select fields.
- Select-all control for multiple selections.
- Option groups with grouped selection support.
- Icons, images, comments, and visual dividers inside option lists.
- Programmatic sorting, value updates, insertion, and removal.
- Disabled and readonly states controlled at runtime.
- Automatic initialization through a CSS class.
- Native
changeevents on the underlying select element.
How To Use It
Installation
Load Bootstrap framework first, followed by the component stylesheet and JavaScript.Bootstrap Icons are needed when you use the built-in search clear icon or Bootstrap icon names inside options.
<!-- Bootstrap --> <link rel="stylesheet" href="/assets/bootstrap/bootstrap.min.css"> <!-- Optional for search and Bootstrap option icons --> <link rel="stylesheet" href="/assets/bootstrap-icons/bootstrap-icons.css"> <!-- bootstrap-select --> <link rel="stylesheet" href="/assets/bootstrap-select/bootstrap-select.css"> <script src="/assets/bootstrap/bootstrap.bundle.min.js"></script> <script src="/assets/bootstrap-select/bootstrap-select.js"></script>
Basic Usage
Add the bootstrap-select class to a regular select field. The component initializes it automatically.
<label for="project-role" class="form-label">Project role</label> <select id="project-role" class="bootstrap-select"> <option value="">Choose a role</option> <option value="designer">Designer</option> <option value="developer">Developer</option> <option value="manager">Project Manager</option> </select>
Listen for its normal change event when your app logic depends on the selected value.
const roleSelect = document.querySelector('#project-role');
roleSelect.addEventListener('change', function () {
console.log(roleSelect.value);
});
Add Search
Add the searchable class to place a search field above the option list. data-bs-search-text changes its placeholder.
<label for="timezone-select" class="form-label">Time zone</label> <select id="timezone-select" class="bootstrap-select searchable" data-bs-search-text="Filter time zones" > <option value="new-york">New York</option> <option value="sao-paulo">São Paulo</option> <option value="paris">Paris</option> <option value="tokyo">Tokyo</option> </select>
Multiple Selection
Use the standard multiple property for checkbox-based multi-selection. Add data-bs-toggle-button="true" when the list also needs a checkbox that selects or clears all available options.
<label for="region-select" class="form-label">Sales regions</label> <select id="region-select" class="bootstrap-select searchable" multiple data-bs-toggle-button="true" data-bs-search-text="Find a region" > <option value="north-america">North America</option> <option value="south-america">South America</option> <option value="europe">Europe</option> <option value="asia-pacific">Asia Pacific</option> </select>
Read selected values through selectedOptions when you only need native DOM access.
const regionSelect = document.querySelector('#region-select');
regionSelect.addEventListener('change', function () {
const regions = [...regionSelect.selectedOptions].map(option => option.value);
console.log(regions);
});
Group Multiple Choices
Standard <optgroup> elements organize related choices. Multi-select mode also adds a checkbox to each group.
<label for="stack-select" class="form-label">Technology stack</label>
<select id="stack-select" class="bootstrap-select searchable" multiple>
<optgroup label="Frontend">
<option value="react">React</option>
<option value="vue">Vue</option>
<option value="svelte">Svelte</option>
</optgroup>
<optgroup label="Backend">
<option value="node">Node.js</option>
<option value="php">PHP</option>
<option value="python">Python</option>
</optgroup>
</select>
Add Icons, Images, And Comments
Option data attributes add richer content to the generated dropdown.
<label for="deployment-select" class="form-label">Deployment target</label>
<select id="deployment-select" class="bootstrap-select">
<option
value="cloud"
data-bs-select-option-icon="cloud"
data-bs-select-option-comment="Managed cloud environment"
>
Cloud
</option>
<option
value="edge"
data-bs-select-option-icon="hdd-network"
data-bs-select-option-comment="Distributed edge deployment"
>
Edge
</option>
<option
value="local"
data-bs-select-option-icon="pc-display"
data-bs-select-option-comment="Runs on local infrastructure"
>
Local
</option>
</select>
An image can sit on the right side of an option.
<option value="canada" data-bs-select-option-image="/images/flags/canada.svg" data-bs-select-option-image-class="rounded-1" > Canada </option>
A custom icon library can replace Bootstrap Icons through data-bs-select-option-icon-class.
<option value="germany" data-bs-select-option-icon-class="fi fi-de" > Germany </option>
Add Dividers
An option with data-bs-select-option-divider="true" generates as a visual divider.
Dividers work best inside an <optgroup>, where their position stays associated with the surrounding group.
<optgroup label="Account actions"> <option value="profile">Edit profile</option> <option value="security">Security settings</option> <option data-bs-select-option-divider="true"></option> <option value="signout">Sign out</option> </optgroup>
Select Classes
bootstrap-select: Initializes the select automatically.searchable: Adds the filter input.form-select-lg: Applies Bootstrap’s large input sizing.form-select-sm: Applies Bootstrap’s small input sizing.form-select-plaintext: Applies Bootstrap’s plaintext form style.label-floating: Uses a Bootstrap floating-label layout.label-outline: Applies the component’s outlined label style.
Select Attributes And Properties
multiple(boolean): Enables multiple selection.disabled(boolean): Starts the entire control in a disabled state.data-bs-search-text(string): Sets the search field placeholder. The default isSearch....data-bs-toggle-button(boolean): Adds the select-all checkbox to a multiple select when set totrue.
Option Attributes
data-bs-select-option-icon(string): Adds a Bootstrap Icon before the option text. Supply the icon name without thebi-prefix.data-bs-select-option-icon-class(string): Adds classes to the option icon element. It also supports another icon library when no Bootstrap icon name is set.data-bs-select-option-image(string): Sets the image URL shown at the right side of an option.data-bs-select-option-image-class(string): Adds custom classes to the generated option image.data-bs-select-option-comment(string or HTML): Adds supporting content below the main option text.data-bs-select-option-divider(string): Renders the option as a divider when set totrue.
Manual Initialization
The constructor accepts an optional visibility parameter.
visibility(string, defaultcollapsed): Acceptscollapsedorexpanded.
<label for="status-select" class="form-label">Status</label> <select id="status-select"> <option value="draft">Draft</option> <option value="review">In review</option> <option value="published">Published</option> </select>
const sequence =
`${Date.now()}${Math.floor(Math.random() * 1000)}`;
const statusSelect = new bsSelect(
'status-select',
sequence,
{
visibility: 'expanded'
}
);
Work With Automatically Created Instances
Automatically initialized controls are stored by select ID in FORM.select.
const projectSelect = FORM.select['project-role'];
This instance exposes methods for sorting, selection state, removal, insertion, disabled state, readonly state, and cleanup.
Sort Options
A string is enough for a basic ascending or descending sort.
const languageSelect = FORM.select['language-select'];
// Sort alphabetically.
languageSelect.sort('asc');
// Reverse alphabetical order.
languageSelect.sort('desc');
More detailed sorting behavior uses an object.
languageSelect.sort({
mode: 'asc',
disabled: 'bottom',
sortDisabled: 'true',
emptyDisabledValues: 'top',
optionGroups: 'include'
});
The sorting parameters are:
mode(string, defaultasc): Acceptsascordesc.disabled(string, defaultignore): Acceptsignore,top,bottom, orinclude.sortDisabled(string, defaulttrue): Controls whether disabled choices are sorted when disabled options receive special placement.emptyDisabledValues(string, defaulttop): Acceptstoporinclude.optionGroups(string, defaultinclude): Acceptsincludeorignore.
Dividers inside an option group preserve that group’s order instead of participating in recursive sorting.
Get And Set Values
Calling value() with no argument returns the selected value. Multiple selects return an array.
const regionPicker = FORM.select['region-select']; // Read all selected values. const selectedRegions = regionPicker.value(); console.log(selectedRegions);
Set one or several values through the same method.
// Replace the existing selection.
regionPicker.value(
['north-america', 'europe'],
{
swap: true,
disabled: false
}
);
Set swap to false when new values should join the existing selection.
regionPicker.value(
['asia-pacific'],
{
swap: false,
disabled: false
}
);
Disabled options are skipped by default. Pass disabled: true only when application logic deliberately needs to select one.
Remove Options
Remove options by value, ID, or the component’s internal option index.
const categorySelect = FORM.select['category-select'];
// Remove one value.
categorySelect.remove({
value: 'archived'
});
// Remove several values.
categorySelect.remove({
values: ['draft', 'legacy']
});
// Remove an optgroup or option by ID.
categorySelect.remove({
id: 'inactive-categories'
});
// String shorthand for an ID.
categorySelect.remove('inactive-categories');
API Methods
const selectInstance = FORM.select['project-role'];
// Sort options.
// Accepts "asc", "desc", or a sorting configuration object.
selectInstance.sort('asc');
// Insert option or optgroup elements.
// The optional second argument targets an optgroup.
selectInstance.insert(
'<option value="qa">QA Engineer</option>'
);
// Remove options or groups by value, ID, or internal index.
selectInstance.remove({
value: 'qa'
});
// Get the current value.
const currentValue = selectInstance.value();
// Set the current value.
selectInstance.value('developer');
// Enable or disable the control.
selectInstance.disabled(true);
selectInstance.disabled(false);
// Apply or remove readonly behavior.
selectInstance.readonly(true);
selectInstance.readonly(false);
// Remove the enhanced UI and restore the native select and label.
selectInstance.destroy();
Change Events
Selection changes and state-changing API operations dispatch the standard bubbling change event on the original select.
const departmentSelect =
document.querySelector('#department-select');
departmentSelect.addEventListener('change', function (event) {
console.log(event.target.value);
});
For a multiple select, read all selected options from the original element.
departmentSelect.addEventListener('change', function () {
const values = [...departmentSelect.selectedOptions]
.map(option => option.value);
console.log(values);
});
Alternatives:
- Advanced Select Boxes For Bootstrap 5 With use-bootstrap-select
- Bootstrap 5 Select Dropdown Enhancer – AvalynxSelect
- Multi-select Dropdown Component For JavaScript – slim-select
- Bootstrap Style Searchable Dropdown Plugin – fstdropdown
Changelog:
v5.3.10 (08/16/2026)
- Improved multiple-select toggle-all control







