typeahead.js (Fork: Svakinn)
Inspired by twitter.com's autocomplete search functionality, typeahead.js is a fast and fully-featured autocomplete library.
This fork is from Twitter/typeahead.js. The aim is to provide bug fixes and necessary missing features in that version.
Hopefully the next version of typeahead.js will render this fork obsolete.
Knockout binding handler is also included here.
New features are marked in this document as >>New<<.
How you acquire typeahead.js is up to you.
- Download zipball of latest release.
- Download latest typeahead.js.
Note: typeahead.js has a dependency on jQuery 1.9+, which must be loaded before typeahead.js.
Se this doc for the new features in the latest update of this fork.
For some working examples of typeahead.js, visit the typeahead examples page. I am still working on examples for this fork but the Knockout examples are ready.
- Displays suggestions to end-users as they type
- Shows top suggestion as a hint (i.e. background text)
- Works with hardcoded data as well as remote data
- Rate-limits network requests to lighten the load
- Allows for suggestions to be drawn from multiple datasets
- Supports customized templates for suggestions
- Plays nice with RTL languages and input method editors
At the time Twitter was looking to implement a typeahead, there wasn't a solution that allowed for prefetching data, searching that data on the client, and then falling back to the server. It's optimized for quickly indexing and searching large datasets on the client. That allows for sites without datacenters on every continent to provide a consistent level of performance for all their users. It plays nicely with Right-To-Left (RTL) languages and Input Method Editors (IMEs). We also needed something instrumented for comprehensive analytics in order to optimize relevance through A/B testing. Although logging and analytics are not currently included, it's something we may add in the future.
Turns any input[type="text"]
element into a typeahead. datasets
is expected to be a single dataset or an array of datasets.
// single dataset
$('input.typeahead-devs').typeahead({
name: 'accounts',
local: ['timtrueman', 'JakeHarding', 'vskarich']
});
// multiple datasets
$('input.twitter-search').typeahead([
{
name: 'accounts',
prefetch: 'https://twitter.com/network.json',
remote: 'https://twitter.com/accounts?q=%QUERY'
},
{
name: 'trends',
prefetch: 'https://twitter.com/trends.json'
}
]);
Destroys previously initialized typeaheads. This entails reverting DOM modifications and removing event handlers.
$('input.typeahead-devs').typeahead({
name: 'accounts',
local: ['timtrueman', 'JakeHarding', 'vskarich']
});
$('input.typeahead-devs').typeahead('destroy');
Sets the current query of the typeahead. This is equivalent to using $("input.typeahead").val(query)
.
*>>New<< In earlier versions of typeahead, if were using remote
or prefetch
data, this method was necessary to initialize the data in the control. This fork solved this problem so initialization of data no longer requires any tricks. You can use any method you like to set the data in the input box and do it whenever you like.
Example:
$('#MyInputBoxId').typeahead('setQuery','hello');
Sets the selected datum object of the typeahead. This method is preferred for initialization over the setQuery
method in case you have actual data record for the selected option. In case you have no record but want to initialize the text, then use the setQuery instead.
Example:
$('#MyInputBoxId').typeahead('setDatum', myDatum);
Returns the datum object from the last selected or autocompleted data in the control.
Example:
var myDatum = $('#MyInputBoxId').typeahead('getDatum');
Returns the current input control value.
Example:
var myText = $('#MyInputBoxId').typeahead('getQuery');
Still the same value can be acceived via:
var myText = $('#MyInputBoxId').val();
Clears the current cache of the typeahead. In most cases this is not needed. However if you are reusing the page with different data and cache keys (for instance in SPA application), it may be preferable to clear the cache to reduce the memory footprint of the application. This method may also be used instead of using varying cacheKey
's for remote data.
The cache cleared is both the remote and the prefetched cache.
Example:
$('#MyInputBoxId').typeahead('clearCache');
Also: replace prefetch_url before reload it
Reloads all suggestion data in the control. This includes local
, prefetch
and remote
data. This function is mostly handy when the html page containing the control is reused, for example when used in SPA applications. In that case the Initialize method is not executed automatically but we may still require refresh on the control.
When cacheKey
is used as function or local data is data bound using data binding library (such as Knockout
) we may want to update the suggestion data manually when underlying data (i.e. local
) is changed.
The refresh method returnes JQuery deferred object that resolves when all data is reloaded. New event is also raised: typeahead:refreshed
Example:
$('#MyInputBoxId').typeahead('refresh');
Opens the dropdown on the relevant element (only if it has suggestions)
Example:
$('#MyInputBoxId').typeahead('openDropdown');
Closes the dropdown on the relevant element.
Example:
$('#MyInputBoxId').typeahead('closeDropdown');
A dataset is an object that defines a set of data that hydrates suggestions. Typeaheads can be backed by multiple datasets. Given a query, a typeahead instance will inspect its backing datasets and display relevant suggestions to the end-user.
When defining a dataset, the following options are available:
-
name
– The string used to identify the dataset. Used by typeahead.js to cache intelligently. -
valueKey
– The key used to access the value of the datum in the datum object. Defaults tovalue
. -
nameKey
>>New<< – If the input display name should be other than the unique value, then this is the name of the datum in the datum object. Defaults tovalue
or the value of thevalueKey
. -
limit
– The max number of suggestions from the dataset to display for a given query. Defaults to5
. -
minLength
– The minimum number characters entered in the input box before the typeahead fires up. Defaults to1
.
>>New<<: Setting this value to 0 fires up typeahead on empty input box with all suggestions up to thelimit
value. -
template
– The template used to render suggestions. Can be a string or a precompiled template. If not provided, suggestions will render as their value contained in a<p>
element (i.e.<p>value</p>
). -
engine
– The template engine used to compile/rendertemplate
if it is a string. Any engine can use used as long as it adheres to the expected API.
Required iftemplate
is a string. -
restrictInputToDatum
>>New<< – This option will make sure the user can only leave the input box with empty text or text corresponding to the internalselectedDatum
. TheselectedDatum
is set byautocomplete
orselection
events, or programmatically by invoking the typeaheadsetDatum
method.
When user leaves the input box one of these following things will happen:
If the string is empty the internalselectedDatum
retrieved by thegetDatum
method will be set to null. The eventnoSelect
will be raised.
If the string matches the internalselectedDatum
nothing happens. If we have the internalselectedDatum
set, the text will be set to that datums name. No events will be raised. -
header
– The header rendered before suggestions in the dropdown menu. Can be either a DOM element or HTML. -
footer
– The footer rendered after suggestions in the dropdown menu. Can be either a DOM element or HTML. -
local
– An array of datums. -
matcher
>>New<< - Function with the signature function(query,dataset) to override the normal suggestion getter for the local and prefetched data. It returns list of search items (suggestions) on the form {name:<display name>
, value:<key value>
, tokens:<List of search tokens>
, datum:<the datum object>
}. The query parameter is the current search query and the dataset the typeahead dataset object.
*Be warned: it requires knowledge of the internals of typeahead's dataset to create function of this complexity. -
prefetch
– Can be a URL to a JSON file containing an array of datums or function handling datum population or, if more configurability is needed, a prefetch options object. -
remote
– Can be a URL or handler function to fetch suggestions from when the data provided bylocal
andprefetch
is insufficient or, if more configurability is needed. See remote options object for details.
The individual units that compose datasets are called datums. The canonical form of a datum is an object with a value
property and a tokens
property. value
is the string that represents the underlying value of the datum and tokens
is a collection of single-word strings that aid typeahead.js in matching datums with a given query.
{
value: '@JakeHarding',
name: 'Jake Harding',
tokens: ['Jake', 'Harding']
}
For ease of use, datums can also be represented as a string. Strings found in place of datum objects are implicitly converted to a datum object.
When datums are rendered as suggestions, the datum object is the context passed to the template engine. This means if you include any arbitrary properties in datum objects, those properties will be available to the template used to render suggestions.
<img src="{{profileImageUrl}}">
<p><strong>{{name}}</strong> {{value}}</p>
{
value: '@JakeHarding',
tokens: ['Jake', 'Harding'],
name: 'Jake Harding',
profileImageUrl: 'https://twitter.com/JakeHaridng/profile_img'
}
Prefetched data is fetched and processed on initialization. If the browser supports local storage, the processed data will be cached there to prevent additional network requests on subsequent page loads.
When configuring prefetch
, the following options are available:
-
url
– A URL to a JSON file containing an array of datums. url or handler Required. -
prefetcHandler
>>New<< - Custom function with the signaturefunction()
, returning array of datums, to take control of the prefetched data retrieval. This can be both used to handle local synchronous data or to fetch asynchronous data from remote source using the promise pattern.
In case this function is used for asynchronous data fetch it must return the data array wraped inpromise
(i.e.return $.Deferred().resolve(data);
), but it should return the data arrey for synchronous operations. Both JQuery promises and Q promises are supported. -
ttl
– The time (in milliseconds) the prefetched data should be cached in local storage. Defaults to86400000
(1 day). Setting this value to 0 will prevent caching. -
filter
– A function with the signaturefilter(parsedResponse)
that transforms the response body into an array of datums. Expected to return an array of datums. -
cacheKey
>>New<< – String or function returning string, to control the name used for caching of the prefetched values. Using function for cachekey can be useful when using the typeahead reload method. -
skipCache
>>New<< – If set to true, stops typeahead from caching prefetched values in browsers local store. Settingttl
to 0 has the same effect.
Remote data is only used when the data provided by local
and prefetch
is insufficient. In order to prevent an obscene number of requests being made to remote endpoint, typeahead.js rate-limits remote requests.
When configuring remote
, the following options are available:
-
url
– A URL to make requests to when the data provided bylocal
andprefetch
is insufficient.url
orhandler
options are required for remote lookups. -
handler
>>New<< - Custom function with the signaturefunction(query, data)
to take control of the typeahead data retrieval. This can be both used to handle local synchronous data or to fetch asynchronous data from remote source using the promise pattern.
In case this function is used for asynchronous data fetch it must returnpromise
, but it should returntrue
for synchronous operations. Both JQuery promises and Q promises are supported.
Whenhandler
option is used for data retrieval the optionsbeforeSend
,replace
,wildcard
,dataType
andcache
do not apply. However the throttling options are used and the cache control is also in play. See this page for details on the handler usage. -
dataType
– The type of data you're expecting from the server. See the jQuery.ajax docs for more info. Defaults toJson
. This applies only in conjunction with theurl
option. -
cache
– Determines whether or not JQuery will cache responses. See the jQuery.ajax docs for more info. This applies only for theurl
option, by default all remote responses are cached for each query. -
skipCache
>>New<< – Orders remote queries not to use local cache but always go remote for data lookup on each keystroke. This can be useful for mutating remote data. -
cacheKey
>>New<< – By default all remote lookups are cached per string combination entered in the typeahead control. This option can be used to control caching which may be necessary if more than one typeahead control is used in the application. By default this value is set to the url value forurl
requests and thename
value forhandler
requests.
This option value may also be set to function with the signaturefunction(query)
. It must then return cache key including the query value. This function method may be particularly helpful when using handler functions for remote lookup where results may be varying on different contexts.
Example:
cacheKey: function(query) { return 'admin1_#' + vm.country + '_%' + query;}
-
timeout
– Sets a timeout for requests. See the jQuery.ajax docs for more info. This applies only in conjunction with theurl
option. -
wildcard
– The pattern inurl
that will be replaced with the user's query when a request is made. Defaults to%QUERY
. This applies only in conjunction with theurl
option. -
replace
– A function with the signaturereplace(url, uriEncodedQuery)
that can be used to override the request URL. Expected to return a valid URL. If set, no wildcard substitution will be performed onurl
. This applies only in conjunction with theurl
option. -
rateLimitFn
– The function used for rate-limiting network requests. Can be eitherdebounce
orthrottle
. Defaults todebounce
. -
rateLimitWait
– The time interval in milliseconds that will be used byrateLimitFn
. Defaults to300
. -
maxParallelRequests
– The max number of parallel requests typeahead.js can have pending. Defaults to6
. -
beforeSend
– A pre-request callback with the signaturebeforeSend(jqXhr, settings)
. Can be used to set custom headers. See the jQuery.ajax docs for more info. This applies only in conjunction with theurl
option. -
filter
– A function with the signaturefilter(parsedResponse)
that transforms the response body into an array of datums. Expected to return an array of datums.
typeahead.js triggers the following custom events:
-
typeahead:initialized
– Triggered after initialization. If data needs to be prefetched, this event will not be triggered until after the prefetched data is processed. -
typeahead:opened
– Triggered when the dropdown menu of a typeahead is opened. -
typeahead:closed
– Triggered when the dropdown menu of a typeahead is closed. -
typeahead:selected
– Triggered when a suggestion from the dropdown menu is explicitly selected. The datum for the selected suggestion is passed to the event handler as an argument in addition to the name of the dataset it originated from. -
typeahead:autocompleted
– Triggered when the query is autocompleted. The datum used for auto completion is passed to the event handler as an argument in addition to the name of the dataset it originated from. -
typeahead:noSelect
>>New<< – Triggered when user exists the input without text matching any name in the suggestion data. This is also triggered if the input value is empty. -
typeahead:reloaded
>>New<< – Triggered when dataset has been reloaded using the typeahead methodreload
. -
typeahead:busyUpdate
>>New<< – Triggered when the typeahead starts or stops lookup work -> is busy processing or looking up data. This applies also toprefetch
data. This event can be used to manage loaders or busy indicators for the control. Your worker functon should have the following signature:function myFunction(element,isBusy)
where isBusy is the boolean busy indication value.
All custom events are triggered on the element initialized as a typeahead.
You can use JQuery to hook the custom events to your handling functions.
Example:
$(´#yourElementIdWithHash´.on('typeahead:selected', yourSelectedEventHanlerFunction);
where the handler function has this format:
function yourSelectedEventHanlerFunction(element,datum) {
//your implementation here
}
Above the datum parameter contains the data for the suggestion you selected.
Element is the input box Dom element.
Any template engine will work with typeahead.js as long as it adheres to the following API:
// engine has a compile function that returns a compiled template
var compiledTemplate = ENGINE.compile(template);
// compiled template has a render function that returns the rendered template
// render function expects the context to be first argument passed to it
var html = compiledTemplate.render(context);
Check out Hogan.js if you're looking for a compatible mustache templating engine.
The styles applied by typeahead.js are for positioning the hint and the dropdown menu, no other styles should be affected. In most cases the styles applied by typeahead.js will work like a charm, but there are edge cases where some custom styles will be necessary. If you're having CSS issues, create an issue for support.
By default, the dropdown menu created by typeahead.js is going to look ugly and you'll want to style it to ensure it fits into the theme of your web page. Below is a Mustache template describing the DOM structure of a typeahead.js dropdown menu. Note that the {{{html}}}
tag is the HTML generated by the custom template you provide when defining datasets.
<span class="tt-dropdown-menu">
{{#dataset}}
<div class="tt-dataset-{{name}}">
{{{header}}}
<span class="tt-suggestions">
{{#suggestions}}
<div class="tt-suggestion">{{{html}}}</div>
{{/suggestions}}
</span>
{{{footer}}}
</div>
{{/dataset}}
</span>
When an end-user mouses or keys over a .tt-suggestion
, the class tt-is-under-cursor
will be added to it. You can use this class as a hook for styling the "under cursor" state of suggestions.
For simple autocomplete use cases, the typeahead component Bootstrap provides should suffice. However, if you'd prefer to take advantage of some of the advance features typeahead.js provides, here's what you'll need to do to integrate typeahead.js with Bootstrap:
- If you're customizing Bootstrap, exclude the typeahead component. If you're depending on the standard bootstrap.js, ensure typeahead.js is loaded after it.
- The DOM structure of the dropdown menu used by typeahead.js differs from the DOM structure of the Bootstrap dropdown menu. You'll need to load some additional CSS in order to get the typeahead.js dropdown menu to fit the default Bootstrap theme.
Knockout binding handler for this library is provided.
See this page for details.
The input box background styling is overwritten by the control.
- Chrome
- Firefox 3.5+
- Safari 4+
- Internet Explorer 7+
- Opera 11+
Typeahead also works on mobile browsers.
Discovered a bug? Please create an issue here on GitHub!
https://github.com/Svakinn/typeahead.js/issues
Thanks for assistance and contributions:
For this fork thanks to:
- @nathankoop for the IE11 Bugfix
- @zhigang1992 for the restrictInputToDatum option
- @ryanpitts for the nameKey idea and implementation
Unlike the original project there is no requirement of setting up build and test environment. Just issue a pull request on the files you would like updated.
Copyright 2013 Twitter, Inc. and other contributors
Licensed under the MIT License