Lattice Grid Buy a licence

demo D88

The editor gallery

Twenty editors in one grid: date, duration, colour, rating, slider

editors/*

Building…
Loading a live grid…

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',
    selection: { mode: 'multiple', ranges: true },
    edit: true,
    toolPanel: { side: 'left', panels: ['columns', 'filters'], actions: ['restore'], exportName: 'editors' },
    columns: [
      { field: 'id', title: 'Order', layout: { width: 120, pin: 'start' } },
      { field: 'reference', title: 'text', layout: { width: 130 }, edit: { enabled: true, editor: 'text' } },
      { field: 'notes', title: 'textarea', layout: { width: 220 }, edit: { enabled: true, editor: 'textarea', props: { rows: 4, submitOn: 'ctrlEnter' } } },
      { field: 'budget', title: 'number', type: 'number', layout: { width: 120 }, edit: { enabled: true, editor: 'number', props: { min: 0, max: 100000, step: 500, spinner: true } } },
      { field: 'due', title: 'date', type: 'date', layout: { width: 140 }, edit: { enabled: true, editor: 'date' } },
      { field: 'signedOff', title: 'checkbox', type: 'boolean', layout: { width: 110 }, edit: { enabled: true, editor: 'checkbox' } },
      { field: 'stage', title: 'select', layout: { width: 140 }, lookup: { options: [{ id: 'planned', label: 'Planned' }, { id: 'approved', label: 'Approved' }, { id: 'in-flight', label: 'In-flight' }, { id: 'blocked', label: 'Blocked' }, { id: 'done', label: 'Done' }] }, edit: { enabled: true, editor: 'select', props: { allowClear: true } } },
      { field: 'tags', title: 'multiSelect', layout: { width: 190 }, lookup: { options: [{ id: 'fibre', label: 'fibre' }, { id: 'copper', label: 'copper' }, { id: 'wireless', label: 'wireless' }, { id: 'core', label: 'core' }, { id: 'edge', label: 'edge' }, { id: 'peering', label: 'peering' }], multiple: true }, edit: { enabled: true, editor: 'multiSelect', props: { selectAll: true, chipLimit: 2 } } },
      { field: 'window', title: 'time', type: 'time', layout: { width: 110 }, edit: { enabled: true, editor: 'time', props: { step: 15 } } },
      { field: 'starts', title: 'datetime', type: 'datetime', layout: { width: 180 }, edit: { enabled: true, editor: 'datetime' } },
      { field: 'elapsed', title: 'duration', type: 'duration', layout: { width: 130 }, edit: { enabled: true, editor: 'duration' } },
      { field: 'host', title: 'ipaddress', type: 'ipv4', layout: { width: 150 }, edit: { enabled: true, editor: 'ipaddress' } },
      { field: 'token', title: 'password', type: 'secret', layout: { width: 150 }, edit: { enabled: true, editor: 'password', props: { revealable: true } } },
      { field: 'payload', title: 'code', type: 'json', layout: { width: 220 }, edit: { enabled: true, editor: 'code', props: { language: 'json', rows: 8 } } },
      { field: 'transfer', title: 'unit', type: 'bytes', layout: { width: 130 }, edit: { enabled: true, editor: 'unit' } },
      { field: 'vlanMask', title: 'radix', type: 'hex16', layout: { width: 120 }, edit: { enabled: true, editor: 'radix' } },
      { field: 'effort', title: 'slider', type: 'number', layout: { width: 150 }, edit: { enabled: true, editor: 'slider', props: { min: 0, max: 100, step: 5, marks: [0, 50, 100] } } },
      { field: 'impact', title: 'rating', type: 'number', layout: { width: 130 }, edit: { enabled: true, editor: 'rating', props: { max: 5, allowClear: true } } },
      { field: 'priority', title: 'segmented', layout: { width: 170 }, lookup: { options: [{ id: 'low', label: 'Low' }, { id: 'normal', label: 'Normal' }, { id: 'high', label: 'High' }] }, edit: { enabled: true, editor: 'segmented' } },
      { field: 'team', title: 'treeSelect', layout: { width: 170 }, lookup: { options: [
        { id: 'north.leeds', label: 'Leeds', path: ['North', 'Leeds'] },
        { id: 'north.newcastle', label: 'Newcastle', path: ['North', 'Newcastle'] },
        { id: 'north.glasgow', label: 'Glasgow', path: ['North', 'Glasgow'] },
        { id: 'south.london', label: 'London', path: ['South', 'London'] },
        { id: 'south.bristol', label: 'Bristol', path: ['South', 'Bristol'] },
        { id: 'south.cardiff', label: 'Cardiff', path: ['South', 'Cardiff'] },
        { id: 'central.birmingham', label: 'Birmingham', path: ['Central', 'Birmingham'] },
        { id: 'central.manchester', label: 'Manchester', path: ['Central', 'Manchester'] },
      ] }, edit: { enabled: true, editor: 'treeSelect', props: { defaultExpanded: true } } },
      { field: 'owner', title: 'objectPicker', layout: { width: 180 }, lookup: { options: [
        { id: 'u1', label: 'Priya Raman', role: 'Network engineering' },
        { id: 'u2', label: 'Tom Ellery', role: 'Network engineering' },
        { id: 'u3', label: 'Sara Whitlock', role: 'Field operations' },
        { id: 'u4', label: 'Dan Osei', role: 'Field operations' },
        { id: 'u5', label: 'Marta Kowal', role: 'Capacity planning' },
        { id: 'u6', label: 'Joe Brennan', role: 'Capacity planning' },
      ] }, edit: { enabled: true, editor: 'objectPicker', props: { secondary: 'role' } } },
      { field: 'icon', title: 'iconPicker', layout: { width: 140 }, edit: { enabled: true, editor: 'iconPicker', props: { columns: 8 } } },
      { field: 'accent', title: 'colour', layout: { width: 130 }, edit: { enabled: true, editor: 'colour', props: { swatches: ['#1a6bc7', '#2f9e44', '#e8590c', '#c92a2a', '#7048e8', '#0b7285'] } } },
    ],
    rows,  // work orders, a field per editor
  });
</script>

Choosing the right cell editor for each column type

The editor gallery is a single grid carrying twenty editors side by side: text, number, date, duration, colour, rating, slider, lookup and more, each wired to the column type it belongs to rather than bolted on as an afterthought. A developer reaches for a specific editor whenever the default text input would misrepresent the data, a duration column edited as free text invites a typo a stepper would prevent, and a colour column benefits from a swatch picker rather than a hex string typed by hand. Lattice Grid selects the editor through the editors/* configuration, which maps a column’s declared type to its editing widget, so setting a column to type: 'date' or type: 'duration' brings its editor along with it instead of requiring a second registration step. Each editor opens on the same double-click, Enter or type-to-start gesture regardless of which one it is, so the interaction model stays constant even as the widget underneath changes from a calendar to a slider track. As a JavaScript data grid built for wide, densely typed tables, the gallery also keeps every editor keyboard-operable: a slider responds to arrow keys in fixed increments, a rating editor accepts a typed digit as well as a click, and Tab commits the current cell and advances focus without requiring a pointer at any point in the sequence.

What editor does Lattice Grid use for a date or duration column?

Lattice Grid picks the editor from the column’s type: a date column opens a calendar editor, a duration column opens a stepper for hours and minutes, and so on through the twenty types in the editors/* set. The mapping is automatic once the column type is declared, so no separate editor needs to be registered for standard types.