Today we are going to look at how to implement a jQuery autocomplete feature against a UI which is bound to a model via knockout bindings. And in this exercise you'd also learn about how to write your custom bindings using knockout's framework.
So in this exercise I am simply going to write a small app which is going to list some task and allow us to assign some user to the task. Here is the example below:
jQuery autocomplete with knockout.js
The important parts in the code are:
1. The data-bind declaration for the textbox
<input type="text" data-bind="value: name, autoComplete: {label: name, value: id}"/>
2. The custom binding declaration
ko.bindingHandlers.autoComplete = { init:function(el, va, ba, vm, ctx){ var prop = va(); $(el).autocomplete({ source: users, select: function(evt, ui){ evt.preventDefault(); var item = ui.item; console.log(item); prop.label(item.label); prop.value(item.value); } }); } };
Knockout exposes a bindingHandler property via which we add a new property. That property can have any methods defined in it, but the following two are reserved for knockout – init & update.
The two functions have the same signature:
ko.bindingHandler.yourCustomHandler = { init: function(element, valueAccessor, bindingAccessor, viewModel, bindingContext){ //logic } };
init is called when a particular dom element is created in the context of binding. update is called whenever there are any changes in the model. To get more idea about the arguments these functions have, visit the knockout docs.
We've used only the init function since that is the only one required.
But what is the significance of the value binding there?
Without the value binding there wouldn't be a two-way binding per se.
The autocomplete part is pretty much self explanatory. This app is fairly simple. The autocomplete options don't take part in the model. However, if they did, that would have to be in a different blog post all together.
Can we do the same exercise without the value binding?!
+ me on Google Plus if you figure that out!... ;)