Lattice Grid Buy a licence

the record editor · v1.107.0

JavaScript Record Editor for Forms and Grids

An order and its lines, saved once. The form on top holds the order, the grid below holds its lines, and both sit on the same rows. Change the status and a quantity, then watch the unsaved changes badge: it covers both.

See what it does Free on localhost

Building…
Loading a live grid…

no half-saved record

Reject the save and nothing is written.

An order header and its lines usually sit on two screens with a save button each, so the order that reaches the database can be one nobody typed. Here, tick Reject the next save in the demo above and press Save order. The store throws, the batch rolls back and the editor stays dirty. The demo shows a form and one grid on one small store. It does not show every view type.

const editor = createRecordEditor(el, {
  source, key: 'SO-4471',
  form: { rows: [{ cols: [{ type: 'input', name: 'customer', required: true }] }] },
  children: [{ id: 'lines', type: 'grid', relation: { from: 'id', to: 'orderId' }, config: { columns } }],
});

editor.on('dirty', ({ dirty }) => saveButton.disabled = !dirty);
if (!editor.validate()) await editor.save();

what it does

A form and its related rows, treated as one record.

  • One dirty state

    isDirty() is true if the form or any child has an unsaved edit, and a dirty event tells you when it changes. Wire it to a leave-this-page guard.

  • One validation pass

    validate() checks the form, then each child, and reports the first failure by view and field, such as the lines grid and its Qty column.

  • One batched save

    save() hands your store every changed row in a single call. If the store throws, the whole batch rolls back and the editor stays dirty.

  • Any child view

    A child can be a grid, a list, a tree, a board, a data view or a chart, each bound to the rows related to the record.

demos

Run it, then change it.

docs

Reference and the rest of the product.