Skip to content

What Is a Filter AST?

A Filter AST is a portable description of a filter. It records what the filter means as data, without tying that meaning to one filter popup, framework, database, or API.

You do not need compiler knowledge to use it. If you can read a sentence such as “show open, high-priority tickets or any ticket from a VIP customer,” you already understand the idea.

AST stands for Abstract Syntax Tree:

  • Abstract means it keeps the meaning and leaves out presentation details such as buttons, labels, and popup layout.
  • Syntax means it follows a small set of structural rules.
  • Tree means a rule can contain smaller rules, like branches containing more branches and leaves.

In a RevoGrid Filter AST, the leaves are field conditions and the branches join them with and, or, or not.

Consider this business rule:

Show a ticket when it is both open and high priority, or when the customer is a VIP.

Its tree reads like this:

OR
├─ AND
│ ├─ status equals "Open"
│ └─ priority is at least 3
└─ customerTier equals "VIP"

The same rule as a RevoGrid FilterAst is ordinary JSON-shaped data:

import type { FilterAst } from '@revolist/revogrid-pro';
const ticketQueue: FilterAst = {
type: 'group',
operator: 'or',
children: [
{
type: 'group',
operator: 'and',
children: [
{
type: 'condition',
field: 'status',
operator: 'equal',
valueType: 'string',
value: 'Open',
},
{
type: 'condition',
field: 'priority',
operator: 'greaterThanOrEqual',
valueType: 'number',
value: 3,
},
],
},
{
type: 'condition',
field: 'customerTier',
operator: 'equal',
valueType: 'string',
value: 'VIP',
},
],
};

The AST describes the question. It does not contain the rows, the matching results, or database-specific instructions.

Applications often create filters in several places: column menus, a visual rule builder, quick search, saved views, and backend APIs. Without a shared format, each feature can describe the same rule differently.

RevoGrid’s canonical FilterAst is the common contract between those paths. It is:

  • Meaningful: nested Boolean logic is explicit rather than implied by UI state.
  • JSON-safe: it can be serialized, stored, logged, and sent in a request.
  • Validated: malformed trees are rejected before they replace the active filter.
  • Portable: the same tree can drive local rows or be interpreted by your backend.
  • UI-independent: a filter can survive a redesign or move between different applications.

“Canonical” does not mean RevoGrid automatically converts the tree to SQL, REST parameters, or GraphQL. Your backend owns that translation and must allow-list fields and operators before building a query.

Filter AST becomes valuable when a filter is more than a temporary choice in one column menu.

NeedBusiness outcome
Saved views and reusable segmentsUsers can return to the same definition instead of rebuilding it.
Shared rules across screensA queue, dashboard, and export can use one filter contract.
Remote or virtual dataThe backend can evaluate the complete dataset instead of only the loaded page.
Cross-column OR, nested groups, and NOTBusiness rules are represented without flattening or changing their meaning.
Visual and programmatic editingA person can use the grouped editor while an application can generate the same structure.
Validation and diagnosticsInvalid saved or generated rules fail as one atomic update, leaving the previous view active.
Auditing and troubleshootingA JSON filter is easier to inspect, compare, version, and log than transient UI state.

Typical examples include support queues, approval routing, fraud-review segments, inventory alerts, compliance views, and report definitions.

Use FilterAst when at least one of these is true:

  • The rule needs OR across different fields, nested groups, or NOT.
  • Users save, share, or reopen complex views.
  • Filtering is executed by a remote data service.
  • A visual rule builder and application code must exchange the same filter.
  • You need a stable, JSON-safe filtering contract.

Use ordinary multiFilterItems instead when users only filter individual columns and all columns combine with AND. It is simpler and works with existing Core column controls. FilterAst is a Pro capability and requires AdvanceFilterPlugin for canonical execution.

Every tree is made from only three node types:

NodeWhat it saysEveryday example
conditionTest one field with one operator.Status equals Open.
groupJoin one or more child rules with and or or.Open and high priority.
notReverse the result of one child rule or group.Not archived.

A condition names the row field, operator, and operand type:

const condition: FilterAst = {
type: 'condition',
field: 'amount',
operator: 'greaterThanOrEqual',
valueType: 'number',
value: 1000,
};

