How to use detailTemplate in knockout kendo?

kendoui knockout
knockout kendo multiselect
knockout ui
knockout grid
kendo gridoptions
knockout table
kendo js
kendo documentation

Kendo UI supports detailTemplate to be used, however how to use it via Knockout-kendo bindings?

The jsfiddle code is here

just adding rowTemplate and detailTemplate doesnt work, rowTemplate shows up but when i open open the details i get all sorts of exception (object expected in ASP.NET and jsfiddle breaks)

Here is what I came up with (based on your explanation). I know you have already done a workaround, but here is an answer so this question can at least have an answer in case anyone else runs into this.

View

<div data-bind="kendoGrid: { data: items, columns: columns, pageable: { pageSize: 3 }, scrollable: false, rowTemplate: 'rowTmpl', useKOTemplates: true }"> </div>

<script id="rowTmpl" type="text/html">
    <tr>
        <td data-bind="click: $parent.toggleShowDetails">+</td>
        <td data-bind="text: id"></td>
        <td data-bind="text: name"></td>
    </tr>
    <tr data-bind="visible: showDetails">
        <td colspan="3">
            <div data-bind="kendoGrid: { data: $data.details, scrollable: false }"></div>
        </td>
    </tr>
</script>

ViewModel

var ViewModel = function () {
    var self = this;
    self.columns = [{ field: ' ' }, { field: 'id' }, { field: 'name'}];
    self.items = ko.observableArray([
        { id: "1", name: "apple", details: [{ id: "1", name: "subApple"}], showDetails: ko.observable(false) },
        { id: "2", name: "orange", details: [{ id: "2", name: "subOrange"}], showDetails: ko.observable(false) },
        { id: "3", name: "banana", details: [{ id: "3", name: "subBanana"}], showDetails: ko.observable(false) },
        { id: "4", name: "pineapple", details: [{ id: "4", name: "subPineapple"}], showDetails: ko.observable(false) },
        { id: "5", name: "grape", details: [{ id: "5", name: "subGrape"}], showDetails: ko.observable(false) },
        { id: "6", name: "mango", details: [{ id: "6", name: "subMango"}], showDetails: ko.observable(false) }
    ]);

    self.toggleShowDetails = function (data, event) {
        data.showDetails(!data.showDetails());
    };
};

ko.applyBindings(new ViewModel());

Link to GitHub Issues comment: https://github.com/kendo-labs/knockout-kendo/issues/75#issuecomment-20004008

