Knockout.js binding for Bootstrap Typeahead plugin
Here's a rather hacky script I wrote to bind fields marked up with Bootstrap's Typeahead plugin (see https://gist.github.com/1866577 for the version I use) to Knockout.js observables. Feedback is very welcome.
// Bootstrap.Typeahead binding: presently requires custom version from gist: https://gist.github.com/1866577.
// Use like so: data-bind="typeahead: { target: selectedNamespace, source: namespaces }"
ko.bindingHandlers.typeahead = {
init: function(element, valueAccessor) {
var binding = this;
var elem = $(element);
var value = valueAccessor();
// Setup Bootstrap Typeahead for this element.
elem.typeahead(
{
source: function() { return ko.utils.unwrapObservable(value.source); },
onselect: function(val) { value.target(val); }
});
// Set the value of the target when the field is blurred.
elem.blur(function() { value.target(elem.val()); });
},
update: function(element, valueAccessor) {
var elem = $(element);
var value = valueAccessor();
elem.val(value.target());
}
};
Update: Binding now uses only the valueAccessor, rather than looking for a separate 'source' binding. This is cleaner.
Comments
Anonymous
December 15, 2012
did u ever test this out?Anonymous
December 15, 2012
Of course :) Note the comment regarding the need to use the gist version. You can achieve the same thing using Bootstrap 2.2.0, patching it as per this GitHub comment: github.com/.../5063Anonymous
December 15, 2012
It helps me understand it easier. Or do you got google talk?Anonymous
December 15, 2012
I don't want to dabble with the library, i am getting a json array back and want to bind it. What would be the binding on the html tag?Anonymous
December 15, 2012
Something like this: <span>Namespace</span><input type="text" data-bind="typeahead: { target: selectedNamespace, source: namespaces }"> In that example, selectedNamespace is the observable which is being set by the input and namespaces is the observable which contains the data. In your example, you might set the source using something like: self.namespaces = ko.observable(); $.getJSON('/namespaces', self.namespaces);Anonymous
December 15, 2012
So namespaces has the array, while selectedNamespace refers to the textbox value?Anonymous
December 15, 2012
is valueAccessor is array of values and element is teh id of the textbox?Anonymous
December 15, 2012
> So namespaces has the array, while selectedNamespace refers to the textbox value? yes >is valueAccessor is array of values and >element is teh id of the textbox? No, checkout the Knockout.js docs: knockoutjs.com/.../custom-bindings.html They should answer your questions succinctly.Anonymous
December 15, 2012
I added an array straight this.List = ['alpha', 'anna', 'atakata','baba', 'bella']; this.typeahead = ko.observable(); and i referenced them. using the binding: <input id="typeahead" type="text" data-bind="typeahead: { target: typeaheadbox, source: customerList }", valueUpdate: 'afterkeydown'" >Anonymous
December 15, 2012
Well in my usage, I'm using an observable, not a native array(shouldn't matter). Also, your code there is not syntactically valid HTML or XML - what's that superfluous: , valueUpdate: 'afterkeydown'" bit for?Anonymous
December 15, 2012
The comment has been removedAnonymous
December 15, 2012
my array updates each time the key is pressed via a json call, it doesn't always have all the elements.Anonymous
December 15, 2012
If you really want, I will try and fix your code for you... but I think you should run through the Knockout.js tutorials and the Bootstrap documentation first, then ask on StackOverflow. Also, consider putting your own code on JSFiddle so I can see it.