How to make checkboxes object column filter which will use object's property

1 Answer 357 Views
Grid
kva
Top achievements
Rank 2
Iron
Iron
Iron
kva asked on 20 Jul 2023, 10:08 AM | edited on 03 Aug 2023, 04:47 AM
In grid, I have a column for User, which shows the User's Name. I want to create a checkboxes column filter which will show users' names. How to implement this?
Stoyan
Telerik team
commented on 07 Aug 2023, 08:45 PM

Hello Kva,

If I understand your question correctly you are looking to achieve a filter menu that is to filter the rows of the Grid via the selected checkbox of the filter menu.

This can be achieved by setting the Multi configuration of a Grid's column:

columns.Bound(p => p.ProductName).Filterable(ftb => ftb.Multi(true).Search(true));

For a runnable example on the topic I recommend our Multicheckbox Grid Filtering demo.

Alternatively, if I have misunderstood what is the desired outcome, please share as much information on the topic as is available to you.

kva
Top achievements
Rank 2
Iron
Iron
Iron
commented on 09 Aug 2023, 06:33 AM

As I wrote, I have a column for User, which shows the User's Name. So, please, provide answer for User's Name.
Stoyan
Telerik team
commented on 11 Aug 2023, 04:10 PM | edited

Hello Kva,

As far as I understand in the current case you are looking to use MultiCheckbox Filtering on a Grid column that is bound to a complex type. Am I correct?

To add the Checkbox you can use the ItemTemplate of the Column's Filterable property. This will allow you to customize the multiple checkboxes:

 

columns.Bound(p => p.Category).ClientTemplate("#=Category.CategoryName#").Width(180) .Filterable(ftb => ftb.Multi(true).CheckAll(false).ItemTemplate("categoryFilterItemTemplate")
.DataSource(ds => ds.Ajax().Read(r => r.Action("EditingCustom_Read", "Grid").Data("{ field: 'Category' }"))))

 

 

    function categoryFilterItemTemplate(e) {
            return "<span><label><input class='product-filter-input' type='checkbox' name='" + e.field + "' value='#= Category.CategoryName #'/><span>#= Category.CategoryName #</span></label></span><br/>"
        }

I've applied the behavior of the code above to this Telerik REPL example.

 

However, to achieve the actual filtering when only one property of the complex type is submitted poses an additional hurdle. I am currently investigating possible solutions and will contact you again to let you know about my findings.

Thank you for your patience in advance!

 

Stoyan
Telerik team
commented on 14 Aug 2023, 01:36 PM | edited

Hello Kva,

I'd like to update you that I am continuing to investigate the matter at hand.

With that said it is also worth noting that the complex configuration that would be needed can be avoided, if you could bind the Grid's column to a property of the nested object.

For example:

columns.Bound(p => p.User.Name).Filterable(ftb => ftb.Multi(true).CheckAll(false)
.DataSource(ds => ds.Ajax().Read(r => r.Action("EditingCustom_Read", "Grid").Data("{ field: 'User.Name' }"))))
Let me know whether this configuration is feasible in the requirement at hand otherwise I will continue the research on Filtering of column bound to a complex model property.

 

 

 

1 Answer, 1 is accepted

Sort by
1
Stoyan
Telerik team
answered on 21 Aug 2023, 11:55 AM | edited on 21 Sep 2023, 01:37 PM

Hello Kva,

Here is how you can achieve Filtering of a Grid column that binds to a complex object at the server-side:

  1. Define a method that realizes the custom filtering;
    public IQueryable<OrderViewModel> CategoryFilter(IQueryable<OrderViewModel> orders,IQueryable<FilterDescriptor> categoryFilters)
            {
                IQueryable<OrderViewModel> filteredOrders = orders;
                foreach (var filter in categoryFilters)
                {
                    var filterValue = filter.Value;
                    filteredOrders = orders.Where(x=>x.Category.CategoryName==filter.Value.ToString());  
                }
                
                return filteredOrders;
            }
  2. Define a method to modify the filters of the DataSourceRequst to remove any FilterDescriptors related to the column. This is needed because the filters are passed as strings and a casting error from a string to an object type would occur;
    public void ModifyFilters(IList<IFilterDescriptor> filters)
            {
                if (filters.Any())
                {
                    for (int i = filters.Count - 1; i >= 0; i--)
                    {
                        var filter = filters[i];
                        var descriptor = filter as FilterDescriptor;
                        if (descriptor != null && descriptor.Member == "Category")
                        {
                            var index = filters.IndexOf(filter);
                            filters.RemoveAt(index);
                        }
                        else if (filter is CompositeFilterDescriptor)
                        {
                            ModifyFilters(((CompositeFilterDescriptor)filter).FilterDescriptors);
                        }
                    }
                }
            }
  3. In the Controller access the request and save the filters for the complex column in a variable - e.g. categoryFilter;
    var filters = FilterDescriptorExtensions.SelectMemberDescriptors(request.Filters).AsQueryable();
    var categoryFilters = filters.Where(x => x.Member == "Category");
  4. After retrieving the data from the database, apply the custom filtering.
                var result = GetData();
                result = CategoryFilter(result, categoryFilters);
  5. Apply the ModifyFilters method of the original request to remove the FilterDescriptors of the field.
    ModifyFilters(request.Filters);

The sample snippets above are excerpts from the attached sample project. You can run it to see the entire behavior in action.

Additionally, the ModifyFilter method implementation was inspired by the grid-get-all-filters-recursively-and-modify-them-on-server MVC Example at our GitHub examples repo.

I hope the information above is useful.

Regards,
Stoyan
Progress Telerik

Stay tuned by visiting our public roadmap and feedback portal pages. If you're new to the Telerik family, be sure to check out our getting started resources, as well as the only REPL playground for creating, saving, running, and sharing server-side code.
Tags
Grid
Asked by
kva
Top achievements
Rank 2
Iron
Iron
Iron
Answers by
Stoyan
Telerik team
Share this question
or