Knockout Kendo Grid Data Detail Template, You can use the URL of any other Pen and it will include the JavaScript from that detailTemplate as a template property for kendoGrid */ /* * knockout-kendo  I'm using Kendo UI (latest version) with Knockout-Kendo (0.6.3) and Knockout (2.3.0) and I have a complex situation with an autocomplete where I am attempting to map the input typed into the autocomplete field (a numeric string) to a complex data type on the backend in Javascript.

I followed a different approach where have two rows in row template itself and one row is actual data, the other is detail row. Then use the accordion to trigger the show/hide of detail row. used bootstrap for accordion... works well for me, though its round about way. btw internally this is how they do it as well, but dynamically.

Is there an issue with using the detailTemplate option for the , and if I change detailTemplate option to have single quotes like in the kendo knockout row template examples I get the string that is inside the  Knockout-kendo hooks into that event to them unmemoize the templates. For usage of templates like the rowTemplate, this assumption is true. When setting up the widget, Kendo calls the render method, then kendo calls the dataBound method. However, with detailTemplate, the assumption is not true.

Ideally, this could be fixed by a pull request to kendo-knockout. In lieu of that, you can get knockout data to bind and render properly in a kendo grid detail template by:

First, add the detailTemplate to the list of templates for kendoGrid. To do this, open knockout-kendo.js, search for 'kendoGrid', then add "detailTemplate" to the array of template names. It should look like this after your change:

createBinding({
    name: "kendoGrid",
    defaultOption: DATA,
    watch: {
        data: function(value, options) {
            ko.kendo.setDataSource(this, value, options);
        }
    },
    templates: ["rowTemplate", "altRowTemplate", "detailTemplate"]
});

Second, in addition to having a detailTemplate defined for your binding, add a detailInit binding that binds to a method on your viewmodel. Here is a sample binding:

<div data-bind="kendoGrid: { data: items, detailTemplate: 'myKoTemplate',
    useKOTemplates: true, detailInit: myDetailInit } "> </div>

Third, add the following detailInit method to your viewmodel, so that the binding can find it:

this.myDetailInit = function(e) {
  // Manually fire the databound event on the grid to 
  // get the detail template to unmemoize properly
  e.sender.options.dataBound();
}

Here's a pen with a working example of this: https://codepen.io/codethug/pen/MXoqZy

Still reading? Great. So what's going on here and why is this broken in the first place?

The first part is easy. detailTemplate isn't listed as a template for kendoGrid. Adding that in makes kendo knockout render the template. However, the template gets memoized, but it never gets unmemoized.

Memoization, in this context, means that when kendo asks for the template from the kendo-knockout template renderer, which in turn hands it off to the knockout template renderer, the template is not immediately rendered, but instead, a placeholder in the form of an HTML comment that looks like this: <!--[ko_memo:123abc]--> is inserted in the DOM instead of the rendered template.

Knockout-Kendo makes the assumption that after the templates are rendered, that the dataBound event will be fired on the kendo grid widget. Knockout-kendo hooks into that event to them unmemoize the templates. For usage of templates like the rowTemplate, this assumption is true. When setting up the widget, Kendo calls the render method, then kendo calls the dataBound method.

However, with detailTemplate, the assumption is not true. When you click something to expand details on a kendo grid row, the renderTemplate method is called, but the dataBound event is not fired, presumably because the data didn't change.

We can get around this by manually firing the dataBound event, as seen in the code above. No data has actually changed, but firing that event will trigger kendo knockout into unmemoizing the HTML comment <!--[ko_memo:123abc]--> and replacing it with the properly rendered template.

Declarative Grid, method to change my namespace (kendo-) as to not clash with ko. If I remove the line with the data-kendo-detail-template, the grid displays fine. the template also be defined as a declarative grid using a property of the  When using Knockout, all interactions between the DOM and your data are intended to happen in bindings. Knockout provides an extensibility point that allows you to extend the default bindings with your own custom bindings. In simple words, Knockout has magic properties and Kendo has magic objects. Using Knockout-Kendo. Getting started with Knockout-Kendo is easy.

Grid - Knockout-Kendo.js, Home page for the Knockout.js Kendo UI bindings. a user to interact with tabular data. Official Kendo UI Grid documentation var ViewModel = function() { this.items = ko.observableArray([ { id: or kendo.data.DataSource to use in the grid. detailExpand. Fired when the user expands a detail table row. The event handler function context (available via the this keyword) will be set to the widget instance. Event Data e.detailRow jQuery. The jQuery object which represents the detail table row. e.masterRow jQuery. The jQuery object which represents the master table row. e.sender kendo.ui.Grid

Knockout-Kendo.js, <div data-bind="kendoListView: { data: items, template: template }"> </div> var ViewModel = function() { this.items = ko.observableArray([ { id: "1", name: "apple"}​,  The Kendo UI Templates use a simple templating syntax called hash templates. With this syntax, the # (hash) sign is used to mark areas in a template that should be replaced by data when the template is executed. The # character is also used to signify the beginning and end of custom JavaScript code inside the template.

Kendo UI Grid Detail Template MVVM Binding - JSFiddle, without this line, detail template bindings will not work. 15. kendo.bind(e.​detailRow, e.data);. 16. } 17. }).data("kendoGrid");. 18. CSS Tidy. 1. 1. ​  Knockout.js and Kendo UI can be a terrific combination for developing slick and dynamic user interfaces. The Knockout-Kendo library is open source (MIT license) and provides everything that you need to use Kendo UI widgets through Knockout bindings.

Comments
  • Did you ever get this figured out?
  • I followed a different approach where have two rows in row template itself and one row is actual data, the other is detail row. Then use the accordion to trigger the show/hide of detail row. used bootstrap for accordion... works well for me, though its round about way. btw internally this is how they do it as well, but dynamically.
  • I see well I have opened up an issue on GitHub here: github.com/kendo-labs/knockout-kendo/issues/75 if there is an update I will let you know.
  • yes this is how i have done too.. but using bootstrap accordion