Filter Templates
Introduction
Section titled “Introduction”Filter templates let a user snapshot a whole filter — every column’s conditions plus the quick filter — under a name, then re-apply it later in a single click. Each saved template shows an applied / not-applied indicator so it’s obvious which one (if any) matches the grid’s current filter.
import { filterTemplates } from '@zengrid/enterprise/grid';
const templates = filterTemplates(grid, { storage: 'local', // persist to localStorage (default) storageKey: 'orders-grid', // give each grid a distinct key ui: { mount: toolbarEl }, // optional built-in bar});
templates.save('High value, unshipped'); // snapshot the current filtertemplates.apply(id); // restore it latertemplates.getActiveId(); // which template matches right now?filterTemplates() is license-gated (it asserts the filter-templates feature). It
builds entirely on core’s grid.filter snapshot/restore API — no special grid setup is
needed beyond having filterable columns.
Storage is pluggable
Section titled “Storage is pluggable”'local'(default) — persists tolocalStorage, keyed bystorageKey. Give each grid on a page its own key.'memory'— session-only; nothing is written to disk.{ load, save }— supply your own backend.load()returns the saved templates,save(templates)persists them — point it at your API to sync per-user.
The applied indicator
Section titled “The applied indicator”getActiveId() normalizes the current filter and compares it, order-independently,
against each saved template — returning the matching template’s id, or null. The
built-in FilterTemplateBar uses it to mark the active chip; subscribe to the manager
(and, if you render your own UI, to the grid’s filter:change) to keep it live as the
user edits filters.
The FilterTemplateBar renders a chip per template with an applied indicator. Click a chip to apply; use "Save current filter" to snapshot the current filter.
interface FilterTemplate { id: string; name: string; model: FilterSnapshot; // { state: FilterModel[]; quick: { query; columns } }}
interface FilterTemplatesInit { storage?: 'local' | 'memory' | { load(): FilterTemplate[]; save(t: FilterTemplate[]): void }; storageKey?: string; // localStorage key for storage: 'local' templates?: FilterTemplate[]; // seed when storage is empty ui?: FilterTemplateBarOptions; // mount the built-in bar}
function filterTemplates(grid, options?): FilterTemplateManager;
interface FilterTemplateManager { save(name: string): FilterTemplate; apply(id: string): void; remove(id: string): void; rename(id: string, name: string): void; list(): FilterTemplate[]; getActiveId(): string | null; // the applied indicator isActive(id: string): boolean; snapshot(): FilterSnapshot; setTemplates(templates: FilterTemplate[]): void; subscribe(cb: () => void): () => void; destroy(): void; // also tears down an attached bar}- No core change needed. Templates snapshot
grid.filter.getState()+getQuick()and restore viasetState()/setQuick()— the public Filter API. - Distinct
storageKeyper grid. Withstorage: 'local', two grids sharing a key would share templates — key them apart. - The bar is optional.
filterTemplates()returns a headless manager; theFilterTemplateBar(viaui) is one presentation. Build your own from the manager API if you prefer. - Active detection is order-independent. Column order and condition order don’t affect whether a template matches — only the effective filter does.
- Filter Styling — theme the filter popup, down to the part.
- Applying Filters — the
grid.filter.*API templates build on. - Quick Filter — the grid-wide search captured in a template.