This is a migrated thread and some comments may be shown as answers.

Filter not working when applied to a grid from server-side

7 Answers 674 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Sibin
Top achievements
Rank 1
Sibin asked on 12 Jan 2021, 10:14 AM

Hi,

I am trying to apply filter to a grid from server-side. Below is the implementation. 

public static AjaxDataSourceBuilder<T> Configure<T>(this AjaxDataSourceBuilder<T> source, UserGridPreferenceVM userPreferences) where T : class
{
    if (userPreferences.Filter?.Filters != null && userPreferences.Filter.Filters.Length > 0)
    {
        List<FilterDescriptor> filters = new List<FilterDescriptor>();
  
        foreach (FilterElement filter in userPreferences.Filter.Filters)
        {
            filters.Add(new FilterDescriptor(filter.Field, GetFilterOperator(filter.Operator), filter.Value));
        }
  
        source.Filter(s =>
        {
            s.AddRange(filters);
        });
    }
  
    return source;
}

 

I have 2 questions.
1. When the grid loads the filter condition is set but value of the filter is not set.
2. How we can apply Logic operator "And"/"Or" to the filter wrt above code snippet?

 

Thanks in advance.

7 Answers, 1 is accepted

Sort by
0
Nikolay
Telerik team
answered on 15 Jan 2021, 09:40 AM

Hello Sibin,

Straight to the questions.

1. Since the filtering is applied server-side the Grid does not have information about it. The Grid receives the already filtered data which for the Grid is the whole data.

2. The "and" logic can be applied by simply adding a new FilterDescriptor() object. For instance:

        public ActionResult GetStudents([DataSourceRequest] DataSourceRequest request)
        {

            IList<IFilterDescriptor> filters = new List<IFilterDescriptor>() { 
                new FilterDescriptor() { Member = "FirstName", Value = "James", Operator = FilterOperator.IsEqualTo },
                new FilterDescriptor() { Member = "LastName", Value = "Smith", Operator = FilterOperator.IsEqualTo }
            };
            request.Filters = filters;

            return Json(students.ToDataSourceResult(request));
        }

However, I strongly recommend adding the filters through the API of the grid.

For example:

@(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.OrderViewModel>()
    ...
    .DataSource(dataSource => dataSource
        .Ajax()
        .Filter(x=> x.Add(y=> y.Freight).IsGreaterThan(12).And().IsLessThan(25))
      ...
     )
)

This way, not only the data will be filtered, but the filter UI will reflect the applied filters. Additionally, the above configuration demonstrates how to chain filter expressions with AND/OR.

Let me know if you have any questions.

Regards,
Nikolay
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Sibin
Top achievements
Rank 1
answered on 18 Jan 2021, 05:00 AM

Hi Nikolay,

Grid API is my first preference to apply the filter logic. But again I need this to be a generic implementation. That was the purpose of the extension method for the grid API which I send you in the first post.

As per the suggestion I had changed the generic extension method as below. But unfortunately this too is not working. The lambda expression I input to add method is not understood for the grid API filter method. Can you please help with this issue? 

public static AjaxDataSourceBuilder<T> Configure<T>(this AjaxDataSourceBuilder<T> source, UserGridPreferenceVM userPreferences) where T : class
        {
            if (userPreferences.Filter?.Filters != null && userPreferences.Filter.Filters.Length > 0)
            {
                foreach (FilterElement filter in userPreferences.Filter.Filters)
                {
                    if (String.IsNullOrEmpty(filter.Field) || String.IsNullOrEmpty(filter.Operator))
                    {
                        continue;
                    }
 
                    PropertyInfo prop = typeof(T).GetProperty(filter.Field);
                    dynamic value = Convert.ChangeType(filter.Value.ToString(), prop.PropertyType);
 
                    ParameterExpression parameter = Expression.Parameter(typeof(T), "e");
                    MemberExpression memeberExp = Expression.Property(parameter, filter.Field);
                    ConstantExpression constant = Expression.Constant(value, prop.PropertyType);
                    BinaryExpression body = GetBody(memeberExp, constant, filter.Operator);
 
                    Expression<Func<T, bool>> expression = Expression.Lambda<Func<T, bool>>(body, parameter);
 
                    source.Filter(s =>
                    {
                        s.Add(expression);
                    });
 
                }
            }
 
            return source;
        }
private static BinaryExpression GetBody(MemberExpression me, ConstantExpression constant, string operatorValue)
        {
            switch (operatorValue)
            {
                case "gt":
                    return Expression.GreaterThan(me, constant);
 
                case "eq":
                    return Expression.Equal(me, constant);
 
               .... // removed for brevity
            }
 
            throw new InvalidOperationException(operatorValue);
        }

 

thanks

0
Nikolay
Telerik team
answered on 20 Jan 2021, 08:48 PM

Hello Sibin,

I will see what we can do, however, I will need a bit more time to investigate. Please expect another reply shortly.

Regards,
Nikolay
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Nikolay
Telerik team
answered on 01 Feb 2021, 02:39 PM

Hello Sibin,

As promised I am getting back to you.

Since the late Kendo UI R1 2021 release, the Grid Toolbar uses new styles to be aligned with Kendo UI Toolbar which affects the described behavior.

In the current case, the Kendo UI Button needs to be wrapped in an element with class .toolbar:

<div class="toolbar">
    @Html.Kendo().Button().Name("btnDtGrdInsert").Content("Insert Record")
</div>

This has been demonstrated in the following demo:

Let me know if you have any questions.

Regards,
Nikolay
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Sibin
Top achievements
Rank 1
answered on 02 Feb 2021, 11:51 AM

Hi Nikolay,

But my question was not regarding the Grid toolbar button. Can you please go though the thread once more and let us know?

Thank you,

Sibin.

0
Nikolay
Telerik team
answered on 03 Feb 2021, 11:52 AM

Hi Sibin,

Apologies for the wrong reply. I have missed up threads.

I am still working on it and will follow up.

Regards,
Nikolay
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Nikolay
Telerik team
answered on 10 Mar 2021, 03:18 PM

Hello Sibin,

I am following up on the inquiry. 

I consulted with the team and was advised that the desired server-side filtering can be achieved using the Kendo.Mvc.CompositeFilterDescriptor. This has been demonstrated in the following forum post:

Let me know if you have any questions.

Regards,
Nikolay
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Tags
Grid
Asked by
Sibin
Top achievements
Rank 1
Answers by
Nikolay
Telerik team
Sibin
Top achievements
Rank 1
Share this question
or