Home/Filter Control/Applying Filters
Filter Control

Applying Filters

Decide when a filter fires and where the filtering happens: as the user types or on an Apply button, against your server or against the rows already in the browser.

Filtering as you type

The filter row applies on every change. Type in First Name and watch one reload follow the pause, not each keystroke.

First Name
Department
Salary
Start Date

In filterMode: 'row' every filter is visible and every change applies straight away. Text filters wait 300 ms after the last keystroke before the grid reloads, so typing a word is one request, not eight.

Only text filters wait. Number, date and select filters apply the moment the value changes — there is nothing to finish typing. Try the Salary filter and the reload starts immediately.

Apply and Clear buttons

The same filters behind a funnel icon. Set an operator and a value, then press Apply — that is the only moment the grid reloads.

First Name
Department
Salary
Start Date

In filterMode: 'popup' the funnel icon opens an editor with the operator, the value and two buttons. Nothing is sent while the user is choosing. Press Apply and the grid reloads once; press Clear and the column's filter is removed.

Choose this when a filter costs the server real work, or when a user typically sets several conditions before caring about the result. Rename both buttons through config.filterLabels.

Filtering in the browser

Filter Department to Sales, then click a Department cell and change it. The row leaves the view immediately — no request.

First Name
Department
Salary
Start Date

With filterApplyMode: 'client' the grid filters the rows it has loaded instead of asking the server. Your data source is called once with empty filters and returns the full set.

Try it: filter Department to Sales, then click a Department cell in the result and change it to something else. The row leaves the view as soon as you commit — no request, no manual refresh. Edit it back and it returns. The same rule applies to rows added or removed while a filter is active.

Two limits worth knowing. It needs scrollMode: 'infinite' — paging and virtual paging fall back to server filtering and log a one-time warning. And it only ever filters what is loaded, so it suits datasets you are willing to hold in the browser.

Two questions, not one

"When does the filter apply" and "where does the filtering happen" are separate settings, and you can mix them freely.

  • config.filterMode — 'row' applies as the user types; 'popup' waits for Apply.
  • config.filterApplyMode — 'server' (the default) sends the filter to your data source; 'client' filters the loaded rows in the browser.

Every example here loads slowly on purpose

The demo data source waits before answering, so you can watch the loading state appear. That is the point of the comparison: with the filter row you see one load per keystroke pause, with the popup you see exactly one, when you press Apply.

Filter application options

PropertyTypeDefaultDescription
config.filterMode'row' | 'popup''row'Filter row applies immediately; popup waits for the Apply button.
config.filterApplyMode'server' | 'client''server'Send the filter to the data source, or filter loaded rows in the browser. Client mode needs scrollMode: 'infinite'.
filter.type'text' | 'number' | 'date' | 'select' | 'set'—Decides the delay in filterMode: 'row': text waits 300ms after the last keystroke, every other type applies at once.
config.filterLabels.applystring'Apply'Label of the popup button that commits the filter.
config.filterLabels.clearstring'Clear'Label of the popup button that removes the filter.
config.trackBystring—Row identity key. Required when edits and filters are both active so a committed row is matched by id.
(filterChange)FilterState—Fires after every applied change, in both modes.