Knockout Binding for KendoUI ComboBox

Knockout Binding for KendoUI ComboBox

by Rupesh Kokal

HTML

<link rel="stylesheet" href="http://cdn.kendostatic.com/2011.3.1129/styles/kendo.default.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2011.3.1129/styles/kendo.common.min.css">
<script src="http://cdn.kendostatic.com/2011.3.1129/js/kendo.all.min.js"></script>
<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>
<div id="example">
 <input data-bind="kendoComboBox: myOptions, value: mySelectedOption, optionsText: 'name', optionsValue: 'id', comboBoxOptions: {suggest: true}" />

 <hr/>

 <div data-bind="text: mySelectedOption"></div>      

 <button data-bind="click: addItem">Add Item</button>
 <button data-bind="click: resetDefault">Reset Default</button>
 <div data-bind="text: ko.toJSON(myOptions)"></div>
</div>

JavaScript

ko.bindingHandlers.kendoComboBox = {
        isValidSelection: function (dataSource, binding, selectedText) {
            var unwrap = ko.utils.unwrapObservable;
            //Go through the source and find the id, and use its label to set the autocomplete
            var source = unwrap(dataSource);
            var valueProp = unwrap(binding.optionsValue);
            var labelProp = unwrap(binding.optionsText) || valueProp;

            var selectedItem = ko.utils.arrayFirst(source, function (item) {
                if (unwrap(item[labelProp]) === selectedText)
                    return true;
            }, this);

            return selectedItem ? true : false;
        },
        init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
            var unwrap = ko.utils.unwrapObservable;
            var dataSource = valueAccessor();
            var binding = allBindingsAccessor();
            var valueProp = unwrap(binding.optionsValue);
            var labelProp = unwrap(binding.optionsText) || valueProp;
            var options = {};

            if (binding.comboBoxOptions) {
                options = $.extend(options, binding.comboBoxOptions);
            }

            //handle value changing
            var modelValue = binding.value;
            if (modelValue) {
                var handleValueChange = function () {
                    //Get the selected Value from the Kendo ComboBox
                    var selectedText = this.text();
                    var selectedValue = this.value();
                    //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 (ko.bindingHandlers.kendoComboBox.isValidSelection(dataSource, binding, selectedText)) {
                        if (ko.isWriteableObservable(modelValue)) {
                            //Since this is an observable, the update part will fire and...