4

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/

Camille Laborde
  • 858
  • 11
  • 17
  • What if you change `data: LienActionIndicateurPourFicheCollection` to `data: ko.toJS(LienActionIndicateurPourFicheCollection)`? – sroes Jan 27 '14 at 19:58
  • I just tried, but as I expected, i'm losing the binding between the grid and the collection if i'm doing that (remove a row from collection does not update the grid). – Camille Laborde Jan 28 '14 at 09:04

2 Answers2

2

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

Community
  • 1
  • 1
sroes
  • 14,663
  • 1
  • 53
  • 72
  • Thanks for your answer ! Unfortunately, the update on Collection are still not shown in the grid : try to do delete an item there : http://jsfiddle.net/camlaborde/htq45/3/ – Camille Laborde Jan 28 '14 at 09:55
  • I think it's because it the removeItem function, the 'item' parameters is no longer an observable ... i think i have found a workaround and will post it soon – Camille Laborde Jan 28 '14 at 10:03
  • Ok ! here the solution : http://jsfiddle.net/camlaborde/htq45/4/ ! Thanks a lot :) – Camille Laborde Jan 28 '14 at 10:06
  • Yeah, you beat me to it. You have to check if the ids equal because the objects aren't the same anymore. – sroes Jan 28 '14 at 10:08
  • I think I will have to think this further again, cause with this solution, I can't have inline edition into the grid anymore : if I bind a span to the first line string value : http://jsfiddle.net/camlaborde/8aR8T/2/ – Camille Laborde Jan 30 '14 at 07:49
  • You could apply the same workaround as when you delete an item. See http://jsfiddle.net/8aR8T/3/ – sroes Jan 30 '14 at 08:47
  • Yeah works great ! I think I'm even going to add a ko.observableArray.fn.getItemById(prop,value), to use that for all my collection ! – Camille Laborde Jan 30 '14 at 08:58
0

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.

JoeWarwick
  • 105
  • 2
  • 8