If you’re using Kendo UI’s grid, you know you can plug it into a Web API OData data source.  The nice thing about using an OData end point is you don’t have to parse all the possible filter values in your Web API code.  You’d have to plan for column names, values, different operators, and’ing and or’ing of values, etc.  Instead, with OData, just keep the data IQueryable, mark the method with a [Queryable] attribute, and you’re all set.

But what if you want some client-side filtering to start off with?  You could hack up the OData URL sent back to Web API, or you could set a filter on the grid’s data source (extending the example here).

$(function () {
    var dataSource = new kendo.data.DataSource({
        type: "odata",
        transport: {
            read: {
                url: "/api/Cats",
                dataType: "json"
            },
        },
        schema: {
            data: function (data) {
                return data["value"];
            },
            total: function (data) {
                return data["odata.count"];
            },
            model: {
                fields: {
                    Id: { type: "number" },
                    Name: { type: "string" },
                    Color: { type: "string" }
                }
            }
        },
        pageSize: 10,
        serverPaging: true,
        serverFiltering: true,
        serverSorting: true,
        filter: { field: "Color", operator: "eq", value: "black" }
    });
 
    $("#grid").kendoGrid({
        dataSource: dataSource,
        filterable: true,
        sortable: true,
        pageable: true,
        columns: [
            { field: "Id" },
            { field: "Name" },
            { field: "Color" }
        ]
    });
});

See the “filter” setting on the data source?  That will tell OData to search for /api/Cats/?<other OData stuff>&$filter=Color eq ‘black’ on the URL (you will probably get a “+” symbol instead of a space from URL encoding).  This URL stuff will become part of the query’s where clause and filter your data.  Since this is just a grid filter, your user can go in and edit it, clear it, etc.

But what if you have more complex filtering needs?  What if you have multiple values or “or” logic instead of “and” logic?

filter: {
    logic: "or",
    filters: [
        { field: "Name", operator: "contains", value: "fluffy" },
        { field: "Color", operator: "eq", value: "black" }
    ]
}

This will let you “or” your columns, so you are looking for Names containing “fluffy” or Colors equal to “black”.  The URL will look like /api/Cats/?<other OData stuff>&$filter=(substringof(‘fluffy’,Name) or Color eq ‘black’).

What if your filtering needs are more complex than this?  What if you have both “and” and “or” logic you want to pass through to filter your OData?

filter: [
    {
        logic: "or",
        filters: [
            { field: "Name", operator: "contains", value: "fluffy" },
            { field: "Color", operator: "eq", value: "black" }
        ]
    },
    {
        logic: "and",
        filters: [
            { field: "Active", operator: "eq", value: true }
        ]
    }
]

The grid’s filter property is smart enough to handle more complex JavaScript objects thrown at it, as long as is matches the filter pattern.  Take advantage of this to prefilter your grid data so those fancy OData queries don’t send down values that aren’t helpful for your end users.