Lattice Grid Buy a licence

blog

The table is the schema

Building…
Loading a live grid…

Most data grids open by asking you to describe your data to them: a columns array, a rows array, a config object, all in JavaScript and all before anything appears on the screen. That is a fair contract when the page is a single-page application that had to boot a framework anyway. It is a worse fit when the page is mostly server-rendered HTML and the grid is one region inside it.

htmx is built for that second kind of page. The server owns the HTML, sends fragments back in response to requests, and htmx swaps them into place. A grid that expects to be constructed by hand, in JavaScript, inside one of those fragments is working against the model: the fragment is swapped, the grid it held is discarded, and nothing puts it back.

The markup is the schema

The grid above started as a plain <table>. Each header cell carries a data-field that names its column, the body carries the rows, and a single call to hydrateTable reads both and replaces the table with a live grid. There is no columns array anywhere on the page. The shape of the data is the shape of the table, which the server already knows how to render, so nothing is described twice.

Two things follow from starting with a real table rather than an empty container. The page works with JavaScript switched off: what a reader with no scripting, or a crawler, sees is the same data in a table, not a spinner waiting on a bundle. The grid is enhancement laid over a page that had already answered the question. And a typed column is declared the way a server template declares anything, with an attribute on the header cell, data-type="number", rather than a line of client-side configuration a template engine would have to learn to emit.

Surviving the swap

The reason to reach for the htmx module rather than a hand-written createGrid is what happens on the next request. htmx swaps fragments of the DOM in and out, and the module attaches to those swaps, so a grid inside a swapped region is preserved rather than torn out and forgotten. From there it can drive sort, filter and infinite scroll as ordinary htmx requests that the server answers, which keeps pagination and the request lifecycle on the server where htmx already puts everything else.

The demo on this page is the client-side half of that: a table becomes a grid, in the browser, with no server behind this page at all. The server-driven half needs a server, which a static page like this one does not have, so this shows the hydration and leaves the request-driving to the documentation.

One bundle, one attribute, one call

The integration ships as a single module that carries its own copy of the grid, so a page loads it instead of the base build rather than beside it. The whole setup is a data-lattice-grid attribute on the table and a call to autoInit, and the licence, on a deployed site, travels in the same config the hydration reads. Nothing about the page stops being HTML.

See it running or read the guide.

Read next

  • Swap the import

    A compatibility layer gives Lattice Grid the shape of dhtmlx's dhx.Grid, so the constructor, the data and selection namespaces and the events keep working. Swap the import.

  • The column knows it holds metres

    In most grids a unit is a formatter, and a formatter is a lie that shows the moment someone sorts. Lattice Grid makes a quantity a data type, so the column stays a number.

  • When the grid became the interface

    Grids are sold to developers, so they are built for developers. Why Lattice Grid ships redaction, annotation and presentation tools to every user as standard.

All posts RSS