Knockout kendo grid template binding

http://stackoverflow.com/questions/10996945/knockout-kendo-grid-template-binding

by rniemeyer

HTML

<script src="http://knockoutjs.com/downloads/knockout-2.0.0.debug.js"></script>
<link rel="stylesheet" href="http://rniemeyer.github.com/knockout-kendo/css/kendo.common.min.css">
<link rel="stylesheet" href="http://rniemeyer.github.com/knockout-kendo/css/kendo.default.min.css">
<script src="http://cdn.kendostatic.com/2012.1.322/js/kendo.all.min.js"></script>
<script src="http://rniemeyer.github.com/knockout-kendo/js/knockout-kendo.min.js"></script>
<div data-viewId="languageList" >
    <div id="languageList" data-bind="with: viewModel">
        <div id="languageListGrid" data-bind="kendoGrid: { data: languageViewModels, columns: [ 
                { 
                    template: '<a href=\'\' data-bind=\'click: function() { onLanguageSelected(&quot;#=Language#&quot;) }\'>#=Language#</a>', 
                    field: 'Language', 
                    title: 'Language',
                    width: 50
                }
        
                ], 
            scrollable: false, sortable: true, pageable: false }, preventBinding: true" style="height: 380px">

        </div>
    </div>
</div>

<div data-viewid="languageDetails">
    <div id="languageDetails" data-bind="with: viewModel" class="hidden">
        <form id="languageDetailsForm" action="" style="font-family: Trebuchet MS, Verdana, Helvetica, Sans-Serif;">
        <div data-bind="kendoWindow: {isOpen: isOpen, title:'Language', width: 400, height: 200, modal: true }" >
            test
            <button id="cancelLanguage" class="k-button" data-bind="click: cancelLanguage">Cancel</button>
        </div>
       </form>
    </div>
</div>

CSS

div.hidden {display:none;}

JavaScript

$(function () {
    ko.bindingHandlers.preventBinding = {
      init: function() {
          return { controlsDescendantBindings: true };
      }        
    };
  
    ko.bindingHandlers.kendoGrid.options.dataBound = function(data) {
      var body = this.element.find("tbody")[0];
  
      if (body) {
         ko.applyBindings(ko.dataFor(body), body);   
      }
    };
  
    var elementIsBoundNew = function (element) {
        return !!ko.dataFor(element);
    }

    var applyBindings = function (viewModel, elementId) {
        var element = $('div[data-viewId="' + elementId + '"]')[0];
        if (!elementIsBoundNew(element)) {
            var parentViewModel = { viewModel: viewModel };
            ko.applyBindings(parentViewModel, element);
        }
    };

    var FranchiseDetailsViewModel = function () {
        var 
            self = this,
            initialize = function () {
                self.languagesInfoViewModel(new LanguageListViewModel(self));
                applyBindings(self.languagesInfoViewModel, "languageList");
            };

        FranchiseDetailsViewModel.prototype.languagesInfoViewModel = ko.observable();
        initialize();
    };

    var LanguageListViewModel = function (franchise) {
        var 
            self = this,
            initialize = function () {
                var languageViewModel = new LanguageDetailsViewModel(franchise);
                self.languageViewModels.push(languageViewModel);
            };
        LanguageListViewModel.prototype.languageViewModels = ko.observableArray([]);
        LanguageListViewModel.prototype.selectedLanguageViewModel = ko.observable();

        LanguageListViewModel.prototype.onLanguageSelected = function (selectedLanguage) {
  //var language = new LanguageDetailsViewModel(franchise);  
            self.selectedLanguageViewModel(self.languageViewModels()[0]);

            applyBindings(self.selectedLanguageViewModel, "languageDetails");

           ...