// This will be called once when the binding is first applied to an element,

// and again whenever the associated observable changes value.

// Update the DOM element based on the supplied values here.

}

};

So lets start with the simple stuff... You create a custom binding by adding a property to ko.bindingHandlers. Your binding handler can contain two callbacks: init and update. As described in the document, init happens when the binding is first encountered and update is call when the binding is encountered AND whenever the observable changes.

Next, lets cover the parameters:

element - this is the HTML element to which the data-bind attribute is added

valueAccessor - a function that returns the model property value. For example if your data-bind is: , you would call valueAccessor() in your binding to see what the value of some-Property is.

allBindingsAccessor - another function that will return all properties bound to this model. Another example will help illuminate: . Calling allBindingsAccessor() would return a javascript object like this { custom-Binding: property, my-Binding-Property: value, my-Binding-Property-2: value-2}.

viewModel - the viewModel bound by ko.applyBindings(viewModel)

bindingContext - (from the knockout site) An object that holds the binding context available to this element’s bindings. This object includes special properties including $parent, $parents, and $root that can be used to access data that is bound against ancestors of this context.

So we've covered the signature and the basic functionality. How do we apply this to a jQuery UI Autocomplete control?

The data-bind:

The first thing to note is that there are two bindings in this statement:

value: $root.filter - tells knockout to bind the value contained in the filter property of the view model to the value of the input control.

jqAuto: { autoFocus... - tells knockout how to bind the autocomplete. We'll see the code of the binding in a bit but lets explain each part of this binding first.

{autoFocus: true, minLength: 1, delay: 200} - these are parameters passed straight through to jQuery as options for the autocomplete

jqAutoSource: $root.filterResults - this is the autocomplete's source property. It is bound to the filterResults property of the viewModel and is an observable array

jqAutoQuery: $root.filterQuery - this is used in conjunction with the property above to fill the source collection via an ajax request. So, you could just supply the values for the source in an observable array or you can supply this function to retrieve the source from your server

jqAutoSourceLabel - if jqAutoSource contains an object, this is the property that identifies the label to use in the autocomplete

jqAutoSourceInputValue: if jqAutoSource contains an object, this is the property that will show in the autocomplete dropdown

jqAutoSourceValue: if jqAutoSource contains an object, this is the property that identifies the value to use for autocomplete

The binding:

//jqAutoSource -- the array to populate with choices (needs to be an observableArray)

//jqAutoQuery -- function to return choices

//jqAutoValue -- where to write the selected value

//jqAutoSourceLabel -- the property that should be displayed in the possible choices

//jqAutoSourceInputValue -- the property that should be displayed in the input box //jqAutoSourceValue -- the property to use for the value

} else { //whenever the items that make up the source are updated, make sure that autocomplete knows it mappedSource.subscribe(function(newValue) { $(element).autocomplete("option", "source", newValue); });