Knockout Binding for jQuery UI autocomplete
Knockout Custom Binding for jQuery UI autocomplete
by cjgaudin
HTML
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/themes/base/jquery-ui.css">
<script src="http://rniemeyer.github.com/KnockMeOut/Scripts/jquery.tmpl.js"></script>
<script src="http://rniemeyer.github.com/KnockMeOut/Scripts/knockout-latest.debug.js"></script>
<input data-bind="autoComplete: myOptions, value: mySelectedOption, optionsText: 'name', optionsValue: 'id', autoCompleteOptions: {autoFocus: true}" />
<hr/>
<div data-bind="text: ko.toJSON(mySelectedOption)"></div>
JavaScript
ko.bindingHandlers.autoComplete = {
findSelectedItem: function (dataSource, binding, selectedValue) {
var unwrap = ko.utils.unwrapObservable;
//Go through the source and find the id, and use its label to set the autocomplete
var source = dataSource;
var valueProp = unwrap(binding.optionsValue);
var labelProp = unwrap(binding.optionsText) || valueProp;
var selectedItem = ko.utils.arrayFirst(source, function (item) {
if (unwrap(item[valueProp]) === selectedValue)
return true;
}, this);
return selectedItem;
},
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var unwrap = ko.utils.unwrapObservable;
var source = unwrap(valueAccessor()) || {};
var binding = allBindingsAccessor();
var valueProp = unwrap(binding.optionsValue);
var labelProp = unwrap(binding.optionsText) || valueProp;
var displayId = $(element).attr('id') + '-display';
var displayElement;
var options = {};
if (binding.autoCompleteOptions) {
options = $.extend(options, binding.autoCompleteOptions);
}
//Create a new input to be the autocomplete so that the label shows
// also hide the original control since it will be used for the value binding
$(element).hide();
$(element).after('<input type="text" id="' + displayId + '" />')
displayElement = $('#' + displayId);
//handle value changing
var modelValue = binding.value;
if (modelValue) {
var handleValueChange = function (event, ui) {
var labelToWrite = ui.item ? ui.item.label : null
var valueToWrite = ui.item ? ui.item.value : null;
//The Label and Value should not be null, if it is
// then they did not make a selection so do not update the
// ko model
if...