Using Kendo Grid with knockoutjs row template make filtering impossible

1.4k Views Asked by At

I'm currently building an application using knockoutjs for the MVVM pattern, and Kendo Web for the controls. I have somme issues with filtering/grouping the data in the kendo grid.

I need to have highly customizable rows, and so I choose to use row template according to this sample :

http://rniemeyer.github.io/knockout-kendo/web/Grid.html

I also need to have a two way binding with the grid, cause I need to add/remove/update items.

The grid :

<div data-bind="kendoGrid: {    
    data: LienActionIndicateurPourFicheCollection, 
    widget: indicateurWidget,
    rowTemplate: 'indicateurRowTmpl', 
    useKOTemplates: true,
    dataSource : {
        schema: {
            model: {
                fields: {
                    Code: { type: 'string' },
                    Titre: { type: 'string' },
                    Note: { type: 'number' }              
                }
            }
        },
    },
    columns: [            
       { title: '#', width: 30 },
       { field: 'Code', title: 'Code', width: 80 },
       { field: 'Titre', title: 'Titre', width: 150 },
       { field: 'Note', title: 'Note', width: 80 }]
    }">
</div>

The row template :

<script id="indicateurRowTmpl" type="text/html">
    <tr">
        <td>
            <button data-bind="visible: $root.isInEditMode, click: removeIndicateur"
                    class="common-button delete-button"></button>
        </td>
        <td data-bind='text: Code'></td>
        <td data-bind='text: Titre'></td>
        <td data-bind='text: Note'></td>
    </tr>
</script>

When I'm using the grid, it works fine, expect when I use grouping/filtering : it's like the grid is using the observable objet instead of the value to perform the operations.

Example : When I'm grouping on 'Note' integer value : enter image description here

To prevent that, I have replaced in columns definition "field: 'Note'" by "field: 'Note()'" : the grouping works fine now, since grid use the integer value instead of a function.

But the filtering remain impossible : the column filter menu has changed from number filter to string filter when I have make the 'Note()' change. I suppose it's because the fields entry key 'Note' does not match the columns entry key 'Note()' anymore !

  • I've tried to replace 'Note' by 'Note()' in fields definition : does not work.
  • I've replace Note observable by a non observable variable in my item model : all is working fine, but i'm not enable to edit those values anymore, and I want to.

Thanks for your help !

EDIT : here a jsfiddle reproducting the bug : http://jsfiddle.net/camlaborde/htq45/1/

EDIT#2 here's the final solution, thanks to sroes : http://jsfiddle.net/camlaborde/htq45/7/

EDIT#3 final solution plus inline grid edition : http://jsfiddle.net/camlaborde/8aR8T/4/

2

There are 2 best solutions below

7
On BEST ANSWER

It works if you create a computed which returns the items as a plain JS object:

this.items.asJS = ko.computed(function() {
    return ko.toJS(this.items());
}, this);

http://jsfiddle.net/htq45/2/

The reason why putting ko.toJS(this.items) directly in the binding doesn't work is because the way kendo tracks individual options in the bindings. Knockout.js man RP Niemeyer taught me this: Dynamically enable/disable kendo datepicker with Knockout-Kendo.js

0
On

I solved this issue by using Knockout ES5. Then, when assigning my data to my model, I used knockout-mapping with a mapping object like this:

    var dataMapper = {
        create: function(o) {
            return ko.track(o.data), o.data;
        }
    };
    ko.mapping.fromJS(json, dataMapper, self.data);

This makes the filtering and sorting work out of the box for the knockout kendo grid.