EditingPlugin
Editing Plugin for tbw-grid
Enables inline cell editing in the grid. Provides built-in editors for common data types and supports custom editor functions for specialized input scenarios.
Why Opt-In?
Section titled “Why Opt-In?”Editing is delivered as a plugin rather than built into the core grid:
- Smaller bundle — Apps that only display data don’t pay for editing code
- Clear intent — Explicit plugin registration makes editing capability obvious
- Runtime validation — Using
editable: truewithout the plugin throws a helpful error
Installation
Section titled “Installation”import { EditingPlugin } from '@toolbox-web/grid/plugins/editing';Edit Triggers
Section titled “Edit Triggers”Configure how editing is triggered with the editOn option:
| Value | Behavior |
|---|---|
'click' | Single click enters edit mode (default) |
'dblclick' | Double-click enters edit mode |
Keyboard Shortcuts
Section titled “Keyboard Shortcuts”| Key | Action |
|---|---|
Enter | Commit edit and move down |
Tab | Commit edit and move right |
Escape | Cancel edit, restore original value |
Arrow Keys | Navigate between cells (when not editing) |
Examples
Section titled “Examples”Basic editing with double-click trigger
Section titled “Basic editing with double-click trigger”grid.gridConfig = { columns: [ { field: 'name', editable: true }, { field: 'price', type: 'number', editable: true }, { field: 'active', type: 'boolean', editable: true }, ], plugins: [new EditingPlugin({ editOn: 'dblclick' })],};
grid.on('cell-commit', ({ field, oldValue, newValue }) => { console.log(`${field}: ${oldValue} → ${newValue}`);});Custom editor function
Section titled “Custom editor function”columns: [ { field: 'status', editable: true, editor: (ctx) => { const select = document.createElement('select'); ['pending', 'active', 'completed'].forEach(opt => { const option = document.createElement('option'); option.value = opt; option.textContent = opt; option.selected = ctx.value === opt; select.appendChild(option); }); select.addEventListener('change', () => ctx.commit(select.value)); return select; }, },]See Also
Section titled “See Also”EditingConfigfor configuration optionsEditorContextfor custom editor context- Live Demos for interactive examples
Extends BaseGridPlugin
Inherited methods like
attach(),detach(),afterRender(), etc. are documented in the base class.
Events
Section titled “Events”| Event | Description | Triggered By |
|---|---|---|
changed-rows-reset | Emitted when tracking is reset (unless silent) | resetChangedRows() |
cell-commit | Emitted when the cell value is committed (on blur or Enter) | beginCellEdit(), beginBulkEdit() |
row-commit | Emitted after the row edit is committed | beginBulkEdit(), commitActiveRowEdit() |
Accessors
Section titled “Accessors”changedRows
Section titled “changedRows”Get all rows that have been modified. Uses ID-based lookup for stability when rows are reordered.
readonly changedRows: T[]changedRowIds
Section titled “changedRowIds”Get IDs of all modified rows.
readonly changedRowIds: string[]activeEditRow
Section titled “activeEditRow”Get the currently active edit row index, or -1 if not editing.
readonly activeEditRow: numberactiveEditCol
Section titled “activeEditCol”Get the currently active edit column index, or -1 if not editing.
readonly activeEditCol: numberWhether any row in the grid is dirty.
readonly dirty: booleanpristine
Section titled “pristine”Whether all rows are pristine.
readonly pristine: booleandirtyRowIds
Section titled “dirtyRowIds”Get IDs of all dirty rows.
readonly dirtyRowIds: string[]Methods
Section titled “Methods”isRowEditing()
Section titled “isRowEditing()”Check if a specific row is currently being edited.
isRowEditing(rowIndex: number): booleanParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowIndex | number |
isCellEditing()
Section titled “isCellEditing()”Check if a specific cell is currently being edited.
isCellEditing(rowIndex: number, colIndex: number): booleanParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowIndex | number | |
colIndex | number |
isRowChanged()
Section titled “isRowChanged()”Check if a specific row has been modified.
isRowChanged(rowIndex: number): booleanParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowIndex | number | Row index to check (will be converted to ID internally) |
isRowChangedById()
Section titled “isRowChangedById()”Check if a row with the given ID has been modified.
isRowChangedById(rowId: string): booleanParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowId | string | Row ID to check |
isDirty()
Section titled “isDirty()”Check if a row differs from its baseline. Requires dirtyTracking: true.
isDirty(rowId: string): booleanParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowId | string |
isPristine()
Section titled “isPristine()”Inverse of isDirty.
isPristine(rowId: string): booleanParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowId | string |
markAsPristine()
Section titled “markAsPristine()”Re-snapshot baseline from current data (call after a successful save).
markAsPristine(rowId: string): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowId | string |
markAsNew()
Section titled “markAsNew()”Mark a row as new (auto-called by insertRow() when dirty tracking is on).
markAsNew(rowId: string): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowId | string |
markAsDirty()
Section titled “markAsDirty()”Mark a row as dirty after an external mutation that bypassed the editing pipeline.
markAsDirty(rowId: string): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowId | string |
markAllPristine()
Section titled “markAllPristine()”Mark all tracked rows as pristine (call after a batch save).
markAllPristine(): voidgetOriginalRow()
Section titled “getOriginalRow()”Get a deep clone of the original (baseline) row data. Returns undefined for new rows.
getOriginalRow(rowId: string): T | undefinedParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowId | string |
hasBaseline()
Section titled “hasBaseline()”Lightweight check for whether a baseline exists (no cloning).
hasBaseline(rowId: string): booleanParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowId | string |
getDirtyRows()
Section titled “getDirtyRows()”Get all dirty rows with their original and current data.
getDirtyRows(): DirtyRowEntry<T>[]revertRow()
Section titled “revertRow()”Revert a row to its baseline values (mutates the current row in-place). Triggers a re-render.
revertRow(rowId: string): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowId | string | Row ID (from getRowId) |
revertAll()
Section titled “revertAll()”Revert all dirty rows to their baseline values and re-render.
revertAll(): voidsetInvalid()
Section titled “setInvalid()”Mark a cell as invalid with an optional validation message.
Invalid cells are marked with a data-invalid attribute for styling.
setInvalid(rowId: string, field: string, message: string): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowId | string | The row ID (from getRowId) |
field | string | The field name |
message | string | Optional validation message (for tooltips or display) |
Example
Section titled “Example”// In cell-commit handler:grid.on('cell-commit', (detail, e) => { if (detail.field === 'email' && !isValidEmail(detail.value)) { detail.setInvalid('Invalid email format'); }});
// Or programmatically:editingPlugin.setInvalid('row-123', 'email', 'Invalid email format');clearInvalid()
Section titled “clearInvalid()”Clear the invalid state for a specific cell.
clearInvalid(rowId: string, field: string): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowId | string | |
field | string |
clearRowInvalid()
Section titled “clearRowInvalid()”Clear all invalid cells for a specific row.
clearRowInvalid(rowId: string): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowId | string |
clearAllInvalid()
Section titled “clearAllInvalid()”Clear all invalid cell states across all rows.
clearAllInvalid(): voidisCellInvalid()
Section titled “isCellInvalid()”Check if a specific cell is marked as invalid.
isCellInvalid(rowId: string, field: string): booleanParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowId | string | |
field | string |
getInvalidMessage()
Section titled “getInvalidMessage()”Get the validation message for an invalid cell.
getInvalidMessage(rowId: string, field: string): string | undefinedParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowId | string | |
field | string |
hasInvalidCells()
Section titled “hasInvalidCells()”Check if a row has any invalid cells.
hasInvalidCells(rowId: string): booleanParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowId | string |
getInvalidFields()
Section titled “getInvalidFields()”Get all invalid fields for a row.
getInvalidFields(rowId: string): Map<string, string>Parameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowId | string |
resetChangedRows()
Section titled “resetChangedRows()”Reset all change tracking.
resetChangedRows(silent: boolean): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
silent | boolean | If true, suppresses the changed-rows-reset event |
Events
Section titled “Events”| Event | Description |
|---|---|
changed-rows-reset | Emitted when tracking is reset (unless silent) |
beginCellEdit()
Section titled “beginCellEdit()”Programmatically begin editing a cell.
beginCellEdit(rowIndex: number, field: string): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowIndex | number | Index of the row to edit |
field | string | Field name of the column to edit |
Events
Section titled “Events”| Event | Description |
|---|---|
cell-commit | Emitted when the cell value is committed (on blur or Enter) |
beginBulkEdit()
Section titled “beginBulkEdit()”Programmatically begin editing all editable cells in a row.
beginBulkEdit(rowIndex: number): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowIndex | number | Index of the row to edit |
Events
Section titled “Events”| Event | Description |
|---|---|
cell-commit | Emitted for each cell value that is committed |
row-commit | Emitted when focus leaves the row |
commitActiveRowEdit()
Section titled “commitActiveRowEdit()”Commit the currently active row edit.
commitActiveRowEdit(): voidEvents
Section titled “Events”| Event | Description |
|---|---|
row-commit | Emitted after the row edit is committed |
cancelActiveRowEdit()
Section titled “cancelActiveRowEdit()”Cancel the currently active row edit.
cancelActiveRowEdit(): void