demo D283
Validation declared on the column in ESM
An invalid edit vetoed with an announced inline error, from rules stated as data
validation: { required, min, max, pattern, oneOf }
This grid states its edit rules as data on the column, required, min, max, a pattern or an allowed list, and vetoes an invalid edit with an announced inline error. It keeps the definition of a good value next to the column, so validation is readable and consistent rather than hand-coded per field.
This is the ES module version. The grid is imported straight from a CDN as a module, the same configuration as the vanilla tab without a global script tag, so it drops into any bundler or a bare module script.
The configuration
<link rel="stylesheet" href="https://cdn.latticegrid.dev/lattice-grid@1.107.0/lattice-grid.min.css">
<div id="grid" style="height: 520px"></div>
<script type="module">
import { createGrid } from 'https://cdn.latticegrid.dev/lattice-grid@1.107.0/lattice-grid.esm.min.js';
const grid = createGrid(document.getElementById('grid'), {
rowKey: 'id',
selection: 'multiple',
edit: true,
columns: [
{ field: 'id', title: 'Order', layout: { width: 120, pin: 'start' } },
{ field: 'reference', title: 'Reference', layout: { width: 130 }, edit: true,
// A pattern the whole value must match, with its own message.
validation: {
required: true,
pattern: '^(CHG|INC|REQ)-\\d{4}$',
messages: { pattern: 'Use CHG, INC or REQ followed by four digits.', required: 'A reference is required.' },
} },
{ field: 'team', title: 'Team', filter: { type: 'set' }, edit: true,
// One of a fixed set, and never blank.
validation: { required: true, oneOf: ['Core', 'Platform', 'Edge', 'Field'], messages: { oneOf: 'Pick one of the four teams.' } } },
{ field: 'circuits', title: 'Circuits', type: 'number', layout: { width: 110 }, edit: true,
// A whole number in range: min and max carry the bounds.
validation: { required: true, min: 1, max: 40, messages: { min: 'At least one circuit.', max: 'Forty circuits at most.' } } },
{ field: 'budget', title: 'Budget', type: 'number', layout: { width: 140 },
format: { style: 'currency', currency: 'GBP' }, total: 'sum', edit: true,
// A cross-field rule: the budget is read against the circuits on the same
// row, so the ceiling moves with the record. Return true or a message.
validation: {
min: 0,
messages: { min: 'A budget cannot be negative.' },
crossField: (value, row) => {
const circuits = Number((row.data ?? row).circuits ?? 0);
return Number(value) <= circuits * 5000 ? true : 'At ' + circuits + ' circuits the cap is ' + (circuits * 5000);
},
} },
],
rows, // work orders: id, reference, team, circuits, budget
});
// A vetoed edit is announced with its message and rolled back; a corrected
// value clears the mark. A value your own code writes is never gated.
</script>
Validation stated as data, enforced before the value lands
A grid that lets people edit needs to say what a good value looks like. Lattice Grid takes those rules as data on the column: validation accepts required, min and max, minLength and maxLength, a pattern, a oneOf list, and a crossField predicate for a rule that reads the rest of the row. Each rule is checked against a new value before it is written. A failing value is vetoed, so the cell keeps its old value and nothing half-valid ever lands, and the cell is marked with the grid’s own invalid state, an error that is announced to a screen reader rather than shown only as a red border. Correct the value and the mark clears.
Declaring the rules rather than writing them as a function keeps the constraints in one readable place, checkable outside the render path, and lets a rule carry its own message so a person sees “Use CHG, INC or REQ followed by four digits” instead of a generic refusal. Only a person’s edit is gated: a value written by your own code or arriving from a live feed is treated as the authority and lands untouched, so validation guards the keyboard without fighting your data flow.
How do I stop a grid accepting an invalid edit?
Declare the rules on the column under validation: required for a value that may not be blank, min and max for a number or date range, pattern for a shape the whole value must match, oneOf for a fixed set, and crossField for a rule that compares against other fields on the same row. A failing edit is vetoed before it is written, the cell is marked with an announced inline error, and a corrected value clears the mark. Give a rule its own message through messages so the reason is specific rather than generic.