diff --git a/README.md b/README.md index 159fb73..bdc6ec6 100644 --- a/README.md +++ b/README.md @@ -38,4 +38,7 @@ Clone the repository then `npm i && npm run start` to build the example. ##Additional Binding Options * function `mappingFunction`: Function on your model which will map the suggestion data returned from your queries (e.g. so you can use computed observables and extenders in your template) -* string `displayKey`: Property name on complex object suggestion data which will be used to populate the hint/value of the typeahead input. \ No newline at end of file +* string `displayKey`: Property name on complex object suggestion data which will be used to populate the hint/value of the typeahead input. +* string `onSelectFunction`: a function which will be triggered when selecting an item. The function will be sent three parameters: the knockoutobservable for the binding, the selected suggestion, and the event. +* object `typeaheadOpts`: additional options for typeahead. see [jquery_typeahead](https://github.com/twitter/typeahead.js/blob/master/doc/jquery_typeahead.md#options ) +* boolean `localSuggestions`: if you are using local data, set it to true. Your data can be an array of strings, or an object. diff --git a/knockout.typeahead.js b/knockout.typeahead.js index 58d022b..66d43a9 100644 --- a/knockout.typeahead.js +++ b/knockout.typeahead.js @@ -17,6 +17,7 @@ ko.bindingHandlers.typeahead = { var mapping = ko.unwrap(allBindings().mappingFunction); var onSelect = allBindings.get("onSelectFunction"); var displayedProperty = ko.unwrap(allBindings().displayKey); + var localSuggestions = ko.unwrap(allBindings().localSuggestions || false); var user_typeahead_options = ko.unwrap(allBindings().typeaheadOpts) || {}; var value = allBindings.get("value"); @@ -25,26 +26,41 @@ ko.bindingHandlers.typeahead = { var auth = (allBindings.has("authToken")) ? { "Authorization": "Bearer " + ko.unwrap(allBindings().authToken) } : {}; - var remoteData = { - url: url, - ajax: { - headers: auth - } - }; - if (remoteFilter) { - remoteData.filter = remoteFilter; - }; var resultsLimit = allBindings.get("limit") || 10; - var suggestions = new Bloodhound({ - datumTokenizer: function (token) { - return Bloodhound.tokenizers.whitespace(token); - }, + var bloodhound_options = { queryTokenizer: Bloodhound.tokenizers.whitespace, - remote: remoteData, limit: resultsLimit - }); + } + + if (localSuggestions != false) { + bloodhound_options.datumTokenizer = function (token) { + var t = token + if (Object.prototype.toString.call(t) == "[object Object]") { + t = token[displayedProperty] + } + return Bloodhound.tokenizers.whitespace(t); + } + bloodhound_options.local = url + } else { + bloodhound_options.datumTokenizer = function (token) { + return Bloodhound.tokenizers.whitespace(token); + } + bloodhound_options.remote = { + url: url, + ajax: { + headers: auth + } + }; + if (remoteFilter) { + bloodhound_options.remote.filter = remoteFilter; + }; + + } + + var suggestions = new Bloodhound(bloodhound_options); + suggestions.initialize();