input {string} [optional] The jQuery input selector is only required if the Typeahead was initialized without a jQuery object. In that case, if no input is found, the Typeahead is dropped.

minLength {numeric} 2 (default) The number of characters typed inside the search input before searching for results. It is possible to set this option to 0 and combine it with searchOnFocus: true to display a set of results by default.

maxLength {numeric} false (default) The maximum number of characters typed inside the input to perform a search.

maxItem {numeric} 8 (default) The maximum number of search results that will appear inside the list. Set 0 to display ALL search results. It is possible to combine maxItem with maxItemPerGroup to get different results. // Only 8 results will be displayed // Could be 6 from group1 and 2 from group2 (8 results) maxItem: 8, source: { group1: {}, group2: {}, group3: {}, group4: {} } // Display "Infinity" number of results until 8 item per group is reached // Could be 8 from group1, 4 from group2, 1 from group3 and 8 from group4 (21 results) maxItem: 0, maxItemPerGroup: 8, source: { group1: {}, group2: {}, group3: {}, group4: {} }

dynamic Advanced {boolean} false (default) By default, the typeahead will only load once the source data. Although you can change this behavior and request the data to be re-loaded on every "input" event (similar to keypress). - Demo * Note that you can modify the Ajax request to send the query with {{query}} modifier.

delay {numeric} 300 (default) If dynamic: true , the delay (in milliseconds) will add a timer to prevent from sending a request on every key typed. Instead the request(s) will be sent once the delay expires.

order {null|string} null (default) Takes the default order in which the data was given. If "asc" or "desc" is set, they results will re-order based on display key. asc Reorder the result set ascending desc Reorder the result set descending

offset {boolean} false (default) The position of the matched query can be anywhere inside the result string true The query can only be match if the result string starts by the query characters.

hint {boolean|object} false (default) No hint is activated true or css object A suggestion text will appear if there is an item inside the result list that starts by the user query, also pressing the right arrow at the end of the search input text will autocomplete the query with the suggested hint and call callback.onClickBefore with the selected item.

accent Advanced {boolean|object} false (default) If enabled, the query and search results will ignore accents (ãàáäâẽèéëêìíïîõòóöôùúüûñç) and display every matches regardless of the punctuation. Ex: é = e, À = a, etc. It is possible to set a custom accent object, by simply setting from and to keys * Using this option on large data sets (10,000+ items) might impact your search performances. // {{group}}" will be replaced by the value of "conference" accent: { from: 'àé', to: 'ae' }

highlight {boolean|string} true (default) The search result(s) will receive the <strong> HTML tag around the matched query. If set to true , only the display keys will be highlighted If set to "any" , any string within the template will be highlighted

multiselect {object} null (default) multiselect configuration: limit {number}: Optional limit of maximum items to select

{number}: Optional limit of maximum items to select limitTemplate {string|function}: Template when the limit is reached

{string|function}: Template when the limit is reached matchOn {string|array}: Unique item identifier to remove an item from the result list when selected (use any of the item key), by default a JSON of the item will be used

{string|array}: Unique item identifier to remove an item from the result list when selected (use any of the item key), by default a JSON of the item will be used cancelOnBackspace {boolean}: If true, the last label will be deleted if the query is empty and backspace is pressed

{boolean}: If true, the last label will be deleted if the query is empty and backspace is pressed href {string|function}: Href link on the multiselect item

{string|function}: Href link on the multiselect item data {array|function}: Default items when Typeahead is loaded

{array|function}: Default items when Typeahead is loaded callback.onClick(node, item, event) {function}: Triggered when a multiselect item is clicked

