DataSourceRequest Manipulating / Out of box filtering (FilterDescriptor vs CompositeFilterDescriptor)

1 Answer 822 Views
Grid
Kerem
Top achievements
Rank 1
Kerem asked on 09 Oct 2014, 11:42 AM
Hi everyone,

I'm working on a grid that needs different type of filtering. For example: I've an hierarchical departments table and when i choose a parent department, grid should show me all students under the children departments. I've spent hours on this and figured it out.

Extension Method:
public static class Extensions
{
    public static List<FilterDescriptor> ToFilterDescriptor(this IList<IFilterDescriptor> filters)
    {
        var result = new List<FilterDescriptor>();
        if (filters.Any())
        {
            foreach (var filter in filters)
            {
                var descriptor = filter as FilterDescriptor;
                if (descriptor != null)
                {
                    result.Add(descriptor);
                }
                else
                {
                    var compositeFilterDescriptor= filter as CompositeFilterDescriptor;
                    if (compositeFilterDescriptor!= null)
                    {
                        result.AddRange(compositeFilterDescriptor.FilterDescriptors.ToFilterDescriptor());
                    }
                }
            }
        }
        return result;
    }
}

In Use:
public ActionResult List([DataSourceRequest] DataSourceRequest request)
{
    var departments= new List<int?>();
    var nRequest = new DataSourceRequest
    {
        Groups = request.Groups,
        Aggregates = request.Aggregates,
        Page = request.Page,
        PageSize = request.PageSize,
        Sorts = request.Sorts,
        Filters = new List<IFilterDescriptor>()
    };
  
    if (request.Filters.Any())
    {
        foreach (var fdc in request.Filters.ToFilterDescriptor())
        {
            switch (fdc.Member)
            {
                case "DepartmentId":
                    var department = Convert.ToInt32(fdc.Value);
                    departments.AddRange(db.StoredProcedureToTakeDepartmentsTree(department).Select(o => o.Id));
                    break;
               default:
                    nRequest.Filters.Add(new FilterDescriptor
                    {
                        Member = fdc.Member,
                        MemberType = fdc.MemberType,
                        Operator = fdc.Operator,
                        Value = fdc.Value
                    });
                    break;
            }
  
        }
    }
    if (!departments.Any())
    {
         //departments = default departments if it's empty
    }
  
    var model = db.Students.Where(o => departments.Contains(o.DepartmentId))
              .Select(o => new
               {
                    o.Id
                   //Some columns
               })
    return Json(model.ToDataSourceResult(nRequest), JsonRequestBehavior.AllowGet);
}


I hope it helps...
Best Regards
Cornel
Top achievements
Rank 1
commented on 03 Oct 2017, 08:15 AM

Thanks Kerem for this post, it helped me a lot!
Reinier
Top achievements
Rank 1
commented on 26 Jun 2019, 12:51 PM

Hi Kerem,

I use your solution to remove one filter out of the request.filters, but then the structure of the nRequest.filters are changed.

The CompositeFilterDescriptor is removed and there is only a list left of FilterDescriptors.

ToDataSourceResult(nRequest) accept this but what is the effect of this filters for the result?

 

Regards, Reinier Pechler

 

 

1 Answer, 1 is accepted

Sort by
0
Alex Hajigeorgieva
Telerik team
answered on 28 Jun 2019, 08:15 AM
Hello, Reinier,

We have a how-to article which shows how to loop and modify filters on the server without changing their type in the documentation here:

https://docs.telerik.com/aspnet-mvc/helpers/grid/how-to/Filtering/get-all-filters-recursively-modify-servre-side

For your convenience, here is the method:

private void ModifyFilters(IEnumerable<IFilterDescriptor> filters)
{
    if (filters.Any())
    {
        foreach (var filter in filters)
        {
            var descriptor = filter as FilterDescriptor;
            if (descriptor != null && descriptor.Member == "OrderDate")
            {
                descriptor.Member = "OrderDate.Date";
            }
            else if (filter is CompositeFilterDescriptor)
            {
                ModifyFilters(((CompositeFilterDescriptor)filter).FilterDescriptors);
            }
        }
    }
}
 
public ActionResult Read([DataSourceRequest] DataSourceRequest request)
{
    ModifyFilters(request.Filters);
 
    return Json(OrderRepository.GetAll().ToDataSourceResult(request));
}

I hope this helps.

Kind Regards,
Alex Hajigeorgieva
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
John
Top achievements
Rank 1
Veteran
commented on 26 Aug 2020, 08:15 PM

Hi Alex,

Are there any examples of getting this to work with other Data Types?  Specifically, when I try to do this with int and decimal data types I get the following error:

'Method 'System.String ToLower()' declared on type 'System.String' cannot be called with instance of type 'System.Decimal'.

Thank you,
John

Tsvetomir
Telerik team
commented on 28 Aug 2020, 01:17 PM

Hi John,

The example provided by my colleague intends to modify the filter's member value without changing the data type by no means. Could you share an example in which the implementation you are currently working on is present? I will investigate it locally and get back to you with the respective suggestions.

 

Kind regards,
Tsvetomir
Progress Telerik

Five days of Blazor, Angular, React, and Xamarin experts live-coding on twitch.tv/CodeItLive , special prizes and more, for FREE?! Register now for DevReach 2.0(20).

Tags
Grid
Asked by
Kerem
Top achievements
Rank 1
Answers by
Alex Hajigeorgieva
Telerik team
Share this question
or