Sortable Grid

Grid with sortable columns, multi-column sort state, and sort events.

This example enables sorting through ColumnDef.sortable and the grid.sort API.

Click a column header to sort. Shift+click for multi-sort.

Enable Sorting

sortable-grid.ts
import { Grid, type ColumnDef, type SortState } from '@zengrid/core';
import '@zengrid/core/dist/styles.css';
const columns: ColumnDef[] = [
{ field: 'id', header: 'ID', width: 60, sortable: true },
{ field: 'name', header: 'Name', width: 200, sortable: true },
{ field: 'role', header: 'Role', width: 150, sortable: true },
{ field: 'status', header: 'Status', width: 120, sortable: true },
];
const rows = [
[1, 'Alice', 'Admin', 'Active'],
[2, 'Bob', 'Editor', 'Inactive'],
[3, 'Charlie', 'Viewer', 'Active'],
];
const grid = new Grid(document.getElementById('grid')!, {
columns,
rowCount: rows.length,
colCount: columns.length,
rowHeight: 40,
colWidth: columns.map((column) => column.width ?? 140),
});
grid.setData(rows);
grid.render();
const sortState: SortState[] = [{ column: 1, direction: 'asc' }];
grid.sort.apply(sortState);

API Usage

sort-api.ts
grid.sort.toggle(1);
grid.sort.apply([{ column: 2, direction: 'asc' }]);
grid.sort.apply([
{ column: 2, direction: 'asc', sortIndex: 0 },
{ column: 1, direction: 'desc', sortIndex: 1 },
]);
grid.sort.clear();
const current = grid.sort.getState();
💡 Tip

Header clicks update sort state automatically for sortable columns. Use Shift plus header click for additive multi-sort behavior.

Sort Events

sort-events.ts
grid.on('sort:change', ({ sortState, previousSortState }) => {
console.log('Previous:', previousSortState);
console.log('Current:', sortState);
});
grid.on('header:sort:click', ({ columnIndex, nextDirection, additive }) => {
console.log({ columnIndex, nextDirection, additive });
});

Backend Sorting

When dataMode: 'backend' is enabled, sort state is included in data requests.

backend-sort.ts
const grid = new Grid(container, {
columns,
rowCount: 50000,
colCount: columns.length,
rowHeight: 40,
colWidth: columns.map((column) => column.width ?? 140),
dataMode: 'backend',
onDataRequest: async (request) => {
const response = await fetch('/api/users/query', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(request.query),
signal: request.signal,
});
return response.json();
},
});

Next Steps