Lattice Grid Buy a licence

demo D154

Cards, lists and feeds

Draw each row as a card instead of dividing it into columns

rowTemplate

Building…
Loading a live grid…

The configuration

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.13.0/lattice-grid.min.css">
<script src="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.13.0/lattice-grid.min.js"></script>

<div id="grid" style="height: 540px"></div>

<script>
  const grid = LatticeGrid.createGrid(document.getElementById('grid'), {
    rowKey: 'id',
    rowHeight: 82,
    // rowTemplate draws each row as a small piece of layout instead of dividing
    // it into columns. The columns stay declared, because they remain the data
    // model behind sort, filter and the tool panel.
    rowTemplate:
      '<div style="padding:11px 16px;line-height:1.35">' +
      '<div style="font-weight:600">{{data.service}} ' +
      '<span style="opacity:.55;font-weight:400">{{data.team}}</span></div>' +
      '<div style="opacity:.6;font-size:.85em;margin-top:2px">' +
      '{{data.region}} &middot; {{data.tier}} &middot; {{data.instances}} instances &middot; {{data.owner}}' +
      '</div></div>',
    columns: [
      { field: 'service', title: 'Service', layout: { pin: 'start', width: 140 } },
      { field: 'team', title: 'Team', filter: { type: 'set' } },
      { field: 'owner', title: 'Owner', filter: { type: 'set' } },
      { field: 'tier', title: 'Tier', cell: { decoration: 'pill', variant: { map: { gold: 'warning', silver: 'neutral', bronze: 'info' } } } },
      { field: 'state', title: 'State', cell: { decoration: 'dot', variant: { map: { healthy: 'success', degraded: 'warning', failing: 'danger', unknown: 'neutral' } } } },
      { field: 'region', title: 'Region', filter: { type: 'set' } },
      { field: 'active', title: 'Active', type: 'boolean' },
      { field: 'deprecated', title: 'Deprecated', type: 'boolean' },
      { field: 'version', title: 'Version', layout: { width: 100 } },
      { field: 'instances', title: 'Instances', type: 'number' },
      { field: 'cpuCores', title: 'vCPU', type: 'number' },
      { field: 'memoryGb', title: 'Memory GB', type: 'number' },
      { field: 'diskBytes', title: 'Disk', type: 'number', format: { notation: 'compact' } },
      { field: 'requests', title: 'Requests', type: 'number', format: { notation: 'compact' } },
      { field: 'errors', title: 'Errors', type: 'number' },
      { field: 'errorRate', title: 'Error rate', type: 'number', format: { style: 'percent', decimals: 2 } },
      { field: 'p50Ms', title: 'p50 ms', type: 'number' },
      { field: 'p95Ms', title: 'p95 ms', type: 'number' },
      { field: 'p99Ms', title: 'p99 ms', type: 'number' },
      { field: 'uptime', title: 'Uptime', type: 'number', format: { style: 'percent', decimals: 3 } },
      { field: 'monthlyCost', title: 'Monthly cost', type: 'number', format: { style: 'currency', currency: 'USD' }, total: 'sum' },
      { field: 'budget', title: 'Budget', type: 'number', format: { style: 'currency', currency: 'USD' }, total: 'sum' },
      { field: 'headcount', title: 'Headcount', type: 'number', total: 'sum' },
      { field: 'openIncidents', title: 'Incidents', type: 'number', total: 'sum' },
      { field: 'lastDeploy', title: 'Last deploy', type: 'dateString' },
      { field: 'created', title: 'Created', type: 'dateString' },
      { field: 'slaTarget', title: 'SLA', type: 'number', format: { style: 'percent', decimals: 2 } },
      { field: 'onCall', title: 'On call' },
      { field: 'repository', title: 'Repository', layout: { width: 260 } },
      { field: 'notes', title: 'Notes' },
    ],
    rows,  // wide service records
  });
</script>

Drawing rows as cards instead of columns

A card layout renders each row as a single card or feed item rather than dividing it into aligned columns. A developer reaches for this when the data reads better as a stack of records than as a table: a feed of activity, a set of profile cards, a list of messages, a mobile view where columns would be too narrow to be useful. Lattice Grid takes a rowTemplate that receives the row and returns the markup for one card, so the visible layout is yours to design while the columns stay the data model underneath: sorting, filtering, grouping and export all continue to work against the columns, even though nothing is drawn in a grid of cells. As a JavaScript data grid, the card body is still virtualised, so a feed of many thousands of cards renders only those in view and recycles card elements as the user scrolls, keeping memory flat regardless of list length. Because the columns remain the model, each card exposes its underlying fields to assistive technology, and the card container is announced as a list item rather than a table cell, matching how the content actually reads.

How do I show data grid rows as cards instead of a table?

Provide a rowTemplate that takes a row and returns the markup for one card. Lattice Grid draws each row with your template instead of splitting it into columns, while the columns remain the data model, so sorting, filtering, grouping and export keep working. The card body stays virtualised, rendering only the cards currently in view.