demo D61
The advanced filter builder
Nested and/or/not groups against the same tree the menus produce
FilterSet
The configuration
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.13.0/lattice-grid.min.css">
<script src="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.13.0/lattice-grid.min.js"></script>
<div id="grid" style="height: 540px"></div>
<script>
const grid = LatticeGrid.createGrid(document.getElementById('grid'), {
rowKey: 'id',
toolPanel: { side: 'left', panels: ['filters', 'columns'], actions: ['restore'], exportName: 'lattice-demo' },
columns: [
{ field: 'service', title: 'Service', layout: { pin: 'start', width: 140 }, filter: true },
{ field: 'team', title: 'Team', filter: { type: 'set' } },
{ field: 'tier', title: 'Tier', filter: { type: 'set' } },
{ field: 'state', title: 'State', filter: { type: 'set' } },
{ field: 'region', title: 'Region', filter: { type: 'set' } },
{ field: 'errorRate', title: 'Error rate', type: 'number', format: { style: 'percent', decimals: 2 }, filter: { type: 'number' } },
{ field: 'monthlyCost', title: 'Monthly cost', type: 'number', layout: { width: 160 },
format: { style: 'currency', currency: 'USD' }, total: 'sum', filter: { type: 'number' } },
{ field: 'lastDeploy', title: 'Last deploy', type: 'dateString', filter: { type: 'date' } },
{ field: 'created', title: 'Created', type: 'dateString', filter: { type: 'date' } },
],
// An or inside an and, with a not beside it: costly, unhealthy, not bronze.
// The parts that belong to one column still appear in that column's menu.
state: {
version: 1,
filters: {
op: 'and',
conditions: [
{ col: 'monthlyCost', op: 'gte', value: 2000 },
{
op: 'or',
conditions: [
{ col: 'state', op: 'in', value: ['failing', 'degraded'] },
{ col: 'errorRate', op: 'gt', value: 0.05 },
],
},
{ op: 'not', conditions: [{ col: 'tier', op: 'eq', value: 'bronze' }] },
],
},
},
rows, // 20,000 service records
});
</script>
Building nested and/or/not filter groups against the grid’s own filter tree
The filter menu produces a condition tree each time a user narrows a column, and the advanced filter builder composes that same tree by hand rather than one column at a time. A developer reaches for it when the filtering logic outgrows per-column menus: a request such as “region is UK or Ireland, and status is not cancelled, and either priority is high or the order is over 90 days old” needs nested groups with mixed AND, OR and NOT, not a flat list of conditions applied in sequence. Lattice Grid exposes this through the FilterSet API, which accepts and returns the identical tree the filter menu builds internally, so a group assembled in the builder, a condition applied from a column menu, and a tree restored from a saved view all pass through the same evaluation path with no separate reconciliation step. Filtering runs against the underlying row model rather than the rendered rows, so a nested group with several branches evaluates in one pass over the data behind a JavaScript data grid, without re-measuring rows that stay off-screen. The builder is keyboard-operable throughout: adding a group, changing its operator, and deleting a condition are each reachable by Tab and Enter, and every group’s boolean operator is a labelled control rather than an icon alone.
How do you build a filter with nested AND, OR and NOT groups?
Use the FilterSet API to construct or edit the condition tree directly rather than composing it through the per-column filter menus. The advanced filter builder gives users the same tree as an interactive form, with groups that can nest inside other groups and each carry their own AND, OR or NOT operator, and the result applies through the same FilterSet call a saved or scripted filter would use.