

Dynamically Filtering the Kendo for Angular Grid From Code
source link: https://www.telerik.com/blogs/dynamically-filtering-kendo-angular-grid-code
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Dynamically Filtering the Kendo for Angular Grid From Code

While the Kendo UI for Angular Grid comes with built-in filtering functionality, sometimes you need to allow users to control what the filters show. We can do that too. Let’s take a look.
In an earlier post, I walked through the mechanics of filtering with the Data Grid from Progress Kendo UI for Angular. In that post, however, I focused on the Grid’s support for letting the user filter the rows in the grid and I only outlined the mechanics of integrating filtering with the rest of the application’s UI.
In this post, I’m going to look at a more realistic example how you can integrate filtering into an application so that, as the user interacts with the application’s UI, your code controls what rows the Grid displays.
My case study app is relatively simple: I have a Grid displaying a list of customers and dropdown list of countries. As the user selects a country from the dropdown list, my code will update the Grid to show only the customers in that country. To make
matters more interesting, I’ll also throw in a checkbox that lets the user select customers based on whether the customer is in the company’s loyalty program.
Here’s what the UI looks like:

Defining the UI
The Customer
class that this grid is showing has six properties. However, for this case study, I’m only interested in the country
and inLoyaltyProgram
properties:
export class Customer
{
constructor(
public id: number,
public country: string,
public inLoyaltyProgram: Boolean,
public custName: string,
public signUpDate: Date | null,
public amountPurchased: number
) { }
}
The markup to define the dropdown list and checkbox is going to look like this:
Select Country:
<kendo-dropdownlist
[data]="countries"
defaultItem=”Pick a Country”
(selectionChange)="CountryChange($event)">
</kendo-dropdownlist><br/><br/>
Loyalty Program Only:
<input type="checkbox" #loyalty kendoCheckBox
(change)="LoyaltyChange($event)"/>
Each of these components calls a function and passes the related event object when the user changes the component’s value. I’ll call these two functions (CountryChange
for the dropdown list and LoyaltyChange
for the
checkbox) my “filter functions.”
I also need two customer arrays. The first array is a “complete/unfiltered” array of customers (probably fetched from some Web service). I bind my Grid, however, to a second array, called selectCustomers
, which displays the currently
selected customers. Initially, I want both arrays to be the same, so I initialize the arrays like this:
public customers: Customer[];
public selectCustomers: Customer[] = [];
this.customers = [new Customer(1, "Peter Vogel", "USA", new Date(), 3250, true),
…more Customers…
];
this.selectCustomers = this.customers;
Finally, I define my Grid with the kendo-Grid
component and bind the Grid to the selectCustomers
list. I also define each column in the Grid so that I can bind each column to one of my company’s properties, control how
the data in the column is formatted, set the heading at the top of the column, and specify the column’s width.
All that Grid markup looks like this:
<kendo-Grid
[kendoGridBinding]="selectCustomers"
[height]="250"
(filterChange)= "this.filterCustomers($event)">
<kendo-Grid-column title="Id" field="id" [width]="50"></kendo-Grid-column>
<kendo-Grid-column title="Name" field="custName" [width]="150"></kendo-Grid-column>
<kendo-Grid-column title="Purchase" field="amountPurchased" [width]="125" format="99,999"></kendo-Grid-column>
<kendo-Grid-column title="Signed Up" field="signUpDate" [width]="200" format="MMM-dd-yyyy"></kendo-Grid-column>
<kendo-Grid-column title="In Program" field="inLoyaltyProgram" [width]="100"></kendo-Grid-column>
</kendo-Grid>
Filtering Infrastructure
To filter a Grid, I need a CompositeFilterDescriptor
that holds zero or more FilterDescriptors
(if the CompositeFilterDescriptor has no FilterDescriptors, then no rows are “filtered out”). I’ll need to import
those two classes and, since I’m also going to need the filterBy
function later on, I’ll import it too:
import { CompositeFilterDescriptor, FilterDescriptor, filterBy }
from "@progress/kendo-data-query";
A FilterDescriptor
has three properties that matter for this case study:
field
: Name of the property to filter onoperator
: The comparison operator to use (e.g., eq, neq, gt, etc.)value
: the value to compare
It makes sense to me to set up two FilterDescriptors—one for filtering by customer and one for filtering by loyalty program—as properties. This lets me set all the properties on each FilterDescriptor to some default values. This simplifies
my later code: As the user makes changes in the dropdown list and checkbox, the only property I have to change in my two filter functions is each FilterDescriptor’s value
property.
Use the Powerful Directive Composition API in Angular 15 with Kendo UI
Angular 15 has many new features, including the new directive composition API. Let’s see how to use it with Kendo UI for Angular.
Declaring those two FilterDescriptor properties looks like this:
countryFilter: FilterDescriptor = {field:"country", operator:"eq", value:"Pick a country"};
loyaltyFilter: FilterDescriptor = {field:"inLoyaltyProgram", operator:"eq", value:false};
Now, in my filter functions, I just retrieve the current value from the event passed to the function and set the value
property in the appropriate FilterDescriptor
. That’s pretty straightforward for the dropdown list because
the dropdown list’s selection event just passes the value currently selected in the dropdown:
CountryChange(e:string): void
{
this.countryFilter.value = e;
this.CreateFilter();
}
It’s a little more complicated for the checkbox because that function is passed an Event
object. However, I can cast that Event object’s target
property as an HtmlInput
object and then retrieve the element’s
checked
property to set the FieldDescriptor’s value
property:
LoyaltyChange(e:Event): void
{
const cbx = e.target as HTMLInputElement;
this.loyaltyFilter.value = cbx.checked;
this.CreateFilter();
}
The CreateFilter
function I’m calling at the end of each of these functions assembles the two FilterDescriptors into a CompositeFilter
and actually filters my data (you’ll see that function after the following short
interruption).
A UX Interruption
I’ve only given the user the ability to filter on whether the customer is in the loyalty program—the user can’t filter for customers not in the program. That’s because I used a checkbox in my user interface to control this filtering option.
While the Kendo UI Dropdown list has an “indeterminate” state that allows the checkbox to indicate that it hasn’t been touched yet, once the user checks the checkbox, the checkbox only alternates between true and false states. If I used false to filter the list to those customers not in the loyalty program then, once a user checks the checkbox, the user would be restricted to switching between using true to see those customers in the program and false to see those customers not in the program … but never all the customers.
If I wanted to let the user have the choice of three states for the loyalty program filter (in the loyalty program, not in the loyalty program, and “don’t care about the loyalty program”), I would have had to use some other combination of components (perhaps two radio buttons or another dropdown list).
I avoided this problem with the countries dropdown list by setting the dropdown list’s defaultItem
property to “Pick a Country.” If the user doesn’t change that default entry or returns to that default entry after
filtering on some country, I’ll go back to showing all the customers, regardless of country.
Back to the code.
Filtering the Customers
Now that I’ve built my FilterDescriptors, I combine them in my CreateFilter
method.
In that CreateFilter
function, I check for the four possible combinations of values in the two FilterConditions and use them to load the CompositeFilterDescriptor’s Filters
array:
- If the
LoyaltyFilter
is set tofalse
and theCustomerFilter
is set to the dropdown list’s default value, I don’t set any filters. - If the
LoyaltyFilter
is set totrue
andCustomerFilter
to some country (i.e., not the default value), I load both filters. - For any other combination, I load only the filter that has its value set.
When you do have multiple items in the Filters
condition, you must set the CompositeFilterDescriptor’s logic
property to “and” or “or” to indicate how the filters are to be combined. When I do use
both filters, I want them to be “and”ed together so, in my CompositeFilterDescriptor, I’ve set the logic property to “and.”
Where these is only one (or no) filter, it doesn’t matter what the logic property is set to—having the property set to “and” is just fine. That means (lucky me!) that I never have to change the logic property: I either want the filters “and”ed together or I don’t care.
Here’s the code that builds my ComponsiteFilterDescriptor
(there are probably more sophisticated ways of doing this, but this version has the advantage of being obvious):
GridFilter:CompositeFilterDescriptor = {filters:[],logic:"and"};
CreateFilter()
{
if (!this.loyaltyFilter.value && this.countryFilter.value == "Pick a country")
{
this.GridFilter.filters = [];
}
if (!this.loyaltyFilter.value && this.countryFilter.value != "Pick a country")
{
this.GridFilter.filters = [this.countryFilter];
}
if (this.loyaltyFilter.value && this.countryFilter.value == "Pick a country")
{
this.GridFilter.filters = [this.loyaltyFilter];
}
if (this.loyaltyFilter.value && this.countryFilter.value != "Pick a country")
{
this.GridFilter.filters = [this.loyaltyFilter, this.countryFilter];
}
At the end of my CreateFilter
function, I can finally filter my complete array of customers into the selectCustomers
array that my Grid is bound to. To do that, I use the filterBy
function I imported earlier, passing
the complete customers
array and my CompositeFilterDescriptor
. The code that uses the result of calling filterBy
to set the array my Grid is bound to looks like this:
…
{
this.GridFilter.filters = [this.loyaltyFilter, this.countryFilter];
}
this.selectCustomers = filterBy(this.customers, this.GridFilter);
}
Now, as the user interacts with the other parts of my application’s UI, my code is in control of what rows the Grid displays. And, I have to admit, while the Grid’s built-in filtering functionality is great, I do like to be in control.
Recommend
-
60
Whether you have just started usingKendo UIor are already pretty proficient with our widgets and main concepts, you know as well as I do, as does anyone in our industry - things change. Every. Time. You. Blink.
-
5
Raymond Camden
-
24
FeaturesAngular Scheduler component with support for row filtering from DayPilot Pro for JavaScriptReal-time filtering by row nameAllow...
-
78
Sorting, Filtering and Grouping With KendoReact GridFiltering, Sorting and Grouping are three important tools you can give your users to help them parse the data presented in a KendoReact Data Grid. Learn how to implement these configurations...
-
4
FeaturesAngular Scheduler component with resources on the Y (vertical) axis and time on the X (horizontal) axisInstant event filtering: by text, catego...
-
7
Kendo Grid: A Primer For First-Time Users This is my take on working with Kendo Grid in a Vue 3 project. While I have not explored the grid functionality to the nth degree, these are some things I like about the grid, some difficulties I had...
-
8
Kendo UI Grid控件的功能强大,这里将常用的一些功能总结一下。 Kendo UI Grid 固定列 在使用Gird控件显示数据时,如果数据列过多,会出现横向滚动条,很多情况下,我们希望某些列固定,这些列固定显示,不随滚动条发生变化。这时,可以在数据...
-
11
Kendo UI For Angular Data Grid And Angular Material: Have Your Cake And Eat It TooQuick summary ↬ Although Angular Material is one of the most popular component libraries which al...
-
7
Server-Side Filtering with the Kendo Angular for UI Grid
-
6
Customizing Filtering in the Telerik UI for ASP.NET MVC Grid
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK