Filter Kendo DataSource before read

1 Answer 969 Views
Grid
Jan-Frederik
Top achievements
Rank 1
Iron
Iron
Jan-Frederik asked on 28 Sep 2022, 12:26 PM | edited on 28 Sep 2022, 01:07 PM

I have a kendo grid with an ajax data source. Before the read operation fires, I would like to apply filters dynamically to the data source. I tried to make this work with the RequestStart event of the data source. Specifically, I used e.sender._filter = filters; here to avoid multiple requests. The problem is that on the server, request.Filters is empty. I assume the reason is that_filter is read-only.

@(Html.Kendo().Grid<DataModel>() .Name("grid") .Columns(columns => { columns.Bound(p => p.Id); columns.Bound(p => p.Name); }) .DataSource(dataSource => dataSource .Ajax() .Events(o => o.RequestStart("addFilters")) .Read(read => read.Url("/data?handler=ReadData") ) ) function addFilters(e) { var filters = getGridFilters(); e.sender._filter = filters; //e.sender.filter(filters) works, but would result in an additional request and an infinite loop } function getGridFilters() { var filters = { logic: "and", filters: [{ field: "Name", operator: "contains", value: "xyz"}]}; return filters; } public JsonResult OnPostReadData([DataSourceRequest] DataSourceRequest request) //request.Filters is empty

{}


1 Answer, 1 is accepted

Sort by
0
Momchil
Telerik team
answered on 30 Sep 2022, 01:13 PM

Hello Jan-Frederik,

Thank you for providing a code snippet of the Grid configuration.

If you wish to have some filters applied, the first time the Grid fetches its data, I suggest using the "Filter" configuration option of its DataSource as this is the intended method to add initial filters.

@(Html.Kendo().Grid<DataModel>()
   .Name("grid") 
   .Columns(columns =>
   {
       columns.Bound(p => p.Id);
       columns.Bound(p => p.Name);        
   })
   .DataSource(dataSource => dataSource
       .Ajax()
       .Read(read => read.Url("/data?handler=ReadData")
       .Filter(f => {
	       f.Add(a => a.Name).Contains("xyz");
       })
    )
)

If you wish to intercept every Read request, then you are on the right track. To achieve that:

  • Subscribe to the "RequestStart" event of the Grid's DataSource and prevent its default action.
  • Send a custom request with the required filters by using the query method of the DataSource.
@(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.OrderViewModel>()    
    .Name("grid")
    ...
    .DataSource(dataSource => dataSource
        .Ajax()
        ...
        .Events(e => e.RequestStart("requestStart"))
     )
)

<script>
    // Use a barrier to manage which requests get sent
    var barrier = false;

    function requestStart(e) {
        if(e.type == "read") { // Handle only read requests

            if (barrier) { // Let the request come through if it has been intercepted already
                barrier = false; // Put barrier down for the next read request
                return;
            }

            e.preventDefault(); // Intercept read request and modify it

            // Save current request parameters
            var queryOptions = {
                aggregate: e.sender.aggregate(),
                group: e.sender.group(),
                sort: e.sender.sort(),
                filter: e.sender.filter(),
                page: e.sender.page(),
                pageSize: e.sender.pageSize(),
            };

            // Add the custom filter
            if(queryOptions.filter) {
                queryOptions.filter.filters.push({ field: "ShipCity", operator: "contains", value: "de" });
            }
            else {
                queryOptions.filter = { logic: "and", filters: [{ field: "ShipCity", operator: "contains", value: "de"}]};
            }

            barrier = true; // Lift barrier up for the next read request
            e.sender.query(queryOptions); // Send modified read request
        }        
    }
</script>

The following REPL sample illustrates what I described above.

Let me know if what I suggested works as per your requirements. Looking forward to hearing your feedback.

 

Best Regards,
Momchil
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Tags
Grid
Asked by
Jan-Frederik
Top achievements
Rank 1
Iron
Iron
Answers by
Momchil
Telerik team
Share this question
or