Lattice Grid Buy a licence

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.

Building…
Loading a live grid…

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.