Lattice Grid Buy a licence

developer guide

Data Grid Inline Editing and Validation

A reader types straight into the cell, and the rules you declared on the column decide whether the value is allowed: required, min and max, length, pattern, one of a list, or a check that reads other fields in the same row. A rejected value never becomes state, and the reason is there to show.

Developer guideEditing › Data Grid Inline Editing and Validation

Editing

Turning it on

edit: { enabled: true },                 // double-click, the default
edit: { enabled: true, start: 'single' },// single click
editBar: true,                            // a spreadsheet-style input above the grid

columns: [
  { field: 'notes', edit: true },
  { field: 'statusId', edit: { editor: 'select' } },
  { field: 'quality', edit: { editor: 'rating', props: { max: 5, allowHalf: true } } },
  { field: 'circuitId', edit: false },
]

The editor is chosen from the type unless you name one. Enter commits and steps down, Tab commits and steps across, Escape cancels. A validator can refuse a value:

Validation

{ field: 'capacity', edit: {
  validate: (p) => p.value > 0 || 'Capacity must be positive',
}}

Declarative validation

The edit.validate function above is the imperative form. Where the rules are simple and the same across columns, declare them as data on validation instead: required, min/max, minLength/maxLength, pattern, oneOf, and a crossField predicate. Each is checked before the write, riding the cancellable beforeEdit event: a failing value cancels the commit, marks the cell with the same accessible invalid state an editor rejection uses, and fires validation:failed. Correcting the value clears the mark and fires validation:cleared. Only a user edit is gated - a host API write is the authority and is never self-vetoed.

Rules as data

columns: [
  { field: 'name', edit: true, validation: { required: true, minLength: 2 } },
  { field: 'age',  type: 'number', edit: true, validation: { min: 0, max: 120 } },
  { field: 'code', edit: true, validation: { pattern: '^[A-Z]{3}$', messages: { pattern: 'Three capitals.' } } },
]

// Why a write was refused, and clearing a mark by hand.
grid.validation.errorFor('r1', 'age');       // { code, message, key, colId } or null
grid.on('validation:failed', (e) => report(e.failures));
grid.on('validation:cleared', () => refreshBanner());

Deleting rows

Set rowDelete: true for the built-in delete gesture: Delete or Backspace on the selected rows, and a "Delete row" item in the cell menu. It works on a memory grid, not only a remote one, and every deletion flows through the cancellable beforeDelete event - so a confirm dialog is a handler that calls e.preventDefault(reason). It is off by default because deleting data on a keystroke is destructive.

Confirm before delete

const grid = createGrid(el, { columns, rows, rowKey: 'id', selection: 'multiple', rowDelete: true });

grid.on('beforeDelete', async (e) => {
  const ok = await confirmDialog(`Delete ${e.rows.length} row(s)?`);
  if (!ok) e.preventDefault('cancelled');   // the rows stay; delete:cancelled fires
});

// The gesture calls this; you can call it too. Defaults to the selection.
grid.edit.deleteRows();