Skip to content

Filter Expressions

The Pro advanced filter can expose an optional expression editor inside each filter popup. It is disabled by default. When enabled, the popup adds an Expression button and expandable editor panel at the bottom, after the regular filter controls. Users can type current-column filter logic as text; valid expressions apply live and compile into the grid’s standard multiFilterItems model.

import { AdvanceFilterPlugin } from '@revolist/revogrid-pro';
const grid = document.createElement('revo-grid');
grid.plugins = [AdvanceFilterPlugin];
grid.columns = [
{ prop: 'status', name: 'Status', filter: ['string', 'selection'] },
{ prop: 'score', name: 'Score', filter: ['number', 'slider'] },
{ prop: 'updated', name: 'Updated', filter: ['date'] },
];
grid.filter = {
expressions: {
enabled: true,
applyDebounceMs: 300,
buttonLabel: 'Expression',
placeholder: 'between 10 and 50\ncontains "north" AND not empty',
},
};

Expressions are scoped to the column whose filter popup is open. You can omit the column name:

between 2024-01-01 and 2024-12-31 AND after 2024-06-01

You can also include the current column prop or name for readability:

updated between 2024-01-01 and 2024-12-31 AND updated after 2024-06-01

References to another column are invalid and do not change active filters.

For application-defined cross-column OR, nested groups, and NOT, use the public Canonical Filter AST. The popup editor remains deliberately scoped to its current column.

Expressions evaluate the current column’s parsed value when cellParser is defined, just like ordinary comparisons. Blank expression operators use the raw source value and property-presence context from Core. See Blank Values for the source-preserving contract.

Use AND, OR, and parentheses to group expressions:

(contains "north" OR contains "west") AND not empty

String columns support:

empty
not empty
= "Active"
!= "Archived"
begins "A"
contains "north"
not contains "draft"

Array columns support strict, valueless length checks:

empty array
not empty array
is empty array
is not empty array

Number and slider columns support:

> 10
>= 25
< 100
<= 500
between 250 and 640.42

Date columns support:

equals 2024-06-01
before 2024-12-31
after 2024-01-01
on or before 2024-12-31
on or after 2024-01-01
not equal 2024-07-04
between 2024-01-01 and 2024-12-31
today
yesterday
last 7 days
this month
last month
this quarter
next quarter
previous quarter
this year
next year
previous year

Selection-style text supports:

is "Open"
in ("Open", "Pending")
not in ("Closed", "Archived")

Registered structured filters use the same lossless mirror without exposing their transport JSON. Objects, arrays, strings, numbers, booleans, and blank values remain typed:

structured "arrayTagsMatch" {
mode: "none",
values: ["renewal", "priority"],
emptyOnly: false,
exact: false
}

The editor highlights keywords, operators, properties, strings, numbers, booleans, and invalid tokens. The grouped filter’s Text view uses the same token presentation; when a structured filter provides describeCondition, that filter-owned readable description replaces its transport value. Legacy saved expressions containing a quoted JSON payload remain accepted.

The editor validates while users type. Valid expressions apply after applyDebounceMs; invalid expressions show diagnostics and keep the previous valid filters unchanged. Press Ctrl+Enter or Cmd+Enter to apply immediately.

The expression panel does not replace the normal popup content. Selection lists, slider controls, date inputs, and condition controls remain visible while the expression panel is expanded.

Expression filters are stored as hidden Pro filter items, so reset, active header state, filter events, and server-side filter payload handling continue to use the standard multiFilterItems flow.

Expression labels use the existing filter localization path:

grid.filter = {
expressions: true,
localization: {
captions: {
expressionButton: 'Expression',
expressionTitle: 'Filter expression',
expressionPlaceholder: 'contains "north"',
expressionApply: 'Apply',
expressionInvalid: 'Invalid expression',
},
},
};