Sunday, July 5, 2020

Kendo Serverside filters with ajax and mvc

Kendo Serverside filters with ajax and mvc 

why? when we don't want to load millions on records on in grid at once, so we need paging , 

but for filters/sorting we need to filter among the million records and show only pageSize records.

Kendo says to use the DataSourceRequest as below

public ActionResult Paging_Orders([DataSourceRequest] DataSourceRequest request)
{
    return Json(GetOrders().ToDataSourceResult(request));
}
but for multiple filters you may get the following errors












Solution
create a class dataSourceHelper.cs
public class DataSourceHelper
    {
public static DataSourceRequest GetDataSourceRequest(string filter, string sort, string page, string pageSize)
{
DataSourceRequest request = new DataSourceRequest()
{
Page = Convert.ToInt32(page),
PageSize = Convert.ToInt32(pageSize) };
if (page == null)
page = "1";
if (pageSize == null)
pageSize = "25";
if (request.Filters == null && !string.IsNullOrEmpty(filter))
{
request.Filters = new List<Kendo.Mvc.IFilterDescriptor>(); request.Filters.AddRange(getFilter(filter));
}
if (request.Sorts == null && !string.IsNullOrEmpty(sort))
{
request.Sorts = new List<Kendo.Mvc.SortDescriptor>();
request.Sorts.AddRange(getSorts(sort)); }
return request;
}
private static IEnumerable<SortDescriptor> getSorts(string sort)
{
List<SortDescriptor> list = new List<SortDescriptor>(); string[] sorts = sort.Split(new[] { "-and-" }, StringSplitOptions.None);
foreach (string s in sorts)
{
string[] x = s.Split('-');
if (x.Length == 2)
list.Add(new SortDescriptor() { Member = x[0], SortDirection = getDirection(x[1]) });
}
return list;
} private static ListSortDirection getDirection(string dir)
{
switch (dir)
{
case "asc":
return ListSortDirection.Ascending; default:
return ListSortDirection.Descending;
}
} private static IEnumerable<IFilterDescriptor> getFilter(string filter)
{
List<IFilterDescriptor> list = new List<IFilterDescriptor>();
string[] filters = filter.Split(new[] { "~and~" }, StringSplitOptions.None);
foreach (string f in filters)
{
string[] x = f.Split('~');
list.Add(new FilterDescriptor() { Member = x[0], MemberType = typeof(string), Operator = getFilterOperator(x[1]), Value = x[2].Trim(new char[] { (char)39 }) });
}
return list;
} private static FilterOperator getFilterOperator(string str)
{
switch (str)
{
case "startswith":
return FilterOperator.StartsWith; case "eq":
return FilterOperator.IsEqualTo;
case "neq":
return FilterOperator.IsNotEqualTo;
default:
return FilterOperator.Contains;
}
}
}
Also do not forget the reference dll using tags
using Kendo.Mvc;
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
Usages
you can call the below datasource and bind it to your grid.
    var dataSource= new kendo.data.DataSource({

        type: "webapi",
        dataType: "json",        
        serverPaging: true,
        serverSorting: true,
        serverFiltering: true,
        pageSize: 500,
        transport: {
            read: {
                url: home + "/Action/GetDataMethod"
            }
        },
        schema: {
            total: "Total",
            data: "Data"
            
        }
        
    });
Controller
 public JsonResult GetDataMethod( string filter,string sort, string page, string pageSize)
        {
            DataSourceRequest request = new DataSourceRequest();
            request = DataSourceHelper.GetDataSourceRequest(filter, sort, page, pageSize);
           						
            var result = BusinessLogic.GetData();//your logic to get millions of data
            if (result != null)
            {
                var filterResult = result.Data.ToDataSourceResult(request);
                request.Page = 1;
                request.PageSize = result.Total;
                result.Total= (int)result.WorkQueueItems.ToDataSourceResult(request).Total;
result.Data= (IEnumerable<DataView>)filterResult.Data;
} return Json(result, Constants.ResultTypes.ApplicationJson, System.Text.Encoding.Unicode, JsonRequestBehavior.AllowGet); }
Note: Total is required to construct the paging section.



No comments:

Post a Comment