Skip to content

Commit 0d58130

Browse files
docs(grid): default filters in the state (#239)
1 parent 869ace5 commit 0d58130

File tree

3 files changed

+238
-0
lines changed

3 files changed

+238
-0
lines changed

_contentTemplates/grid/state.md

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,240 @@
177177
#end
178178

179179

180+
#filter-menu-default-filters
181+
>note There are default filters in the grid state for each column. This allows filter menu templates to work seamlessly and with little code. This, however, means that if you want to alter filters for a column, you must either modify the existing one, or remove it. Simply adding a filter will not show up in the UI because the grid will use the first filter for the given field it finds for the filtering UI.
182+
183+
>caption Handling filter changes - unexpected addition that does not update the UI, replacement of one filter, replacecment of all filters
184+
185+
````Component
186+
@using Telerik.DataSource
187+
188+
To see the full effects of this behavior, filter a column such as the ID being less than or equal to 4.
189+
<br /> Then, click a button to see the different behavior each will have:
190+
<ul>
191+
<li>
192+
the first button will not show the new filter in the Team column header
193+
<TelerikButton OnClick="@WrongFilterAdd">Add filter without replace - you will not see the change in the filter UI but the data will change</TelerikButton>
194+
</li>
195+
<li>
196+
the second button will keep the ID column filter and add the Team filter
197+
<TelerikButton OnClick="@SetFilterWithReplaceInCollection">Replace only Team filter</TelerikButton>
198+
</li>
199+
<li>
200+
the third button will remove all filters and set only the custom Team filter
201+
<TelerikButton OnClick="@SetFilterNewCollection">Replace all filters to filter by Team</TelerikButton>
202+
</li>
203+
</ul>
204+
205+
This flexibility lets you choose what behavior you want from the grid.
206+
207+
208+
209+
<TelerikGrid Data="@MyData" Height="400px" @ref="@Grid"
210+
Pageable="true" Sortable="true"
211+
FilterMode="@GridFilterMode.FilterMenu">
212+
<GridColumns>
213+
<GridColumn Field="@(nameof(SampleData.Id))" Width="120px" />
214+
<GridColumn Field="@(nameof(SampleData.Name))" Title="Employee Name" />
215+
<GridColumn Field="@(nameof(SampleData.Team))" Title="Team" />
216+
<GridColumn Field="@(nameof(SampleData.HireDate))" Title="Hire Date" />
217+
</GridColumns>
218+
</TelerikGrid>
219+
220+
221+
222+
@code{
223+
// adds a filter without affecting the UI
224+
async Task WrongFilterAdd()
225+
{
226+
// get state
227+
var state = Grid.GetState();
228+
229+
// simply add a filter to the existing state and existing (default) filters
230+
// PROBLEM - YOU WILL NOT SEE IT HIHGLIGHT THE UI BECAUSE THERE IS A DEFAULT FILTER ALREADY
231+
232+
state.FilterDescriptors.Add(new CompositeFilterDescriptor()
233+
{
234+
FilterDescriptors = new FilterDescriptorCollection()
235+
{
236+
new FilterDescriptor
237+
{
238+
Member = "Team",
239+
Operator = FilterOperator.IsEqualTo,
240+
Value = "team 1",
241+
MemberType = typeof(string)
242+
},
243+
new FilterDescriptor()
244+
{
245+
Member = "Team",
246+
Operator = FilterOperator.IsEqualTo,
247+
Value = null,
248+
MemberType = typeof(string)
249+
}
250+
},
251+
LogicalOperator = FilterCompositionLogicalOperator.Or
252+
});
253+
254+
// set state
255+
await Grid.SetState(state);
256+
}
257+
258+
// adds a filter
259+
async Task SetFilterWithReplaceInCollection()
260+
{
261+
// get the current state
262+
var state = Grid.GetState();
263+
264+
// remove the current filters for the Team field
265+
// if you don't do this, the default or exiting fitlers will command the UI
266+
// and you may not see the change from the new filter you will add
267+
// see the extension methods related to GetFiltersForMember in the adjacent code tab
268+
// create a new collection so we can iterate over it without it getting lost with the removal from the parent collection
269+
List<IFilterDescriptor> teamFilters = new List<IFilterDescriptor>(state.FilterDescriptors.GetFiltersForMember("Team"));
270+
271+
// remove the existing filters for the Team field from the current collection
272+
for (int i = 0; i < teamFilters.Count(); i++)
273+
{
274+
state.FilterDescriptors.Remove(teamFilters.ElementAt(i) as FilterDescriptorBase);
275+
}
276+
277+
// create the desired new filter for the Team field
278+
CompositeFilterDescriptor theFilterDescriptor = new CompositeFilterDescriptor()
279+
{
280+
FilterDescriptors = new FilterDescriptorCollection()
281+
{
282+
new FilterDescriptor
283+
{
284+
Member = "Team",
285+
Operator = FilterOperator.IsEqualTo,
286+
Value = "team 2",
287+
MemberType = typeof(string)
288+
},
289+
new FilterDescriptor()
290+
{
291+
Member = "Team",
292+
Operator = FilterOperator.IsEqualTo,
293+
Value = null,
294+
MemberType = typeof(string)
295+
}
296+
},
297+
LogicalOperator = FilterCompositionLogicalOperator.Or
298+
};
299+
300+
// add the new filter so that it replaces the original filter(s)
301+
state.FilterDescriptors.Add(theFilterDescriptor);
302+
303+
// set the updated state
304+
await Grid.SetState(state);
305+
}
306+
307+
// replaces all filters
308+
async Task SetFilterNewCollection()
309+
{
310+
// get the current state
311+
var state = Grid.GetState();
312+
313+
//replace the entire filters collection so it only has the new desired filter
314+
state.FilterDescriptors = new List<FilterDescriptorBase>()
315+
{
316+
new CompositeFilterDescriptor()
317+
{
318+
FilterDescriptors = new FilterDescriptorCollection()
319+
{
320+
new FilterDescriptor()
321+
{
322+
Member = "Team",
323+
Operator = FilterOperator.Contains,
324+
Value = "3",
325+
MemberType = typeof(string)
326+
},
327+
new FilterDescriptor()
328+
{
329+
Member = "Team",
330+
Operator = FilterOperator.IsEqualTo,
331+
Value = null,
332+
MemberType = typeof(string)
333+
}
334+
},
335+
LogicalOperator = FilterCompositionLogicalOperator.Or
336+
}
337+
};
338+
339+
// set the new state
340+
await Grid.SetState(state);
341+
}
342+
}
343+
344+
@code {
345+
TelerikGrid<SampleData> Grid { get; set; }
346+
347+
public IEnumerable<SampleData> MyData = Enumerable.Range(1, 30).Select(x => new SampleData
348+
{
349+
Id = x,
350+
Name = "name " + x,
351+
Team = "Team " + x % 5,
352+
HireDate = DateTime.Now.AddDays(-x).Date
353+
});
354+
355+
public class SampleData
356+
{
357+
public int Id { get; set; }
358+
public string Name { get; set; }
359+
public string Team { get; set; }
360+
public DateTime HireDate { get; set; }
361+
}
362+
}
363+
````
364+
````Extensions
365+
using Telerik.DataSource;
366+
367+
//make sure the namespace matches your page, or add an appropriate using
368+
369+
public static class FilterExtensions
370+
{
371+
public static IEnumerable<CompositeFilterDescriptor> GetCompositeFiltersForMember(this IEnumerable<IFilterDescriptor> filtersCollection, string member)
372+
{
373+
var compositeFilters = filtersCollection.OfType<CompositeFilterDescriptor>();
374+
return compositeFilters.GetFiltersForMember(member).Cast<CompositeFilterDescriptor>();
375+
}
376+
377+
public static IEnumerable<IFilterDescriptor> GetAllFiltersForMember(this IEnumerable<IFilterDescriptor> filtersCollection, string member)
378+
{
379+
return filtersCollection.SelectMemberDescriptors().GetFiltersForMember(member);
380+
}
381+
382+
public static IEnumerable<IFilterDescriptor> GetFiltersForMember(this IEnumerable<IFilterDescriptor> filtersCollection, string member)
383+
{
384+
return filtersCollection.Where(filter => filter.GetFilterMember() == member) ??
385+
Enumerable.Empty<IFilterDescriptor>();
386+
}
387+
388+
public static string GetFilterMember(this IFilterDescriptor filter)
389+
{
390+
var filterDescriptor = filter;
391+
var isFilterDescriptor = filterDescriptor is FilterDescriptor;
392+
393+
while (!isFilterDescriptor)
394+
{
395+
var compositeDescriptor = filterDescriptor as CompositeFilterDescriptor;
396+
397+
if (compositeDescriptor == null)
398+
{
399+
break;
400+
}
401+
402+
filterDescriptor = compositeDescriptor.FilterDescriptors?.ElementAtOrDefault(0);
403+
isFilterDescriptor = filterDescriptor is FilterDescriptor;
404+
}
405+
406+
return ((FilterDescriptor)filterDescriptor)?.Member;
407+
}
408+
}
409+
````
410+
#end
411+
412+
413+
180414

181415
#group-from-code
182416
@using Telerik.DataSource;

components/grid/filter/filter-menu.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ You can set the grid filters from your code through the grid [state]({%slug grid
8181
@[template](/_contentTemplates/grid/state.md#filter-menu-from-code)
8282
````
8383

84+
@[template](/_contentTemplates/grid/state.md#filter-menu-default-filters)
8485

8586

8687
## See Also

components/grid/state.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,9 @@ The grid state allows you to control the behavior of the grid programmatically -
395395
@[template](/_contentTemplates/grid/state.md#expand-hierarchy-from-code)
396396
````
397397

398+
@[template](/_contentTemplates/grid/state.md#filter-menu-default-filters)
399+
400+
398401
### Set Default (Initial) State
399402

400403
If you want the grid to start with certain settings for your end users, you can pre-define them in the `OnStateInit event`.

0 commit comments

Comments
 (0)