BootstrapSearch is a fork of bootstrap-5-autocomplete that enhances the functionality with AJAX support, customizable label/value mapping, loading and success indicators, keyboard navigation, and multi-select capabilities.
- AJAX support for dynamic data fetching
- Local data support
- Multi-select
- Customizable dropdown and input labels (supports HTML)
- Keyboard navigation
- Highlight typed text in dropdown
Include Bootstrap 5.3 and FontAwesome in your project, then include bootstrap-search.js at your project:
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script src="path/to/bootstrap-search.js"></script><input type="text" id="example3" placeholder="Select a dish..." autocomplete="off">const foods = [
{ id: 1, name: "Empanadas", country: "Argentina" },
{ id: 2, name: "Pastel de Nata", country: "Portugal" },
{ id: 3, name: "Pulpo a la Gallega", country: "Spain" },
{ id: 4, name: "Completo", country: "Chile" },
{ id: 5, name: "Tacos al Pastor", country: "Mexico" },
{ id: 6, name: "Tapioca", country: "Brazil" }
];
new BootstrapSearch(document.getElementById('example3'), {
data: foods,
inputLabel: 'name',
dropdownLabel: 'name',
value: 'country',
onSelectItem: item => console.log('Selected Local:', item)
});<input type="text" id="example1" placeholder="Type a user name..." autocomplete="off">new BootstrapSearch(document.getElementById('example1'), {
remoteData: q => `https://dummyjson.com/users/search?q=${q}`,
inputLabel: 'firstName',
dropdownLabel: 'firstName',
value: 'id',
resolveData: res => res.users,
onSelectItem: item => console.log('Selected:', item)
});<input type="text" id="example2" placeholder="Type a user..." autocomplete="off">new BootstrapSearch(document.getElementById('example2'), {
remoteData: q => `https://dummyjson.com/users/search?q=${q}`,
inputLabel: item => `${item.firstName} ${item.lastName}`,
dropdownLabel: item => {
const imgUrl = `https://api.dicebear.com/9.x/pixel-art/svg?seed=${item.id}`;
return `<div class="avatar-label"><img src="${imgUrl}" alt="avatar"/>${item.firstName} ${item.lastName}</div>`;
},
value: item => item.id,
resolveData: res => res.users,
onSelectItem: item => console.log('Selected User:', item)
});<input type="text" id="example4" placeholder="Select users..." autocomplete="off">new BootstrapSearch(document.getElementById('example4'), {
remoteData: q => `https://dummyjson.com/users/search?q=${q}`,
inputLabel: 'firstName',
dropdownLabel: 'firstName',
value: 'id',
resolveData: res => res.users,
multiSelect: true,
onSelectItem: items => console.log('Selected Items:', items)
});| Option | Description | Default |
|---|---|---|
| threshold | Number of characters before searching | 2 |
| highlightTyped | Highlight typed text in dropdown | true |
| highlightClass | CSS class(es) for highlight | 'text-primary' |
| inputLabel | String key or function to set input.value when item selected |
'label' |
| dropdownLabel | String key or function to render dropdown item (supports HTML) | 'label' |
| value | String key or function to get value | 'value' |
| showValue | Show value alongside label in dropdown | false |
| showValueBeforeLabel | Show value before label in dropdown | false |
| remoteData | URL string or function returning URL for AJAX request | - |
| resolveData | Function to transform AJAX response | - |
| onInput | Callback on input change | - |
| onSelectItem | Callback when user selects an item | - |
| multiSelect | Allow selecting multiple items | false |
Help contributing to the library with these missing things:
- Remove FontAwesome dependency by parametrizing icons
- Migrate the codebase to TypeScript for type safety and split into multiple files
- Add a build system with support for CDNs and module bundlers
- Extend accessibility and keyboard navigation
- Add unit tests and continuous integration
Thanks to @gch1p for the original library, without it, this would have been impossible :)
