Freigeben über


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/.../5063

  • Anonymous
    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 removed

  • Anonymous
    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.