demo D46
The formatting panel
A user building their own rules at runtime, undoable and saved
grid.formatting.add()
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',
// The Formatting tab is a built-in panel. Adding a rule from it is one call
// into grid.formatting, which is why it is undoable and lands in a saved
// view. It opens on arrival because the panel is the subject.
toolPanel: {
side: 'left',
panels: ['formatting', 'columns', 'filters', 'views'],
actions: ['undo', 'redo', 'export', 'restore', 'maximise'],
exportName: 'lattice-demo',
openPanel: 'formatting',
},
// Two seeded rules, so the list is not empty on arrival. The first is on
// '*', the grid-wide scope, because that is the scope the panel opens on.
formatting: {
'*': [
{ id: 'any-failing', when: { op: 'eq', value: 'failing' }, style: { background: '#fbeceb', color: '#b03030' } },
],
openIncidents: [
{ id: 'incidents-open', when: { op: 'gte', value: 5 }, style: { background: '#fbeceb', color: '#b03030', fontWeight: '600' } },
],
},
columns: [
{ field: 'service', title: 'Service', layout: { pin: 'start', width: 140 } },
{ field: 'team', title: 'Team', filter: { type: 'set' } },
{ field: 'state', title: 'State', filter: { type: 'set' } },
{ field: 'instances', title: 'Instances', type: 'number' },
{ field: 'openIncidents', title: 'Incidents', type: 'number' },
{ field: 'p99Ms', title: 'p99 ms', type: 'number' },
{ field: 'monthlyCost', title: 'Monthly cost', type: 'number', format: { style: 'currency', currency: 'USD' } },
],
rows, // service records
});
</script>
Letting users build their own conditional formatting at runtime
Conditional formatting is usually fixed at build time, but some tools need the end user to define their own highlight rules while the grid is live, an operations dashboard where an analyst wants “flag anything over 500ms in red” without filing a ticket. Lattice Grid supports this through grid.formatting.add(), an imperative method that appends a rule to a column’s formatting list after the grid has already rendered, alongside a matching remove call so a rule panel can list, edit, and retract entries. Each rule takes the same { when, style } shape as configuration-driven rules, so a UI built on top of this API is a form that serialises a condition and a style into one call. Because rule creation sits outside the render path, this pairs with an undo stack: capturing the rule set before and after each add or remove gives undo and redo with no bespoke diffing, and the same serialised list can be persisted to storage and reapplied on load.
Rules added at runtime are compiled into the same per-column lookup used by static formatting, so a JavaScript data grid with a hundred user-authored rules scrolls at the same cost as one configured entirely up front: evaluation stays a fixed per-cell operation during rendering rather than a growing chain of conditions checked in sequence.
How do I let users create their own cell formatting rules?
Call grid.formatting.add() to insert a rule at runtime, and its matching remove method to take one out. Each rule is the same { when, style } pair used in static configuration, so a small form (condition plus colour) is enough to build an editable rules panel, and keeping a list of applied rules gives undo and redo for free.