Grid.js Searchable Table with Row Details — Free JS Snippet

Grid.js Lightweight Searchable Table with Row Details · Tables · Plain HTML, CSS & JS · Live preview

CategoryTables

What's included

Features

Search, sorting and pagination each enabled by one option
Debounced search so typing does not thrash the renderer
Fixed header with a scrolling body
Custom cell formatters using gridjs.html() for coloured language dots
Numeric sort comparator so star counts order correctly
Row-click detail panel using the rowClick event and raw cell data
Custom language labels and empty-state message
About 12 KB gzipped, framework-agnostic, styled with CSS overrides

About this UI Snippet

Grid.js Lightweight Searchable Table — HTML, CSS & JavaScript

Screenshot of the Grid.js Lightweight Searchable Table with Row Details snippet rendered live

Not every table needs a full data-grid framework. When you have a few hundred rows and want search, sorting and pagination without pulling in a large library or a UI-framework dependency, Grid.js is the lightweight option. It is framework-agnostic, weighs about twelve kilobytes gzipped, and turns a configuration object into a clean table with those three features switched on by three options. That makes it a good fit for documentation sites, dashboards embedded in content pages and quick admin tools.

The API is deliberately small. columns describes the headers and, optionally, how each one renders; data is a plain array of arrays (or objects); and the features are options — search, sort and pagination — that can be true or an object of settings. Here search has a debounceTimeout so typing does not re-render on every keystroke, pagination sets a page size with a "Showing 1 to 7 of 16 results" summary, and fixedHeader with a height keeps the header visible while the body scrolls. The whole grid is created with new gridjs.Grid(config) and drawn with .render(element).

Two details deserve attention. First, formatters. A column's formatter receives the cell value and returns what to show, and returning a string displays it as text. To show markup — the coloured language dot, the bold star count — the return value must be wrapped in gridjs.html(), which marks it as trusted HTML. That is a deliberate safety feature, and it puts responsibility on you: anything user-supplied that goes into a gridjs.html() string must be escaped first, or the table becomes an injection point. Second, sort comparison. Grid.js sorts values as strings by default unless told otherwise, so a numeric column needs a custom compare function, as the stars column has, or 9,000 sorts after 226,000.

The rowClick event provides the pointer event and the row, whose cells hold the raw values rather than formatted markup, which is what the detail panel below the table uses. The snippet also marks the clicked row with a class, because Grid.js does not track selection itself. Styling works through Grid.js's stable class names, so the look is set with ordinary CSS overrides, and the language option customises every label — useful both for localisation and for making the interface read naturally.

Step by step

How to Use

  1. 1
    SearchType in the search box. The table filters across every column after a short debounce.
  2. 2
    Sort a columnClick a column heading to sort. The Stars column sorts numerically, not alphabetically.
  3. 3
    Page through resultsUse the pagination controls under the table; the summary shows which results are visible.
  4. 4
    Click a rowSelect a row to highlight it and read its full description in the panel below.
  5. 5
    Search for nothingType a nonsense term to see the custom "No projects match" message.

Real-world uses

Common Use Cases

Documentation and reference tables
Add search and sorting to a static table. For a full-featured grid with editing and grouping see the Tabulator grid.
Lightweight dashboards
Show a list with search and paging without a heavy dependency.
ADMIN
Internal tools
Quick, dependable tables for admin pages built without a UI framework.
Learning trusted HTML in formatters
Shows why gridjs.html() exists and the escaping responsibility that comes with it.

Got questions?

Frequently Asked Questions

Formatters return text by default. Wrap the string in gridjs.html() to render it as markup, and escape any untrusted content first.

Values may sort as strings. Provide sort: { compare: (a, b) => a - b } on the column.

Use search: { debounceTimeout: 150 } so the table waits for a pause in typing.

Listen with grid.on("rowClick", (event, row) => ...). row.cells holds each cell's raw data.

Use the language option to override search, pagination and no-results text.

Yes. Replace data with a server option containing a url and a then function, and optionally enable server-side search, sort and pagination.

Yes. Use the JSX, Vue, Angular or Tailwind export buttons on this page to convert the markup and styles. The behaviour comes from Grid.js, so in a framework project install it with npm install gridjs (or gridjs-react / gridjs-angular / gridjs-vue) instead of the CDN tag, render it in useEffect / onMounted / ngAfterViewInit into a host element, and release it with destroy() when the component unmounts.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Ask an AI assistant like Claude to load the data from a REST endpoint with server-side pagination, add column visibility toggles, or export the visible rows to CSV.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a searchable, sortable, paginated table with Grid.js 6 loaded from a CDN (UMD script and the mermaid theme CSS).

Requirements:
- Create new gridjs.Grid({ columns, data, search: { debounceTimeout: 150 }, sort: true, pagination: { limit: 7, summary: true }, fixedHeader: true, height: '330px' }) and render it into a div.
- Use a formatter with gridjs.html() to show a coloured language dot, and a numeric compare function so the Stars column sorts correctly.
- Customise labels through the language option, including noRecordsFound.
- Listen for rowClick, highlight the clicked row, and show the raw row data in a detail panel.
- Restyle the table through Grid.js class names (gridjs-th, gridjs-td, gridjs-input).

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Source Code

<div class="gj-wrap">
  <div class="gj-head">
    <h3>Open source projects</h3>
    <span class="gj-tag">Grid.js &middot; 12&nbsp;KB gzipped</span>
  </div>
  <div id="gjHost"></div>
  <div class="gj-detail" id="gjDetail" aria-live="polite">Click a row to see its details here.</div>
</div>