{function}: Triggered when a multiselect item is clicked callback.onCancel(node, item, event) {function}: Triggered when a multiselect item is canceled multiselect: { limit: 2, limitTemplate: 'You can\'t select more than 2 teams', matchOn: ["id"], data: function () { var deferred = $.Deferred(); // Load your custom data and resolve the promise // setTimeout is only added to simulate a delay // see hockey_v2 demo for a working example setTimeout(function () { deferred.resolve([{ "matchedKey": "name", "name": "Canadiens", "img": "canadiens", "city": "Montreal", "id": "MTL", "conference": "Eastern", "division": "Northeast", "group": "teams" }]); }, 2000); deferred.always(function () { console.log('data loaded from promise'); }); return deferred; }, callback: { onClick: function (node, item, event) { event.preventDefault(); console.log(item); alert(item.name + ' Clicked!'); }, onCancel: function (node, item, event) { console.log(item) } } },

group Option changed in 2.5.0 {boolean| string| object} false (default) If set to true , the results will grouped by the group name specified inside source . If set to string , the results will be grouped by the corresponding object key. Ex: group: "conference" will group the hockey teams by "Western" and "Eastern" conferences in hockey_v1 demo If an Object is set: key: Grouping key template: Grouping template in the result list (custom header text), can be string or function. // Will use the options.source.groups group: true // Will use the object key to group the items, Western or Eastern conferences group: "conference" // {{conference}} will be replaced by the value of "conference" group: { key: "conference", template: "{{conference}} conference Hockey Teams" } // Divisions translated to French // Function to enable custom group headers based on item properties // IMPORTANT: Return a string group: { key: "division", template: function (item) { var groups = { "Southeast": "Sud-Est", "Southwest": "Sud-Ouest", "Northeast": "Nord-Est", "Northwest": "Nord-Ouest", "Central": "Centrale", "Pacific": "Pacifique", "Atlantic": "Atlantique" }; return "Division " + groups[item.division]; } } // An alternative could be to have a different template if "conference == Eastern" group: { key: "conference", template: function (item) { var conference = item.conference; if (conference.toLowerCase() === "eastern") { conference += " Yay!"; } return conference; } }

groupOrder {string| array| function} null (default) By default, the groups will be output in the same order as they are defined in source Set "asc" or "desc" to have the group name sorted ascending or descending Set an Array to specify the group order to appear in the search result groupOrder: ["country","state","continent","capital"], source: { continent: {}, country: {}, capital: {}, state: {} } Set a Function that returns an Array // In this example, the group will be order by the MOST results first. // Ex: If there are 5 country matches with "a" and 2 matches with continent, // country group will appear first in the search result // Using "this.", see the EXTRAS section for more details groupOrder: function (node, query, result, resultCount, resultCountPerGroup) { var scope = this, sortGroup = []; for (var i in result) { sortGroup.push({ group: i, length: result[i].length }); } sortGroup.sort( scope.helper.sort( ["length"], false, // false = desc, the most results on top function (a) { return a.toString().toUpperCase() } ) ); return $.map(sortGroup, function (val, i) { return val.group }); }

maxItemPerGroup {number} false (default) Set a maximum results per group if group: true configuration is enabled. - Demo

dropdownFilter Option changed in 2.5.0 {boolean| string| object| array} false (default) If a string a specified, a dropdown filter will be created between the search input and the search submit button using the source.group as indexes. The string value will appear at the end of the dropdown and will filter through all the sources. If an array of objects is set, the dropdownFilter will be built based on it. It is then possible to create filters based on item matching key:value. - Demo // Will use the source groups as the filters dropdownFilter: true // Will use the source groups as the filters but overrides the default text dropdownFilter: "Show All" // Only works with "static data" (options.dynamic = false) // Typeahead will gather every "conference" possibilities on the source items and build the options // Notice the "value" key is not defined dropdownFilter: { key: 'conference', template: '{{conference}} Conference Teams', all: 'All Conferences' } // For dynamic data (options.dynamic = true), the key + value must be specified // Use an Array to define the filters // "all" option has to be declared once to override the default text to display all groups dropdownFilter: [{ key: 'conference', value: 'Western', template: '{{conference}} Conference Teams' }, { key: 'conference', value: 'Eastern', template: '{{conference}} Conference Teams', all: 'All Conferences' }] // For "static data" (options.dynamic = false), it is possible to have both ways // of defining filters in an array // Notice the missing "value" key inside the first object dropdownFilter: [{ key: 'conference', template: '{{conference}} Conference Teams', all: 'All Conferences' }, { key: 'division', value: 'Northeast', template: '{{division}} Division' }]

dynamicFilter Advanced {array} of objects false (default) If filters objects are defined, the Typeahead source data will be filtered based on the "selected" / "checked" checkboxes, radios and selects based on "OR" and "AND" filtering similar to database queries. selector is the jquery selector to reach the unique input type "checkbox", "radio" or select tag

is the jquery selector to reach the unique input type "checkbox", "radio" or select tag key the object key that will be filtered, you can use "dot" notation to reach deep object properties, but in that case extra processing will be performed. Ex object.key.is.deep

the object key that will be filtered, you can use "dot" notation to reach deep object properties, but in that case extra processing will be performed. Ex | key prefix means "OR" filtering, the object key CAN match the value

key prefix means "OR" filtering, the object key match the value & key prefix means "AND" filtering, the object key HAS to match the value See game_v3 demo for a complete example <input type="checkbox" id="assassin"> // If the checkbox is "checked", champions with Assassin tag will be searchable dynamicFilter: [{ selector: "#assassin", key: "|tags.Assassin" }], source: { champion: { data: [{ id: 84, key: "Akali", tags: { Assassin: true } }, { id: 222, key: "Jinx", tags: { Marksman: true } }, ... ] } }

backdrop {boolean|object} false (default) If set to true , html will be added to add a backdrop under the search input and results. It is possible to override the css options by passing an object to this option. // Custom light blue backdrop backdrop: { "opacity": 0.15, "filter": "alpha(opacity=15)", "background-color": "#eaf3ff" }

backdropOnFocus {boolean} false (default) If set to true , as soon as the Typeahead input is focused, the backdrop option will be displayed regardless.

cache [recommended] {boolean|string} false (default) If set to true or localStorage , the source data will be stored in localStorage. If set to sessionStorage , the source data will be stored in sessionStorage. * This option can't be combined with dynamic: true

ttl {numeric} 3600000 (1 hour) (default) * This is a cache configuration, it sets the storage time to live in milliseconds.

compression Advanced {boolean} false (default) Enabling this option will compress the data inside Localstorage.

Setting compression: true requires cache: true option to be enabled. - Download - Demo * This option can't be combined with dynamic: true

suggestion {boolean|object} false (default) * Not yet implemented *

searchOnFocus {boolean} false (default) If enabled, the typeahead will display results (if any) on input focus. You can combine this option with the input attribute "autofocus" to display results when the page is loaded.

blurOnTab {boolean} true (default) Blur Typeahead when Tab key is pressed, if false Tab will go though search results

resultContainer {jquery selector|false} null (default) If a jQuery string selector or jQuery object is specified, the typeahead results will appear in that container instead of the default one. If the option is set to false , the HTML result list will not be built. Use this option for filtering "already on page" HTML list elements with show / hide.

generateOnLoad {boolean} null (default) If enabled, the source data will be generated (doing Ajax request and preparing to data to be searched) on page load instead of waiting for the input to be focused. * This option does not work well with dynamic: true unless some other configuration is adjusted.

mustSelectItem {boolean} false (default) If enabled, an item will HAVE TO be selected in order to submit the form. Use this option if you want to restrict searching to your data set only.

href {string|function} null (default) If a string is defined, every result item will receive the string as href attribute replacing any {{itemKey}} by the item's value. It is possible to apply an extra operation of "slugify" on the value {{url|slugify}} . - Demo * If this options is used, an "href" key will be added to every objects to be re-used inside the callbacks. // Replaces group and display item values href: "/location/{{group}}/{{display}}.html" If a function is defined, the function will be given the item as the first param. It is then for you to build a returned string as the item's href. // Be careful as item properties might contain Url-unsafe characters href: function (item) { return "/location/" + item.group + "/" + item.display + ".html" }

display Advanced {array} ["display"] (default) The key that will be searched for typeahead matching results inside source objects. It is possible to search through multiple keys by simply adding them inside the configuration array. display: ["series", "description"], source: { data: [ { series: "Breaking Bad", description: "A chemistry teacher ...", seasons: 5, rating: 9.6 },{ series: "Game of Thrones", description: "Several noble families fight ...", seasons: 4, rating: 9.5 },{ series: "Dexter", description: "A Miami police forensics ...", seasons: 8, rating: 9.0 } ] } // Typeahead can also search deep inside an object, just separate the keys with "." display: ['string', 'deeper.key.level'], source: { data: [{ string: 'string', deeper: { key: { level: 42 } } }] }

template Advanced {string|function} null (default) The template is a HTML string containing keys that will replaced by match results object keys. You MUST use {{variable}} delimiters for your string to be replaced. - Demo 1 - Demo 2 You can also reach multi-level deep object properties using regular "." format, {{variable.secordlevel.thirdlevel}} If you need to print the item values inside HTML data attributes, it is possible to use {{variable|raw}}. That optional modifier will make sure to get the unmodified value. If a function is used, the first parameter will be the "query" and the second will be the current "item" // Only one group of data, only one template display: "series", template: ' ' + '{{series}}, {{seasons}} seasons - ' + ' {{rating}}/10 ', source: { data: [ { series: "Breaking Bad", seasons: 5, rating: 9.6 } ... ] } // If the item has a high rating, display a special ribbon saying "Top Rated" // VERY IMPORTANT to return the template string display: "series", template: function (query, item) { var template = ' ' + '{{series}}, {{seasons}} seasons -' + ' {{rating}}/10 ' if (item.rating >= 9) { template += ' Top Rated '; } return template; }, source: { data: [ { series: "Breaking Bad", seasons: 5, rating: 9.6 } ... ] } // Multiple groups of data, multiple templates // Since source.series has no "template" key, the global template will be used // source.movies is using it's own template // source.movies uses "title" and "franchise" as the searchable keys display: "series", template: " {{series}}, {{seasons}} seasons - rating: {{rating}} " source: { series: { data: [ { series: "Breaking Bad", seasons: 5, rating: 9.6 } ... ] }, movies: { display: ["title", "franchise"], template: " " + "{{title}}, {{ordinal}} of {{total}} movies from" + "{{franchise}} franchise with a budget of {{details.budget}}" + " ", data: [ { title: "Terminator 2", ordinal: "2nd", total: 5, franchise: "Terminator", details: { budget: '$6,400,000' gross: '$38,400,000' } } ... ] } }

emptyTemplate {string|function} In case there are no results to be displayed, a row will be displayed containing this template. It is possible to display the query using {{query}} string. emptyTemplate: "No results found for {{query}}" // A function can also be used receiving the "query" param // IMPORTANT: return a string emptyTemplate: function (query) { if (query.length > 0) { return 'No results found for "' + query + '"'; } } // It is possible to return a jQuery <LI> object emptyTemplate: function (query) { return $('<li>', { "text": "Just use \"" + query + "\"", "class": "my-custom-class" }); }

templateValue Advanced {string|function} null (default) When an item is selected / clicked, by default the "Matched key" will go inside the input. By defining a templateValue , the text that will result in the input can be customized. // Only one group of data, only one template display: ["series", "description", "actors.name"], template: ' ' + '{{series}}, {{seasons}} seasons - ' + ' {{rating}}/10 ', templateValue: "{{series}}", source: { data: [ { series: "Breaking Bad", description: "Breaking Bad is an American crime drama television series created and produced by Vince Gilligan...", actors: [{ name: '...', age: '...' }] seasons: 5, rating: 9.6 } ... ] }

cancelButton {boolean} true (default) This option provides a small "x" on the right side of the input to clear the text, similar to some browser's default behavior with input[type="search"] .

asyncResult {boolean} false (default) This option will display results (by source group) as they are being loaded in a non-blocking way. For example if you have 3 async groups and the last group takes a bit more time, using `asyncResult` the first 2 groups will be displayed and the 3rd one will appear when it becomes available. It is possible to change the interface displaying loading animation per group using `onLayoutBuiltBefore`. See `demo-asyncResult_v1.html` in the example folder https://github.com/running-coder/jquery-typeahead/blob/master/example/demo-asyncResult_v1.html#L206.

filter {boolean|function} true (default) If set to false, Typeahead will skip any kind of filtering. This option is useful if you already filter the results in Backend. If set to function, every element will be filtered using this custom rule. WARNING accent , correlativeTemplate , offset and matcher will be skipped // item: The matched item (object) // displayKey: The matched item display key (string) filter: function (item, displayKey) { if (item.name === "Typeahead") { return undefined; } else if (/hello/.test(displayKey)) { return false; } else if (item.name === "hi") { // return modified item object item.name = "new name key"; return item; } return true; } // return undefined to skip to next item // return false to attempt the matching function on the next displayKey // return true to add the item to the result list // return item object to modify the item and add it to the result list

matcher {function} If set to function, every element will be filtered using this custom rule AFTER the regular Typeahead filters have been applied. // item: The matched item (object) // displayKey: The matched item display key (string) matcher: function (item, displayKey) { if (item.name === "Typeahead") { return undefined; } else if (/hello/.test(displayKey)) { return false; } else if (item.name === "hi") { // return modified item object item.name = "new name key"; return item; } return true; } // return undefined to skip to next item // return false to attempt the matching function on the next displayKey // return true to add the item to the result list // return item object to modify the item and add it to the result list

correlativeTemplate {boolean|array} false (default) By default, search text matching is reserved to display keys. A searched text can't match multiple keys. If the option is enabled with true or array of display keys, every item will reveive an additional key called compiled . This key will then be searched first (using soften matching mechanism) for any matching results, then the display keys will be searched (using a "string perfect" matching mechanism). If the option is set to true, the template option will be compiled into the "compiled" item key. The search mechanism will be soften to match any word, anywhere separated by spaces. It is also possible to set an Array of display keys instead of the complete template Try it on Hockey_v1

source Required {object|array} null (default) The source option corresponds to the data set(s) that Typeahead will look through to find matches for the user query string. Inside the source, you can have multiple lists of data (groups) It is possible to send an async request inside the data function using $.Deferred source.group configuration: minLength : Overrides the default configuration for the specified group.

: Overrides the default configuration for the specified group. maxLength : Overrides the default configuration for the specified group.

: Overrides the default configuration for the specified group. dynamic : Overrides the default configuration for the specified group.

: Overrides the default configuration for the specified group. filter : Overrides the default configuration for the specified group.

: Overrides the default configuration for the specified group. matcher : Overrides the default configuration for the specified group.

: Overrides the default configuration for the specified group. cache : Overrides the default configuration for the specified group.

: Overrides the default configuration for the specified group. compression : Overrides the default configuration for the specified group.

: Overrides the default configuration for the specified group. ttl : Overrides the default configuration for the specified group.

: Overrides the default configuration for the specified group. data : Array or function that returns an Array. The items in your array can either be strings or objects

: Array or function that returns an Array. The items in your array can either be strings or objects href : Overrides the default configuration for the specified group

: Overrides the default configuration for the specified group template : Overrides the default configuration for the specified group

: Overrides the default configuration for the specified group display : Overrides the default configuration for the specified group

: Overrides the default configuration for the specified group ajax : Local or Jsonp Ajax request to get the data from, follow jquery $.ajax standards.

: Local or Jsonp Ajax request to get the data from, follow jquery $.ajax standards. ajax.callback : Allows done , fail , always & then custom callbacks, see example below

: Allows , , & custom callbacks, see example below ajax.path: Specify the json path to the result Array inside the Ajax request // Ajax response ex: { status: 200, response: { data: { user: [{...}, {...}, {...}] } } } // Then the configuration should be: source: { users: { ajax: { url: '/users/', data: { q: '{{query}}' }, path: 'response.data.user' } } } Source configuration examples: // Simple list of strings source: ["item1", "item2", "item3"] // Array of objects, the complete object will be returned inside the callbacks // Typeahead will look inside the "display" key to match the query string. // You can change options.display and set it to "author" source: [{ id: 1, author: "john", display: "item1" },{ id: 2, author: "eric", display: "item2" },{ id: 3, author: "carter", display: "item3" }] // The source contains 2 groups (game & category) // source.game "data" and "url" will be combined // source.game.url is an Array, the data fetched from index[0] and reached by index[1] // source.category.url is a String, meaning there is only the data set in the response // Matcher function for EVERY sources matcher: function (item, displayKey) {}, source: { game: { data: [{ id: 1, display: "Just an extra game" }], ajax: { url: "/game/list.json", path: "data.games" } }, category: { // Matcher function for "category" only matcher: function (item, displayKey) {}, ajax: { method: "GET", url: "/category/list.json" ... } } } // The Ajax request will receive an object to override the default Ajax request // Custom done callback is added to execute extra operation on the data // It is also possible to use fail, then and always callbacks // Add a custom Authorization Bearer header request // Every sources will not be filtered by Typeahead, all backend data will appear inside the results filter: false, source: { teams: { // Only "teams" group will not be filtered by Typeahead filter: false, ajax: { type: "POST", url: "/jquerytypeahead/hockey_v1.json", path: "optional.json.object.index", data: { myKey: "myValue", }, beforeSend: function (jqXHR, options) { jqXHR.setRequestHeader('Authorization', 'Bearer xxxxxxxxxxxx'); }, // Optional callbacks... callback: { done: function (data, textStatus, jqXHR) { console.log(data); // Perform operations on received data... // IMPORTANT: data has to be returned if this callback is used return data; }, fail: function (jqXHR, textStatus, errorThrown) {}, always :function (data, textStatus, jqXHR) {}, then: function (jqXHR, textStatus) {} } } } } // Advanced Ajax request (dynamic) (see user_v1 demo) // source.user.url[0].data.q "{{query}}" will send the query inside the request // source.user.data will be merged with the results of the Ajax request // #user-type updated value gets sent upon request so it bypasses the request cache. // href creates a link by replacing "{{objetKey}}" dynamic: true, source: { user: { href: "https://www.github.com/{{username}}", data: [{ "id": 415849, "username": "an inserted user that is not inside the database", "avatar": "https://avatars3.githubusercontent.com/u/415849" }], ajax: { type: "POST", // The {{query}} can also be replaced inside the URL // url: "/jquerytypeahead/{{query}}", url: "/jquerytypeahead/user_v1.json", path: "data.user", data: { q: "{{query}}", type: function () { return $('#user-type').val(); } } } } } // Set a function that return a request object to have "dynamic" conditions dynamic: true, source: { tag: { ajax: function (query) { if (query === "hey") { query = "hi" } return { url: "http://www.gamer-hub.com/tag/list.json", dataType: "jsonp", path: data, data: { q: query } } } } } // Async request using the data function source: { teams: { data: function () { var deferred = $.Deferred(); // Gather your data, and resolve the deferred object with an array of objects // setTimeout is used only to show that the data is async setTimeout(function () { if (Array.isArray(data) { deferred.resolve(data); } else { deferred.reject("Invalid data."); } }, 2000); deferred.always(function () { console.log('yay! :D') }); return deferred; } } } * If you are using url , make sure the headers of the response is application/json.