Lattice Grid Buy a licence

demo D219

Locales, and it mirrors in htmx

The same grid in English, Japanese and Arabic, which sets the grid right to left

locale · direction: 'rtl'

This shows the same grid in English, Japanese and Arabic, with Arabic laying the whole grid out right to left. It proves the grid adapts to a locale end to end, mirroring its layout for right-to-left languages rather than just swapping words.

Building…
Loading a live grid…

This is the htmx version. A server-rendered table is upgraded in place, so the page is readable before any script runs and gains the full grid when the module loads, which suits a progressively enhanced app.

The configuration

<link rel="stylesheet" href="https://cdn.latticegrid.dev/lattice-grid@1.108.0/lattice-grid.min.css">

<script type="importmap">
{ "imports": { "@toclocoinc/lattice-grid": "https://cdn.latticegrid.dev/lattice-grid@1.108.0/lattice-grid.esm.min.js" } }
</script>

<div id="buttons" style="display: flex; gap: 8px; margin-bottom: 12px"></div>
<!-- A real, server-rendered table: readable with JavaScript off. data-field on
     each header names the column that cell becomes, and data-id on each row is
     the key the grid carries it under. -->
<table id="locales-and-rtl-table" data-lattice-grid>
  <thead>
    <tr>
      <th data-field="product">Product</th>
      <th data-field="price">Price</th>
      <th data-field="updated">Updated</th>
      <th data-field="share">Share</th>
    </tr>
  </thead>
  <tbody>
    <tr data-id="1"><td>Desk lamp</td><td>42.5</td><td>2026-08-01</td><td>0.18</td></tr>
    <tr data-id="2"><td>Task chair</td><td>189</td><td>2026-08-03</td><td>0.41</td></tr>
    <tr data-id="3"><td>Monitor arm</td><td>76.25</td><td>2026-08-09</td><td>0.27</td></tr>
    <!-- the rest of the rows, rendered by your server -->
  </tbody>
</table>

<script type="module">
  import { hydrateTable, registerLocale } from 'https://cdn.latticegrid.dev/lattice-grid@1.108.0/modules/htmx.esm.min.js';
  import { JA_JP } from 'https://cdn.latticegrid.dev/lattice-grid@1.108.0/locales/ja-JP.esm.min.js';
  import { AR } from 'https://cdn.latticegrid.dev/lattice-grid@1.108.0/locales/ar.esm.min.js';

  // This module carries its own copy of the grid, which a locale file's own
  // registration does not reach: hand the module the catalogue.
  registerLocale('ja-JP', JA_JP);
  registerLocale('ar', AR);

  // The same grid and the same rows in three locales. Only the chrome and the
  // formatting change: numbers, currency and dates read the grid's locale, and
  // Arabic sets direction: 'rtl', which mirrors the whole grid, pin and all.
  const locales = {
    English:  { locale: 'en-GB', direction: 'ltr', currency: 'GBP', titles: ['Product', 'Price', 'Updated', 'Share'] },
    日本語:    { locale: 'ja-JP', direction: 'ltr', currency: 'JPY', titles: ['製品', '価格', '更新日', 'シェア'] },
    العربية:  { locale: 'ar-EG', direction: 'rtl', currency: 'EGP', titles: ['المنتج', 'السعر', 'تاريخ التحديث', 'الحصة'] },
  };

  let grid;
  function build(name) {
    const L = locales[name];
    grid?.destroy();
    grid = hydrateTable(document.getElementById('locales-and-rtl-table'), {
      locale: L.locale,
      direction: L.direction,
      columns: [
        { field: 'product', title: L.titles[0], layout: { pin: 'start', width: 180 } },
        { field: 'price', title: L.titles[1], type: 'number',
          format: { style: 'currency', currency: L.currency }, total: 'sum' },
        { field: 'updated', title: L.titles[2], type: 'date' },
        { field: 'share', title: L.titles[3], type: 'number', format: { style: 'percent' } },
      ],
    });
  }

  for (const name of Object.keys(locales)) {
    const b = document.createElement('button');
    b.textContent = name;
    b.onclick = () => build(name);
    document.getElementById('buttons').append(b);
  }
  build('English');
</script>