jQuery Typeahead: AJAX Autocomplete Plugin for Search Inputs
| File Size: | 255 KB |
|---|---|
| Views Total: | 17827 |
| Last Update: | |
| Publish Date: | |
| Official Website: | Go to website |
| License: | MIT |
jQuery Typeahead is a jQuery autocomplete plugin from RunningCoder for search boxes and lookup fields. It displays suggestions as users type and can read local data or query a remote endpoint.
Features
- Local arrays, asynchronous data functions, AJAX, and JSONP sources.
- Dynamic remote searches with a configurable request delay.
- Nested JSON response extraction through
ajax.path. - Grouped results, group ordering, and dropdown filters.
- Custom result, value, group, and empty-state templates.
- Search highlighting, accent matching, sorting, and extra matchers.
- Keyboard navigation, clear-button behavior, and loading states.
- LocalStorage or sessionStorage caching with optional LZString compression.
- Multiselect labels with limits, duplicate matching, and removal callbacks.
- Callbacks for requests, layout changes, navigation, selection, submission, and clearing.
Installation
Load the plugin stylesheet first, then jQuery, then the Typeahead script.
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/jquery-typeahead/2.11.2/jquery.typeahead.min.css">
<script src="/path/to/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-typeahead/2.11.2/jquery.typeahead.min.js"></script>
npm And Yarn
Use the jquery-typeahead package name for npm or Yarn installs.
npm install jquery-typeahead # or yarn add jquery-typeahead
Basic Usage
The plugin stylesheet uses typeahead__container, typeahead__field, and typeahead__query around the input. Add typeahead__button when the field needs the plugin's search-button styling.
<form id="customer-search-form">
<div class="typeahead__container">
<div class="typeahead__field">
<div class="typeahead__query">
<input class="js-customer-typeahead"
name="customer"
type="search"
autocomplete="off"
placeholder="Search customers">
</div>
<div class="typeahead__button">
<button type="submit">
<span class="typeahead__search-icon"></span>
</button>
</div>
</div>
</div>
</form>
Autocomplete From Local Data
Pass an object to source. Each source group can define its own data and display keys.
$.typeahead({
input: '.js-customer-typeahead',
minLength: 1,
order: 'asc',
display: ['name', 'email'],
source: {
customers: {
data: [
{ id: 1, name: 'Ada Miller', email: '[email protected]' },
{ id: 2, name: 'Ben Carter', email: '[email protected]' },
{ id: 3, name: 'Carla Reed', email: '[email protected]' }
]
}
}
});
AJAX Autocomplete With a Nested JSON Response
Set dynamic: true when the endpoint should receive the changing query. The plugin replaces {{query}} in the URL. If the response has the shape {"data":{"customers":[...]}}, set path: "data.customers" to pass the customer array into Typeahead. Deeper objects use the same dot-delimited path format.
$.typeahead({
input: '.js-customer-typeahead',
minLength: 2,
dynamic: true,
delay: 300,
display: ['name', 'email'],
source: {
customers: {
ajax: {
url: '/api/customers/search?q={{query}}',
dataType: 'json',
path: 'data.customers'
}
}
}
});
Send the Query as AJAX Data
The query token also works inside string values in the AJAX data object.
$.typeahead({
input: '.js-customer-typeahead',
dynamic: true,
source: {
customers: {
ajax: {
url: '/api/customers/search',
data: {
q: '{{query}}',
status: 'active'
},
path: 'results'
}
}
}
});
Source And AJAX Configuration
A source group can use local data, an asynchronous data function, or an ajax request. Groups can override matching and cache behavior with settings such as display, href, minLength, maxLength, dynamic, cache, and compression. The Typeahead-specific AJAX fields and request hooks are listed below; normal jQuery AJAX settings can also be passed through the request object.
| AJAX Setting | Purpose |
|---|---|
url |
Request URL. The {{query}} token is replaced with the current encoded query. |
data |
jQuery AJAX data object. A string value can contain {{query}}. |
dataType |
Response type passed to jQuery AJAX. The plugin defaults to JSON and can work with JSONP configuration. |
path |
Dot-delimited path used to extract an array from a nested response, such as data.users. |
beforeSend |
jQuery AJAX hook that runs before the request is sent. |
callback.done |
Transforms successful response data before the plugin populates the source. |
callback.fail |
Runs when the request fails. |
callback.then |
Runs through the request promise chain. |
callback.always |
Runs after request completion regardless of outcome. |
All Plugin Options
Search And Result Options
| Option | Description |
|---|---|
input |
Selector or jQuery input used by $.typeahead(). Default: null. |
minLength |
Minimum query length before a search starts. Use 0 to permit searches on focus. Default: 2. |
maxLength |
Maximum query length used for matching. false removes the limit. Default: false. |
maxItem |
Maximum number of displayed results. 0 or false removes the result limit. Default: 8. |
dynamic |
Requests or regenerates source data as the query changes. Default: false. |
delay |
Delay in milliseconds before a dynamic search runs. Default: 300. |
order |
Sort order for results. Accepts asc, desc, or null. Default: null. |
offset |
Matches items from the first character when set to true. Default: false. |
hint |
Turns the inline hint behavior on or off. Default: false. |
accent |
Matches accented characters through built-in equivalents or a custom replacement object. Default: false. |
highlight |
Highlights matched display values. Use any to highlight matches outside the display keys in a template. Default: true. |
searchOnFocus |
Runs a search when the input receives focus. Default: false. |
blurOnTab |
Blurs the input when Tab is pressed. Set to false to keep Tab navigation inside the result list. Default: true. |
generateOnLoad |
Generates the configured source during page initialization. Default: null. |
mustSelectItem |
Calls the submit callback only after a result item has been selected. Default: false. |
asyncResult |
Displays results as asynchronous sources or requests finish. Default: false. |
filter |
Uses the built-in result filtering when true. A function can replace that filtering. Default: true. |
matcher |
Runs an extra result-matching function after the plugin's filtering step. Default: null. |
Grouping And Filtering Options
| Option | Description |
|---|---|
group |
Groups results. Accepts a Boolean, group-key string, or object with group configuration. Default: false. |
groupOrder |
Controls group order with asc, desc, an array, or a function. Default: null. |
maxItemPerGroup |
Limits the number of visible results in each group. Default: null. |
dropdownFilter |
Creates a dropdown filter from configured group data. Default: false. |
dynamicFilter |
Filters results against the value of another control or dynamic value. Default: null. |
Data And Cache Options
| Option | Description |
|---|---|
source |
Defines local, asynchronous, AJAX, or JSONP data sources. Default: null. |
cache |
Caches source data. Accepts true, localStorage, sessionStorage, or false. Default: false. |
ttl |
Cache lifetime in milliseconds. Default: 3600000. |
compression |
Compresses cached data when LZString and a supported storage cache are available. Default: false. |
Display And Template Options
| Option | Description |
|---|---|
backdrop |
Adds a backdrop behind the result UI. It can also receive a style object. Default: false. |
backdropOnFocus |
Shows the backdrop while the input has focus. Default: false. |
resultContainer |
Places the result list inside another container supplied as a selector or jQuery object. Default: null. |
href |
Builds result links from a string or function. Default: null. |
display |
Selects one or more item keys used for display and matching. Default: ["display"]. |
template |
Defines the HTML template for each result item. Default: null. |
templateValue |
Defines the value written into the input after selection. Default: null. |
groupTemplate |
Defines custom markup for group headings. Default: null. |
correlativeTemplate |
Compiles display keys for multi-key searching inside template content. Default: false. |
emptyTemplate |
Defines the content displayed when no result matches. Default: false. |
cancelButton |
Shows the clear button when the input contains text. Escape also clears the query. Default: true. |
loadingAnimation |
Shows the plugin's loading state during requests and searches. Default: true. |
multiselect |
Activates selected-item labels and multiselect behavior through a configuration object. Default: null. |
callback |
Defines Typeahead lifecycle and interaction callbacks. See Callback Functions below. |
selector |
Overrides the plugin's CSS class names. See Selector Classes below. |
debug |
Prints plugin debug information in development builds. Default: false. |
Multiselect Options
Set multiselect to an object to display selected items as labels inside the Typeahead field.
| Setting | Purpose |
|---|---|
limit |
Maximum number of selected items. |
limitTemplate |
Message or function used after the selection limit is reached. |
matchOn |
One key or an array of keys used to detect duplicate selected items. |
cancelOnBackspace |
Removes the last selected item when Backspace is pressed on an empty query. |
href |
Creates links for selected labels. |
data |
Preloads selected items from an array or a function that returns an array or jQuery Deferred. |
callback.onClick |
Runs when a selected label is clicked. |
callback.onCancel |
Runs when a selected label is removed. |
$.typeahead({
input: '.js-customer-typeahead',
display: ['name'],
templateValue: '{{name}}',
multiselect: {
limit: 3,
limitTemplate: 'You can select up to 3 customers',
matchOn: ['id'],
cancelOnBackspace: true,
callback: {
onClick: function (node, item, event) {
console.log(item);
},
onCancel: function (node, item, event) {
console.log('Removed:', item.id);
}
}
},
source: {
customers: {
data: [
{ id: 1, name: 'Ada Miller' },
{ id: 2, name: 'Ben Carter' },
{ id: 3, name: 'Carla Reed' }
]
}
}
});
Callback Functions
Use the callback object for application code that reacts to requests, navigation, result clicks, form submission, and other Typeahead lifecycle points.
| Callback | Runs When |
|---|---|
onInit |
The Typeahead instance is initialized. |
onReady |
Initial preparation has finished. |
onShowLayout |
The result layout opens. |
onHideLayout |
The result layout closes. |
onSearch |
Source data is searched or prepared for matching. |
onResult |
The result container is displayed. |
onLayoutBuiltBefore |
Result HTML has been built but has not entered the result container yet. |
onLayoutBuiltAfter |
Result HTML has entered the result container. |
onNavigateBefore |
Keyboard result navigation is about to run. |
onNavigateAfter |
Keyboard result navigation has finished. |
onEnter |
A result item receives focus. |
onLeave |
A result item loses focus. |
onClickBefore |
A result click is about to run. The event can be cancelled. |
onClickAfter |
The plugin's default result-click behavior has finished. |
onDropdownFilter |
The dropdown filter value changes. |
onSendRequest |
AJAX requests are sent. |
onReceiveRequest |
AJAX requests have completed. |
onPopulateSource |
Response or source data is about to enter the Typeahead data store. |
onCacheSave |
Source data is about to enter the configured cache. |
onSubmit |
The Typeahead form is submitted. |
onCancel |
A non-empty query is cleared. |
Handle a Selected Result
onClickAfter receives the input node, clicked result element, selected item, and event after the plugin updates the field.
$.typeahead({
input: '.js-customer-typeahead',
source: {
customers: {
data: [
{ id: 1, name: 'Ada Miller' },
{ id: 2, name: 'Ben Carter' }
]
}
},
display: ['name'],
callback: {
onClickAfter: function (node, result, item, event) {
$('#selected-customer-id').val(item.id);
},
onSubmit: function (node, form, item, event) {
event.preventDefault();
console.log(item);
}
}
});
Initialization API
Both $.typeahead(options) and $(selector).typeahead(options) initialize the plugin. The static form uses the input option to find the field. Both forms return a Typeahead instance for a single input. The plugin does not use a command-string API such as .typeahead('destroy'); normal integration runs through the configuration object and callbacks.
var first = $.typeahead({
input: '.js-customer-typeahead',
source: {
customers: {
data: ['Ada', 'Ben', 'Carla']
}
}
});
var second = $('.js-product-typeahead').typeahead({
source: {
products: {
data: ['Keyboard', 'Monitor', 'Mouse']
}
}
});
Selector Classes
Override the selector object when custom class names are required. Multiselect mode uses the labelContainer and label entries in addition to the normal Typeahead classes.
| Selector Key | Default Class |
|---|---|
container |
typeahead__container |
result |
typeahead__result |
list |
typeahead__list |
group |
typeahead__group |
item |
typeahead__item |
empty |
typeahead__empty |
display |
typeahead__display |
query |
typeahead__query |
filter |
typeahead__filter |
filterButton |
typeahead__filter-button |
dropdown |
typeahead__dropdown |
dropdownItem |
typeahead__dropdown-item |
labelContainer |
typeahead__label-container |
label |
typeahead__label |
button |
typeahead__button |
backdrop |
typeahead__backdrop |
hint |
typeahead__hint |
cancelButton |
typeahead__cancel-button |
jQuery Typeahead And Twitter typeahead.js
RunningCoder jQuery Typeahead and Twitter typeahead.js use similar names but different APIs. RunningCoder uses a grouped source object, $.typeahead(), AJAX path extraction, cache settings, and the callback names listed above. Twitter typeahead.js uses its own Typeahead UI and Bloodhound suggestion engine.
If your code contains Bloodhound, typeahead.bundle.js, tt-menu, or typeahead:select, use the Twitter typeahead.js reference.
Alternatives And Related Resources
- jQuery Autocomplete & Typeahead with Ghost-Text - fastsearch-suggest
- jQuery Ajax Autocomplete Plugin For Input Fields - Autocomplete
- jQuery Autocomplete Plugin By Twitter - typeahead.js
- Fast Autocomplete & Typeahead Library - autoComplete.js
- 10 Best Autocomplete & Typeahead JavaScript Plugins
FAQs
Q: Why does an AJAX request complete but show no suggestions?
A: Check that ajax.path resolves to an array. Set debug: true during development to catch an invalid data path or source configuration.
Q: Can a source group load data from a function?
A: Yes. A group's data value can be an array or a function that returns an array or jQuery Deferred/Promise.
Q: Can source groups use different search and cache settings?
A: Yes. Individual groups can define values such as minLength, maxLength, dynamic, cache, and compression.
Changelog
2026-08-25
- Updated doc
- Updated demo
v2.11.2 (2022-09-16)
- CSS update.
v2.11.1 (2020-05-19)
- Updated release.
v2.11.0 (2019-11-01)
- Added multi-source asynchronous results.
v2.10.7 (2019-10-20)
- Fixed cursor placement in Chrome inputs.
- Fixed sorting when a display-key value is null.
- Added an input existence check before accessing matched elements.
This awesome jQuery plugin is developed by running-coder. For more Advanced Usages, please check the demo page or visit the official website.











