demo D63
Filters in saved views
Round-tripping a filter model, including relative dates
state.get() / state.apply()
The configuration
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.27.0/lattice-grid.min.css">
<div id="grid"></div>
<script type="module">
import React from 'https://esm.sh/react@18';
import { createRoot } from 'https://esm.sh/react-dom@18/client';
import { createGrid } from 'https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.27.0/lattice-grid.esm.min.js';
import createLatticeGrid from 'https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.27.0/modules/react.esm.min.js';
const LatticeGrid = createLatticeGrid({ React, createGrid });
const 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' } },
];
// A day offset from today, as the yyyy-mm-dd the date columns store.
const day = (offset) => {
const d = new Date();
d.setDate(d.getDate() + offset);
return d.toISOString().slice(0, 10);
};
// Saved views, each carrying nothing but a filter tree. The last one keeps a
// relative date: the absolute pair is what filters, and the token beside it is
// what makes the date menu read "last 7 days" rather than two fixed dates.
const views = {
saved: [
{ id: 'expensive', name: 'Over $20k',
state: { version: 1, filters: { col: 'monthlyCost', op: 'gt', value: 20000 } } },
{ id: 'unhealthy', name: 'Failing or degraded',
state: { version: 1, filters: { col: 'state', op: 'in', value: ['failing', 'degraded'] } } },
{ id: 'recent', name: 'Deployed this week',
state: { version: 1, filters: {
col: 'lastDeploy', op: 'between', value: [day(-7), day(0)], bounds: '[)',
meta: { relative: 'last7Days', n: 7 },
} } },
],
};
const rows = [/* 20,000 service records */];
function App() {
return (
<LatticeGrid
rowKey="id"
toolPanel={{ side: 'left', panels: ['views', 'filters', 'columns'], openPanel: 'views', actions: ['restore'], exportName: 'lattice-demo' }}
views={views}
columns={columns}
rows={rows}
style={{ height: '540px' }}
/>
);
}
createRoot(document.getElementById('grid')).render(<App />);
</script>
Saving and restoring a filter model, including relative dates
A filter model is the set of active filter conditions across every column: which operators are in use, which values or ranges are set, and how the conditions combine. Round-tripping it is what lets an application offer saved views, where a user picks “Open orders this quarter” from a menu and the grid re-applies the same conditions it had when the view was captured. Lattice Grid exposes this through state.get() and state.apply(), a pair of methods that serialise the current filter model to a plain object and restore it later, in the same session or a fresh one built from persisted JSON. A developer reaches for this wherever filters need to survive a page reload, a saved-view picker, or a shared link that opens pre-filtered. The harder case is a relative date filter such as “last 7 days”: storing the resolved date range would make the saved view stale the next day, so state.get() preserves the relative expression itself, and state.apply() re-resolves it against the current date on restore. This matters for a JavaScript data grid used across time zones, since a relative range resolves against the viewer’s local date, not the date the view was saved. Restoring a filter model does not re-fetch rows, so applying a saved view is a filter pass over data already in memory, not a new query.
How do I save a filter and restore it later, including relative date ranges?
Call state.get() to serialise the current filter model, including any relative date expressions, and store the result. Call state.apply() with that object to restore it, on the same grid instance or a new one. Relative expressions such as “last 7 days” are kept as expressions and re-resolved against the current date at apply time, not frozen to the date they were saved.