valueType describes the operand; it does not convert the values in your rows. For example, valueType: 'number' expects a real number rather than the string '1000'.

Register AdvanceFilterPlugin, get its runtime instance, and apply the complete tree:

import { AdvanceFilterPlugin } from '@revolist/revogrid-pro';
import '@revolist/revogrid-pro/dist/revogrid-pro.css';
grid.plugins = [AdvanceFilterPlugin];
grid.columns = columns;
grid.source = rows;
const filterPlugin = (await grid.getPlugins()).find(
(plugin) => plugin instanceof AdvanceFilterPlugin,
) as AdvanceFilterPlugin;
await filterPlugin.setFilterAst(ticketQueue);

Read the effective filter when you need to save or send it:

const currentFilter = filterPlugin.getFilterAst();
if (currentFilter) {
localStorage.setItem('ticket-queue', JSON.stringify(currentFilter));
}

Restore the saved tree by parsing it and applying it again:

const savedFilter = localStorage.getItem('ticket-queue');
if (savedFilter) {
await filterPlugin.setFilterAst(JSON.parse(savedFilter));
}

Clear it with undefined:

await filterPlugin.setFilterAst(undefined);

setFilterAst() replaces the tree as one atomic operation. getFilterAst() returns a defensive copy, so changing that returned object does not change the grid. Build the next tree and call setFilterAst() again.

The AST is the data model, not a required user interface. A familiar filter rail, active chips, search field, ranges, and toggles can all compile into the same tree. This lets people filter in business language while the application gets a validated, portable definition.

Open the Filter AST Side Panel article. It mounts the same canonical grouped editor used by the filter dialog and exposes Vanilla TypeScript, Vue, React, Angular, shared grid setup, and styling sources.

Each interaction in the example rebuilds and applies the complete AST. Removing a chip removes its branch; Clear all applies undefined. The side panel owns presentation, while AdvanceFilterPlugin owns validation and execution.

For unrestricted rule creation, enable the grouped editor so users can create nested rules without writing JSON:

grid.filter = {
groupedFilter: {},
};

The editor and the API work with the same canonical tree. A user can create a rule visually, your application can read it with getFilterAst(), and the saved result can be restored later with setFilterAst().

Listen for filterastchange to receive the effective AST and its execution context. The context fixes time-sensitive details such as the instant and timezone used for relative date rules.

For a remote data source, cancel local application in beforefilterapply, send the AST and execution context to your service, and replace the grid rows with the server result. The backend must evaluate the rule against the full dataset, not only the page loaded in the browser.

The Canonical Filter AST reference has the complete event example, remote-preview flow, operator table, value rules, and diagnostics.

  1. Start with multiFilterItems unless the product needs canonical or nested logic.
  2. Treat the AST as untrusted input when it comes from storage, a URL, or another service.
  3. Apply it through setFilterAst() so RevoGrid validates it atomically.
  4. Store or transport the tree returned by getFilterAst().
  5. Send executionContext with remote requests, especially for relative dates and blank-value policy.
  6. On the server, allow-list fields and operators and use parameterized database queries.
  7. Test the same saved rule locally and remotely to confirm that both sides return the same rows.

No. It is structured data. A string such as status = "Open" AND priority >= 3 can be convenient for people, but an AST makes the grouping and types explicit for software.

No. Simple column filtering remains the easiest choice for ordinary grid interactions. The AST is the shared model for cases that need richer logic, persistence, or transport.

Yes, if the surrounding storage or URL encoding is suitable for your size and security requirements. The AST is JSON-safe, but you should still validate restored state and avoid treating client-provided fields or operators as trusted database instructions.

Some ASTs can be shown again as independent column filters; those are projectable. A cross-column OR or NOT cannot be represented faithfully by ordinary column controls, so it is canonical-only. It is still a valid filter and can be edited in the grouped editor.

Continue to Canonical Filter AST for every supported operator, exact value shapes, quick-filter composition, events, remote ownership, validation codes, and custom evaluators. See Filter State and Presets for persistence patterns and Filtering Quick Start for simpler column filtering.