Skip to content

Commit facfe59

Browse files
authored
kb(Grid): Add KB for filter operator persistence (#3140)
1 parent 92374ea commit facfe59

File tree

1 file changed

+169
-0
lines changed

1 file changed

+169
-0
lines changed
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
---
2+
title: Persist Grid Filter Operator After Value Clear
3+
description: Learn how to set the filter operator of a Grid column, so that it's not lost after clearing the filter value.
4+
type: how-to
5+
page_title: How to Persist Grid Filter Operator After Clearing the Value
6+
slug: grid-kb-persist-filter-operator
7+
tags: telerik, blazor, grid, filter
8+
ticketid: 1694386
9+
res_type: kb
10+
---
11+
12+
## Environment
13+
14+
<table>
15+
<tbody>
16+
<tr>
17+
<td>Product</td>
18+
<td>
19+
Grid for Blazor, <br />
20+
TreeList for Blazor
21+
</td>
22+
</tr>
23+
</tbody>
24+
</table>
25+
26+
## Description
27+
28+
This KB article answers the following questions:
29+
30+
* How to keep the same filter operator across multiple filter operations in a Grid column?
31+
* The set filter operator is lost when I clear the filter value. How to persist it?
32+
* How to maintain a non-default filter operator when the user removes the current filter value?
33+
34+
## Solution
35+
36+
The suggested approach below applies to both the Grid and the TreeList.
37+
38+
1. Subscribe to the [Grid `OnStateChanged` event](slug:grid-state#events).
39+
1. Check the [`PropertyName` value in the `OnStateChanged` event argument](slug:telerik.blazor.components.gridstateeventargs-1) to detect when the user is filtering.
40+
1. Save the currently applied filter operators for each filtered column to some custom collection.
41+
1. Compare the previously saved filters to the current ones. When the user removes the filter of a column, save the previous filter operator.
42+
1. Once the user filters by a column that has a saved filter operator, restore this operator.
43+
44+
>caption Persist Grid filter operator
45+
46+
````RAZOR
47+
@using Telerik.DataSource
48+
49+
<TelerikGrid Data="@GridData"
50+
TItem="@Product"
51+
FilterMode="GridFilterMode.FilterRow"
52+
Pageable="true"
53+
Sortable="true"
54+
OnStateChanged="@OnGridStateChanged">
55+
<GridColumns>
56+
<GridColumn Field="@nameof(Product.Name)" />
57+
<GridColumn Field="@nameof(Product.Group)" />
58+
<GridColumn Field="@nameof(Product.Price)" DisplayFormat="{0:c2}" />
59+
<GridColumn Field="@nameof(Product.Quantity)" DisplayFormat="{0:n0}" />
60+
<GridColumn Field="@nameof(Product.Released)" DisplayFormat="{0:d}" />
61+
<GridColumn Field="@nameof(Product.Discontinued)" />
62+
</GridColumns>
63+
</TelerikGrid>
64+
65+
@code {
66+
private List<Product> GridData { get; set; } = new();
67+
68+
private List<FilterDescriptor> SavedFilterDescriptors { get; set; } = new();
69+
private Dictionary<string, FilterOperator> ClearedFilterOperators { get; set; } = new();
70+
71+
private void OnGridStateChanged(GridStateEventArgs<Product> args)
72+
{
73+
// Check if the user has changed the filter configuration
74+
if (args.PropertyName == "FilterDescriptors")
75+
{
76+
IEnumerable<CompositeFilterDescriptor> currentFilters = args.GridState.FilterDescriptors.OfType<CompositeFilterDescriptor>();
77+
78+
// Iterate previously saved filters and compare to current ones
79+
foreach (FilterDescriptor savedOneColumnFd in SavedFilterDescriptors)
80+
{
81+
string savedMember = savedOneColumnFd.Member;
82+
object savedFilterValue = savedOneColumnFd.Value;
83+
FilterOperator savedOperator = savedOneColumnFd.Operator;
84+
85+
if (!string.IsNullOrEmpty(savedFilterValue?.ToString()))
86+
{
87+
// Search for current filters for the saved column
88+
FilterDescriptor? currentOneColumnFd = currentFilters
89+
.FirstOrDefault(x => x.FilterDescriptors.OfType<FilterDescriptor>().Any(y => y.Member == savedMember))?
90+
.FilterDescriptors.OfType<FilterDescriptor>().First();
91+
92+
// Check if filter for the current column no longer exists
93+
if (currentOneColumnFd is null)
94+
{
95+
// Save filter operator for future restore
96+
if (ClearedFilterOperators.ContainsKey(savedMember))
97+
{
98+
ClearedFilterOperators[savedMember] = savedOperator;
99+
}
100+
else
101+
{
102+
ClearedFilterOperators.Add(savedMember, savedOperator);
103+
}
104+
}
105+
}
106+
}
107+
108+
SavedFilterDescriptors.Clear();
109+
110+
// Iterate current filters
111+
foreach (CompositeFilterDescriptor currentOneColumnCfd in currentFilters)
112+
{
113+
IEnumerable<FilterDescriptor> currentOneColumnFds = currentOneColumnCfd.FilterDescriptors.OfType<FilterDescriptor>();
114+
115+
string currentMember = currentOneColumnFds.First().Member;
116+
FilterOperator currentOperator = currentOneColumnFds.First().Operator;
117+
object currentValuе = currentOneColumnFds.First().Value;
118+
119+
// Detect new filter value after clearing and restore previous operator
120+
if (ClearedFilterOperators.ContainsKey(currentMember))
121+
{
122+
currentOneColumnFds.First().Operator = currentOperator = ClearedFilterOperators[currentMember];
123+
ClearedFilterOperators.Remove(currentMember);
124+
}
125+
126+
// Save current filter state
127+
SavedFilterDescriptors.Add(new FilterDescriptor() { Member = currentMember, Operator = currentOperator, Value = currentValuе });
128+
}
129+
}
130+
}
131+
132+
protected override void OnInitialized()
133+
{
134+
var rnd = Random.Shared;
135+
136+
for (int i = 1; i <= 57; i++)
137+
{
138+
GridData.Add(new Product()
139+
{
140+
Id = i,
141+
Name = $"Name {i} {(char)rnd.Next(65, 91)}{(char)rnd.Next(65, 91)}",
142+
Group = $"Group {i % 3 + 1}",
143+
Price = rnd.Next(1, 100) * 1.23m,
144+
Quantity = rnd.Next(0, 10000),
145+
Released = DateTime.Today.AddDays(-rnd.Next(60, 1000)),
146+
Discontinued = i % 4 == 0
147+
});
148+
}
149+
}
150+
151+
public class Product
152+
{
153+
public int Id { get; set; }
154+
public string Name { get; set; } = string.Empty;
155+
public string Group { get; set; } = string.Empty;
156+
public decimal Price { get; set; }
157+
public int Quantity { get; set; }
158+
public DateTime Released { get; set; }
159+
public bool Discontinued { get; set; }
160+
}
161+
}
162+
````
163+
164+
## See Also
165+
166+
* [Grid State](slug:grid-state)
167+
* [Grid Filtering](slug:components/grid/filtering)
168+
* [TreeList State](slug:treelist-state)
169+
* [TreeList Filtering](slug:treelist-filtering)

0 commit comments

Comments
 (0)