Filtering
Filter data with operators, SQL-like queries, and export filters to REST, GraphQL, or SQL.
ZenGrid provides a comprehensive filtering system with support for multiple operators, SQL-like queries, and the ability to export filters to various backend formats. Internally, all filter inputs are normalized into a typed filter AST.
Filter Operators
ZenGrid supports a wide range of filter operators:
- equals: Exact match
- notEquals: Not equal to value
- contains: Contains substring
- notContains: Does not contain substring
- startsWith: Starts with value
- endsWith: Ends with value
- greaterThan: Greater than value
- lessThan: Less than value
- greaterThanOrEqual: Greater than or equal to value
- lessThanOrEqual: Less than or equal to value
- blank: Is empty or null
- notBlank: Has a value
- between: Value is between two bounds
- in: Value is in a list
- notIn: Value is not in a list
- regex: Matches regular expression
Basic Filtering
// Apply a simple filtergrid.setFilter('name', 'contains', 'John');
// Clear a column filtergrid.clearColumnFilter('name');
// Clear all filtersgrid.clearFilters();Advanced Column Filters
Apply multiple conditions to a single column:
// Age between 25 and 40grid.setColumnFilter('age', [ { operator: 'greaterThanOrEqual', value: 25 }, { operator: 'lessThanOrEqual', value: 40 }], 'and'); // 'and' | 'or'
// Email ends with specific domainsgrid.setColumnFilter('email', [ { operator: 'endsWith', value: '@company.com' }, { operator: 'endsWith', value: '@partner.com' }], 'or');When using multiple conditions, specify the logic operator: 'and' requires all conditions to match, while 'or' requires at least one to match.
Quick Filter
Search across multiple columns with a single query:
// Search all columnsgrid.setQuickFilter('John');
// Search specific columnsgrid.setQuickFilter('John', ['name', 'email', 'address']);
// Clear quick filtergrid.setQuickFilter('');Quick filter is ideal for implementing a global search box that searches across all visible columns.
SQL-Like Queries
Use SQL-like syntax for complex filtering:
const filterQuery = { sql: 'age > ? AND (status = ? OR status = ?)', params: [25, 'active', 'pending']};
// Apply the SQL-like filtergrid.applyFilterQuery(filterQuery);SQL-like input is parsed into filter.ast, which is the canonical filter contract used by frontend and backend integrations. models, fieldState, and getFilterExports() are derived from that AST when the current filter can be projected into those formats.
Filter Export
Export your filters to various backend query formats:
// Get filter exportsconst exports = grid.getFilterExports();
// REST API formatconsole.log(exports.rest);// { name: { contains: 'John' }, age: { gte: 25, lte: 40 } }
// GraphQL formatconsole.log(exports.graphql);// { where: { name: { contains: "John" }, age: { gte: 25, lte: 40 } } }
// SQL formatconsole.log(exports.sql);// {// query: "name LIKE ? AND age >= ? AND age <= ?",// params: ["%John%", 25, 40]// }Filter Export Adapters
ZenGrid includes three built-in export adapters:
- REST Adapter: Exports to REST API query parameters
- GraphQL Adapter: Exports to GraphQL where clauses
- SQL Adapter: Exports to SQL WHERE clauses with parameterized queries
import { RestAdapter, GraphQLAdapter, SQLAdapter } from '@zengrid/core';
// Use adapters directlyconst restAdapter = new RestAdapter();const restQuery = restAdapter.export(grid.getFilterState());
const graphqlAdapter = new GraphQLAdapter();const graphqlQuery = graphqlAdapter.export(grid.getFilterState());
const sqlAdapter = new SQLAdapter();const sqlQuery = sqlAdapter.export(grid.getFilterState());Filter exports are intended for backend integration. Always validate and sanitize filter parameters on the server side to prevent injection attacks.
Filter Performance
ZenGrid optimizes filter performance through:
- Filter Caching: Results are cached until data or filters change
- Index Management: Maintains indices for fast lookups
- Range Optimization: Optimized handling of range filters
const grid = new ZenGrid(container, { filterCaching: true, // Enable filter result caching filterIndexing: true, // Enable filter index management rangeFilterOptimization: true});Events
Listen to filter changes:
grid.on('filter:beforeFilter', (event) => { console.log('About to filter:', event.filterState); // Return false to cancel filtering});
grid.on('filter:change', (event) => { console.log('Filter changed:', event.filterState); console.log('Visible rows:', event.visibleRowCount);});
grid.on('filter:afterFilter', (event) => { console.log('Filter applied:', event.filterState);});
grid.on('filter:export', (event) => { console.log('Filter exported:', event.format, event.query);});Example: Complex Filtering Scenario
const grid = new ZenGrid(container, { columns: [ { id: 'name', field: 'name', filterable: true }, { id: 'age', field: 'age', filterable: true }, { id: 'status', field: 'status', filterable: true }, { id: 'email', field: 'email', filterable: true } ]});
// Apply multiple filtersgrid.setFilter('status', 'in', ['active', 'pending']);grid.setColumnFilter('age', [ { operator: 'greaterThanOrEqual', value: 21 }, { operator: 'lessThan', value: 65 }], 'and');grid.setFilter('name', 'notBlank');
// Get current filter stateconst filterState = grid.getFilterState();
// Export for backendconst sqlExport = grid.getFilterExports().sql;// Send to backendawait fetch('/api/filtered-data', { method: 'POST', body: JSON.stringify(sqlExport)});Substring Optimization
For substring filters (contains, startsWith, endsWith), ZenGrid uses optimized algorithms:
// Efficient substring searchinggrid.setFilter('description', 'contains', 'important');
// Case-insensitive by defaultgrid.setFilter('name', 'contains', 'john', { caseSensitive: false });For best performance with large datasets, consider using backend filtering mode and creating appropriate database indices.