Multiple Filter on kendogrid not working

user3263194 picture user3263194 · Mar 18, 2014 · Viewed 7.2k times · Source

I'm trying to put 2 filters on kendo grid with 'OR' logic. It's not working. I need the grid to be filtered with the both the dropdowns. If in Foo dropdown 'foo1' is selected and in Bar dropdown 'All' selected, then the grid should be displaying

 foo     bar
  1       1
  1       2

Code below:

$(function() {  
 var grid=$("#grid").kendoGrid({
 dataSource: {
 data: [
    { foo: "1", bar: "1" },{ foo: "1", bar: "2" },
    { foo: "2", bar: "2" },{ foo: "2", bar: "1" },
    { foo: "3", bar: "3" },{ foo: "3", bar: "2" }
    ]
},
columns: [
  "foo","bar"
],
toolbar: kendo.template($("#template").html())
});
grid.find("#foo").kendoDropDownList({
        dataTextField: "name",
        dataValueField: "id",
        autoBind: false,
        optionLabel: "All",
dataSource: [{id:'1', name:'foo1'}, {id:'2', name:'foo2'},{id:'3', name:'foo3'}],
        change: function () {
          var ds = $("#grid").data("kendoGrid").dataSource;        

var filter = {
  logic: "and",
  filters: []
};    
if (this.value()) {
filter.filters.push([{ field: "bar", operator: "eq", value:      
$("#bar").data('kendoDropDownList').value() },
 { field: "foo", operator: "eq", value:  $("#foo").data('kendoDropDownList').value() } 
]);
}
          ds.filter([filter]);
 }
});
grid.find("#bar").kendoDropDownList({
        dataTextField: "name",
        dataValueField: "id",
        autoBind: false,
        optionLabel: "All",
dataSource: [{id:'1', name:'bar1'}, {id:'2', name:'bar2'},{id:'3', name:'bar3'}],
        change: function () {
          var ds = $("#grid").data("kendoGrid").dataSource;        

var filter = {
  logic: "and",
  filters: []
};    
if (this.value()) {
filter.filters.push([{ field: "bar", operator: "eq", value:    
$("#bar").data('kendoDropDownList').value() },
 { field: "foo", operator: "eq", value:  $("#foo").data('kendoDropDownList').value() } 
]);
}
          ds.filter([filter]);
}
});
});
After pushing the filters to the filter array the grid datasource is not filtered.

Updated jsbin below: http://jsbin.com/izuloj/23/edit

Answer

OnaBai picture OnaBai · Mar 18, 2014

There are couple of problems:

  • The argument for DataSource filters is an array but you are pushing an array when you do:
filter.filters.push([
    { field: "bar", operator: "eq", value:  $("#bar").data('kendoDropDownList').value() },
    { field: "foo", operator: "eq", value:  $("#foo").data('kendoDropDownList').value() } 
]);
  • Comparing with empty is not the same that not adding the condition. So you should actually do:
// If there is some value in "bar" we add a condition for filtering it
if ($("#bar").data('kendoDropDownList').value()) {
    filter.filters.push({ 
        field: "bar", 
        operator: "eq", 
        value:  $("#bar").data('kendoDropDownList').value() }
    );
}

// If there is some value in "foo" we add a condition for filtering it
if ($("#foo").data('kendoDropDownList').value()) {
    filter.filters.push(
        { 
            field: "foo", 
            operator: "eq", 
            value:  $("#foo").data('kendoDropDownList').value() } 
    );
}
  • Finally, you should not set any filter if both drop down inputs are empty but in that case you cannot send an empty filter array, you should do ds.filter({})) instead.

So your change function ends being:

function onChange () {
    var ds = $("#grid").data("kendoGrid").dataSource;        
    var filtering = false;

    var filter = {
        logic: "and",
        filters: []
    };    
    if ($("#bar").data('kendoDropDownList').value()) {
        filtering = true;
        filter.filters.push(
            { field: "bar", operator: "eq", value:  $("#bar").data('kendoDropDownList').value() }
        );
    }
    if ($("#foo").data('kendoDropDownList').value()) {
        filtering = true;
        filter.filters.push(
            { field: "foo", operator: "eq", value:  $("#foo").data('kendoDropDownList').value() } 
        );
    }
    if (filtering) {
        ds.filter([filter]);
    } else {
        ds.filter({});
    }
}

Your code modified here : http://jsbin.com/izuloj/31/edit