Lattice Grid Buy a licence

developer guide

Coming from dhtmlx Grid

A compatibility wrapper shaped like dhtmlx's dhx.Grid, so the constructor and the data, selection, history, export and event namespaces keep working after an import swap.

Developer guide › Coming from dhtmlx Grid

Coming from dhtmlx Grid

lattice-grid/modules/dhtmlx-compat exposes a Grid class shaped like dhtmlx's own dhx.Grid, the same constructor call, the same .data, .selection, .history, .export and .events namespaces: sitting on top of a real Lattice grid underneath. Swap the import and, for the surface below, the calling code does not change.

A drop-in constructor

import { Grid } from '@toclocoinc/lattice-grid/modules/dhtmlx-compat';

const grid = new Grid(container, {
  columns: [
    { id: 'name', header: [{ text: 'Name' }], width: 200, sortable: true },
    { id: 'qty', header: [{ text: 'Qty' }], type: 'number', editable: true, editorType: 'input' },
  ],
  data: rows,
});

grid.events.on('cellClick', (row, column, event) => {
  // row and column carry .id, row's own fields sit alongside it,
  // the same shape dhtmlx's own IRow/ICol declare.
});

What is covered: column definitions (header, width, sortable, resizable, hidden, editorType, editorConfig, options, template, summary); .data's add/update/remove/ removeAll/parse/load/find/ findAll/exists/getItem/getId/ getIndex/getLength/forEach/serialize/ sort/filter/resetFilter; .selection's setCell/getCell/getCells/isSelectedCell/ removeCell; .history's undo/redo/ canUndo/canRedo/clear/getHistory; .export.csv/.xlsx; and the events cellClick, cellDblClick, cellRightClick, afterEditStart, afterEditEnd, afterSort, filterChange, afterColumnDrop, resize, afterResizeEnd, afterColumnHide, afterColumnShow, afterExpand, afterCollapse, afterSelect, afterUnSelect, afterCopy, afterRowDrop and scroll. Grid-level dragItem: 'row' becomes rowReorder: true: same-grid drag-to-reorder.

cellClick, cellDblClick, cellRightClick, afterEditStart, afterEditEnd and afterSort call your handler with dhtmlx's own positional arguments: (row, column, event), not Lattice's own event object, because that is dhtmlx's own documented signature for them. afterRowDrop calls your handler with (data, event), firing from either a same-grid reorder settling or a row landing here from another grid, dhtmlx has one event name for what Lattice models as two. Every other mapped event calls your handler with Lattice's own event object, under Lattice's own field names, since a wrong guess at a fabricated positional shape is worse than an honest one.

Index means current display order: after sort, filter and grouping: everywhere .data takes or returns one. dhtmlx is not fully consistent about this across its own methods; this is the one meaning, held everywhere.

Cross-grid dragging needs an explicit rowTransfer. dhtmlx lets any two grids with dragItem: 'row' on the same page exchange rows by default; Lattice's rowTransfer is deliberately opt-in per pair, with no dhtmlx property to derive it from, so a caller wanting that behaviour passes rowTransfer straight through as a bonus config key.

What is not. Every before*/can*/cancel* event is unmapped: dhtmlx's convention lets a handler return false to cancel the action, and Lattice has no cancelable-event model to honour that with: approximating one would silently ignore a return false a caller depends on. Row and column drag-negotiation events (beforeRowDrag, dragRowOut, canRowDrop, cancelRowDrop, beforeRowDrop and their column equivalents) are unmapped for the same reason: each can refuse or steer a drag mid-gesture, which Lattice has no live protocol to offer. export.pdf() and export.png() throw: there is no raster export to translate to. .rangeSelection is offered on a best-effort basis and its range shape is this wrapper's own design, not dhtmlx's, a genuine RangeSelection module is a separate part of dhtmlx's own product, and this wrapper does not know its exact shape. Classic dhtmlXGridObject (pre-Suite 5, string-configured, index-addressed) is a different product in every respect that matters here and is not covered at all.

Calling an unmapped event name does not fail silently: the first subscription logs which name has no Lattice equivalent, so a caller relying on it finds out in development rather than in production.