Expression Filters
Learn how to create complex filter logic using LyteNyte Grid's expression capabilities.
Note
This guide assumes familiarity with LyteNyte Grid expressions and filtering concepts. The demos in this guide use the client row source to demonstrate expression filters.
For background, review the Client Row Filtering and Expressions Overview guide.
Creating Expression Filters
An expression filter returns a boolean value. LyteNyte Grid evaluates this expression
against each row and keeps the row only if the result is true.
To make filter expressions easier to read and write, use column names rather
than column IDs. For example, a user writes Gender == "Male" instead
of row.customerGender == "Male".
Two mechanisms support this mapping:
createResolvedIdentifierPlugin: Intercepts identifier nodes in the AST and rewrites them as function calls. This ensuresGenderresolves from the context at evaluation time instead of being treated as a plain key.- Context Object: Maps each column display name to a function that reads the column value
from the current row using
computeField.
The demo below preloads the expression Gender == "Male" && Quantity > 10.
Type an expression to update the filter, or select one of the provided examples.
The demo includes the complete expression filter implementation. With only a few lines of code, expression filters let users create advanced filtering logic concisely.
Evaluator Setup
Start by creating an Evaluator instance. Instantiate the Evaluator either outside
your React component or inside a useMemo hook to maintain a stable reference.
Use standardPlugins and createResolvedIdentifierPlugin to enable advanced
expression capabilities:
import { createResolvedIdentifierPlugin, Evaluator, standardPlugins,} from "@1771technologies/lytenyte-pro/expressions";
const evaluator = new Evaluator( standardPlugins.concat([ createResolvedIdentifierPlugin({ identifiers: columns.map((x) => x.name ?? x.id), args: ["row"], }), ]),);Building the Filter Function
You can filter rows in LyteNyte Grid by passing a filter function. To implement an expression as a filter function, follow these steps:
-
Create a context object that maps column names to functions that return the column value for a given row:
import { computeField } from "@1771technologies/lytenyte-pro";import type { RowLeaf } from "@1771technologies/lytenyte-pro/types";const columnsContext = useMemo(() =>Object.fromEntries(columns.map((col) => [col.name ?? col.id, (row: RowLeaf) => computeField(col.field ?? col.id, row)]),),[],); -
Pre-parse the expression into an AST to avoid tokenizing it on every predicate evaluation. Set
undefinedIdentifierFallbacktotrueto ensure partially typed expressions returntruerather than throwing an error:const filter = useMemo(() => {if (!committed) return null;try {const ast = evaluator.ast(committed);return (row: RowLeaf<GridSpec["data"]>) =>!!evaluator.run(ast, { row, ...columnsContext }, { undefinedIdentifierFallback: true });} catch {return null; // invalid expression, show all rows}}, [committed, columnsContext]); -
Pass the filter function to
useClientDataSource:const ds = useClientDataSource<GridSpec>({ data, filter });
Completion Provider Wiring
Pass a completion provider to ExpressionEditor.Root to enable autocomplete for column names.
Use createCompletionProvider to create the default provider. Provide a Record<displayName, id> map
so the provider does not require access to the full context object:
const provider = useMemo( () => createCompletionProvider(Object.fromEntries(columns.map((col) => [col.name ?? col.id, col.id]))), [],);Server-Side Expression Filters
The Evaluator can compute expression values on the client when all data referenced by
the expression is available locally. If your data is stored on the server,
serialize the expression AST and evaluate it server-side instead:
const ast = evaluator.ast(committed);const serialized = JSON.stringify(ast); // send in your DataRequestThe AST is fully serializable as long as your plugins do not introduce custom node types that
cannot be converted to JSON. standardPlugins and createResolvedIdentifierPlugin produce only
serializable nodes.
Next Steps
- Expression Fields: Compute cell values from user-defined expressions.
- Expressions Overview: Learn how to build domain-specific expressions.
- Expression Plugins: Extend expression capabilities with custom plugins.
- Client Row Filtering: Explore how to filter rows when using the client row source.
