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.

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

basic-filter.js
// Apply a simple filter
grid.setFilter('name', 'contains', 'John');
// Clear a column filter
grid.clearColumnFilter('name');
// Clear all filters
grid.clearFilters();

Advanced Column Filters

Apply multiple conditions to a single column:

multi-condition-filter.js
// Age between 25 and 40
grid.setColumnFilter('age', [
{ operator: 'greaterThanOrEqual', value: 25 },
{ operator: 'lessThanOrEqual', value: 40 }
], 'and'); // 'and' | 'or'
// Email ends with specific domains
grid.setColumnFilter('email', [
{ operator: 'endsWith', value: '@company.com' },
{ operator: 'endsWith', value: '@partner.com' }
], 'or');
Info

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:

quick-filter.js
// Search all columns
grid.setQuickFilter('John');
// Search specific columns
grid.setQuickFilter('John', ['name', 'email', 'address']);
// Clear quick filter
grid.setQuickFilter('');
💡 Tip

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:

sql-query.js
const filterQuery = {
sql: 'age > ? AND (status = ? OR status = ?)',
params: [25, 'active', 'pending']
};
// Apply the SQL-like filter
grid.applyFilterQuery(filterQuery);

Filter Export

Export your filters to various backend query formats:

filter-export.js
// Get filter exports
const exports = grid.getFilterExports();
// REST API format
console.log(exports.rest);
// { name: { contains: 'John' }, age: { gte: 25, lte: 40 } }
// GraphQL format
console.log(exports.graphql);
// { where: { name: { contains: "John" }, age: { gte: 25, lte: 40 } } }
// SQL format
console.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
export-adapters.js
import { RestAdapter, GraphQLAdapter, SQLAdapter } from '@zengrid/core';
// Use adapters directly
const 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());
Warning

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
performance-config.js
const grid = new ZenGrid(container, {
filterCaching: true, // Enable filter result caching
filterIndexing: true, // Enable filter index management
rangeFilterOptimization: true
});

Events

Listen to filter changes:

filter-events.js
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

complex-filter-example.js
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 filters
grid.setFilter('status', 'in', ['active', 'pending']);
grid.setColumnFilter('age', [
{ operator: 'greaterThanOrEqual', value: 21 },
{ operator: 'lessThan', value: 65 }
], 'and');
grid.setFilter('name', 'notBlank');
// Get current filter state
const filterState = grid.getFilterState();
// Export for backend
const sqlExport = grid.getFilterExports().sql;
// Send to backend
await fetch('/api/filtered-data', {
method: 'POST',
body: JSON.stringify(sqlExport)
});

Substring Optimization

For substring filters (contains, startsWith, endsWith), ZenGrid uses optimized algorithms:

substring-filter.js
// Efficient substring searching
grid.setFilter('description', 'contains', 'important');
// Case-insensitive by default
grid.setFilter('name', 'contains', 'john', { caseSensitive: false });
💡 Tip

For best performance with large datasets, consider using backend filtering mode and creating appropriate database indices.