jQuery UI autocomplete with a Knockout binding handler
Using the jQuery UI AutoComplete widget with Knockout js
<button data-bind="click: updateDataSource">Update Data Source</button> <label for="name-search">Search language:</label> <input type="text" id="name-search" data-bind="value: langName, ko_autocomplete: { minLength : 0, source: languages, select: addLang }" /> <div style="margin-top:1em">The observable array contains the following elements: <ul data-bind="foreach: selectedLangs"> <li data-bind="text: $data" /> </ul> </div>
ko.bindingHandlers.ko_autocomplete = { init: function (element, params) { //We make a shallow copy of the object because we will change it var conf = $.extend({}, params()); // This fixes the problem of showing the value instead of the label when pressing up or down if (!conf.focus) { //There is no focus callback defined so we will add one conf.focus = function (event, ui) { $(element).val(ui.item.label); return false; } } // Use this to check if the autocomplete is already initialize var isAutoComplete = $(element).is(':data(autocomplete)'); // Use an observable instead of a fixed array var source = conf.source; // <- assuming an observable here conf.source = source(); // get the actual content $(element).autocomplete(conf); if (!isAutoComplete) { //watch for modifications var subscription = source.subscribe(function (newValue) { $(element).autocomplete("option", "source", newValue); }); //handle disposal ko.utils.domNodeDisposal.addDisposeCallback(element, function () { subscription.dispose(); $(element).autocomplete("destroy"); }); } }, update: function (element, params) { $(element).autocomplete("option", "source", params.source); return false; } } $(function () { var availableTags = [{ label: "ActionScript", value: 1 }, { label: "AppleScript", value: 2 }, { label: "Asp", value: 3 }, { label: "BASIC", value: 4 }, { label: "C", value: 5 }, { label: "C++", value: 6 }, { label: "Clojure", value: 7 }, { label: "COBOL", value: 8 }, { label: "ColdFusion", value: 9 }, { label: "Erlang", value: 10 }, { label: "Fortran", value: 11 }, { label: "Groovy", value: 12 }, { label: "Haskell", value: 13 }, { label: "Java", value: 14 }, { label: "JavaScript", value: 15 }, { label: "Lisp", value: 16 }, { label: "Perl", value: 17 }, { label: "PHP", value: 18 }, { label: "Python", value: 19 }, { label: "Ruby", value: 20 }, { label: "Scala", value: 21 }, { label: "Scheme", value: 22 }]; // knockout view model var ViewModel = function () { var self = this; self.langName = ko.observable(); self.selectedLangs = ko.observableArray(); self.languages = ko.observableArray(availableTags); self.updateDataSource = function () { self.languages.push({ label: 'Brain F...', value: 25 }); } // user clicked on a auto complete item self.addLang = function (event, ui) { $(event.target).val(""); var lang = ui.item.label; var id = ui.item.value; self.selectedLangs.push("id: " + id + ", Language: " + lang); return false; } return { languages: self.languages, updateDataSource: self.updateDataSource, addLang: self.addLang, langName: self.langName, selectedLangs: self.selectedLangs } }; //bind knockout model ko.applyBindings(new ViewModel()); });DEMO
jQuery UI autocomplete with a Knockout binding handler
Reviewed by Bhaumik Patel
on
8:39 PM
Rating: