Editable Grid

Grid with inline editing, editor configuration, and edit events.

This example enables editing through ColumnDef.editable and editor configuration. Users can start editing with the built-in interaction model, then your app listens for edit events.

Double-click a cell to edit. Press Enter to commit, Escape to cancel.

Enable Editing

editable-grid.ts
import { Grid, type ColumnDef } from '@zengrid/core';
import '@zengrid/core/dist/styles.css';
const columns: ColumnDef[] = [
{ field: 'id', header: 'ID', width: 60 },
{ field: 'name', header: 'Name', width: 200, editable: true, editor: 'text' },
{ field: 'email', header: 'Email', width: 260, editable: true, editor: 'text' },
{ field: 'age', header: 'Age', width: 100, editable: true, editor: 'number' },
{ field: 'active', header: 'Active', width: 100, editable: true, editor: 'checkbox' },
];
const rows = [
[1, 'Alice', 'alice@example.com', 30, true],
[2, 'Bob', 'bob@example.com', 25, true],
[3, 'Charlie', 'charlie@example.com', 35, false],
];
const grid = new Grid(document.getElementById('grid')!, {
columns,
rowCount: rows.length,
colCount: columns.length,
rowHeight: 40,
colWidth: columns.map((column) => column.width ?? 140),
enableSelection: true,
enableKeyboardNavigation: true,
});
grid.setData(rows);
grid.render();
Info

Only columns marked with editable: true enter edit mode. Use editor and editorOptions to choose and configure the editor.

Editor Options

editor-options.ts
const columns: ColumnDef[] = [
{
field: 'name',
header: 'Name',
width: 200,
editable: true,
editor: 'text',
editorOptions: { placeholder: 'Enter name' },
},
{
field: 'age',
header: 'Age',
width: 100,
editable: true,
editor: 'number',
editorOptions: { min: 0, max: 120, step: 1 },
},
{
field: 'role',
header: 'Role',
width: 150,
editable: true,
editor: 'select',
editorOptions: {
options: [
{ value: 'admin', label: 'Administrator' },
{ value: 'editor', label: 'Editor' },
{ value: 'viewer', label: 'Viewer' },
],
},
},
];

Edit Events

edit-events.ts
grid.on('edit:start', ({ cell, value }) => {
console.log('Edit started:', cell, value);
});
grid.on('edit:commit', ({ cell, oldValue, newValue }) => {
rows[cell.row][cell.col] = newValue;
console.log('Committed:', oldValue, newValue);
});
grid.on('edit:cancel', ({ cell }) => {
console.log('Cancelled:', cell);
});
grid.on('edit:end', ({ cell, cancelled }) => {
console.log('Edit ended:', cell, cancelled);
});

Undo And Redo

The undo/redo plugin is installed by the core grid setup. The everyday Grid instance does not currently expose a first-class grid.undoRedo namespace, so application docs should prefer edit events and app-owned history for production workflows.

Advanced integrations can reach plugin methods through grid.getGridApi():

advanced-undo-redo.ts
const api = grid.getGridApi();
const undo = api.getMethod('undoRedo', 'undo');
const redo = api.getMethod('undoRedo', 'redo');
undo?.();
redo?.();
Warning

grid.getGridApi() is a lower-level plugin integration surface. Wrap it in your own adapter before relying on it broadly in app code.

Complete Example

complete-editable.ts
import { Grid, type ColumnDef } from '@zengrid/core';
import '@zengrid/core/dist/styles.css';
const rows = [
[1, 'Alice', 'alice@example.com', 30, 'admin', true],
[2, 'Bob', 'bob@example.com', 25, 'editor', true],
[3, 'Charlie', 'charlie@example.com', 35, 'viewer', false],
];
const columns: ColumnDef[] = [
{ field: 'id', header: 'ID', width: 60 },
{ field: 'name', header: 'Name', width: 200, editable: true, editor: 'text' },
{ field: 'email', header: 'Email', width: 260, editable: true, editor: 'text' },
{ field: 'age', header: 'Age', width: 100, editable: true, editor: 'number' },
{
field: 'role',
header: 'Role',
width: 150,
editable: true,
editor: 'select',
editorOptions: {
options: [
{ value: 'admin', label: 'Administrator' },
{ value: 'editor', label: 'Editor' },
{ value: 'viewer', label: 'Viewer' },
],
},
},
{ field: 'active', header: 'Active', width: 100, editable: true, editor: 'checkbox' },
];
const grid = new Grid(document.getElementById('grid')!, {
columns,
rowCount: rows.length,
colCount: columns.length,
rowHeight: 40,
colWidth: columns.map((column) => column.width ?? 140),
enableSelection: true,
enableKeyboardNavigation: true,
});
grid.setData(rows);
grid.render();
grid.on('edit:commit', ({ cell, newValue }) => {
rows[cell.row][cell.col] = newValue;
});

Next Steps