Declined
Last Updated: 03 Apr 2023 11:07 by ADMIN
Clark
Created on: 27 Mar 2023 14:17
Category: Grid
Type: Bug Report
1
Grid infers search string from first FilterDescriptor

Problem

It seems the Grid and GridSearchBox assume the search string by taking the value of GridState.SearchFilter.FilterDescriptors[0].Value and this is causing a few issues:

  1. If the first filter is a CompositeFilterDescriptor, it causes an exception.
  2. If there is no filter, the search box gets cleared.
  3. If the first filter has a different value than what was typed (because filters were added/changed programmatically), the search box value will be changed.

Background

I am expanding grid search to include non-string columns, and I want this to apply by default across our entire application without having to update every grid individually or developers having to remember to opt in.

To search other type columns, I’ve largely taken the logic from Search Grid in numeric and date fields - Telerik UI for Blazor and it works well. However, that solution utilizes a custom search box component that I would have to add to each grid.

Instead, I have placed this filter creation logic in the OnStateChanged handler as exemplified in How to Search Grid Items with a StartsWith Filter Operator - Telerik UI for Blazor, as we already have a handler for this event that all grids utilize.

This has worked wonderfully except for the issues I’ve mentioned.

Issue #1 – CompositeFilterDescriptor causes exception

If the first filter is a CompositeFilterDescriptor, it causes an exception. Specifically:

Unable to cast object of type 'Telerik.DataSource.CompositeFilterDescriptor' to type 'Telerik.DataSource.FilterDescriptor'.
   at Telerik.Blazor.Components.Common.TableGridBase`2.LoadSearchFilter(IFilterDescriptor descriptor)
   at Telerik.Blazor.Components.TelerikGrid`1.SetStateInternal(GridState`1 state)
   at Telerik.Blazor.Components.TelerikGrid`1.<SetStateAsync>d__311.MoveNext()
   at Web.Pages.Grid.<OnStateChangedHandler>d__18.MoveNext() in C:\src\Web\Pages\Grid.razor:line 196

If there is another filter in the collection that is not a CompositeFilterDescriptor, I can work around this problem by moving it to the front of the list.

// Make sure first filter is not composite.
var nonCompositeFilter = newSearchFilter.FilterDescriptors.OfType<FilterDescriptor>().FirstOrDefault();
if (nonCompositeFilter is not null && newSearchFilter.FilterDescriptors[0] is CompositeFilterDescriptor)
{
    newSearchFilter.FilterDescriptors.Remove(nonCompositeFilter);
    newSearchFilter.FilterDescriptors.Insert(0, nonCompositeFilter);
}

However, if all filters are composite, the exception is unavoidable.

Issue #2 – Search box gets cleared

If the GridState.SearchFilter.FilterDescriptors collection is empty, the search box gets cleared. This is a problem when a user needs to type more characters for a filter to be created.

For example, let’s say you are only searching DateTime columns and using the logic from Search Grid in numeric and date fields - Telerik UI for Blazor. As you type, it checks to see if the input is an integer between 1000 and 2100. Until you type the fourth digit, it will not meet that condition thus will not add a filter. So if you begin by typing “2”, it searches and a filter will not be added yet. However, because there are no filters, it will clear the search box. You won’t be able to type out a full year value of “2023” unless you type fast enough to outpace the debounce delay.

Issue #3 – Search box gets changed

Using the same example as above but with an Enum column instead of a DateTime, begin typing text. If the text matches an enum name, a filter is added for the enum item’s underlying value. For example:

  1. Type “e”.
  2. The first enum item’s name matches “e”, so a filter is added for (int)item IsEqualTo 0.
  3. The search box text is replaced with “0”.

Possible solutions?

  1. Is there some sort of “dummy” filter descriptor I could add to the beginning of the FilterDescriptors collection? Like, it would contain the search string as the Value but it would always evaluate to true and never affect which records match?
  2. I give in and create a custom search box component to hold the search string value separate from GridState, which would require me to update every current and future grid after all.
  3. Telerik could add a SearchString property to the GridState separate from the SearchFilter so that any filter changes would not affect the search string. Or something.

Sample project attached.

Attached Files:
1 comment
ADMIN
Dimo
Posted on: 03 Apr 2023 11:07

Hi Clark,

Thanks for the runnable test project.

As you already realize, all 3 issues are caused by incompatible usage of the built-in Grid search mechanism. The feature is specifically designed for string value search. We have already evaluated the ability to enhance it with other types and rejected the idea. From this point of view, it makes no sense to expose a SearchString property in the Grid state, because it will be a "half-baked" "partial" feature that may allow developers to (try to) do things that we don't support officially.

That's why our example about searching for numeric/date/enum data in the Grid provides the best workaround that we can offer. The next best alternative is modifying our source code.

My primary recommendation is to resort to a custom SearchBox component in the Grid toolbar, as we have done. With regard to issue (2), the easiest solution is not execute SetStateAsync if newDescriptor is empty or the search string is invalid / incomplete.

Regards,
Dimo
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.