Cell Editing and EditorLock
SleekGrid supports inline cell editing. A column can specify an editor (via the editor property), and when the user activates a cell, the grid creates the editor, lets the user change the value, and commits it back to the row item.
StartSharp only: If you are using the StartSharp template, you don't need to wire up inline editing manually. The
GridEditControllerin@serenity-is/pro.extensions(Pro.Extensions) facilitates inline editing with more and automatic features on top of the base SleekGrid editing described on this page — such as inline add/edit/delete rows, auto-save, validation, undo, and an actions column. See Grid Edit Controller. The rest of this page documents the underlying SleekGrid editing mechanism thatGridEditControllerbuilds on.
Enabling Cell Editing
Cell editing is controlled by grid options. To enable it, set editable: true in the grid options and assign editors to columns:
protected override getSlickOptions() {
const opt = super.getSlickOptions();
opt.editable = true;
opt.enableCellNavigation = true;
return opt;
}
A column's editor is set through its editor property (an EditorClass):
column.editor = TextCellEdit;
The Editor Contract
Every cell editor implements the Editor interface:
interface Editor {
destroy(): void;
applyValue(item: any, value: any): void;
focus(): void;
isValueChanged(): boolean;
loadValue(item: any): void;
serializeValue(): any;
validate(): ValidationResult;
}
| Method | Purpose |
|---|---|
loadValue(item) |
Loads the item's field value into the editor. |
serializeValue() |
Reads the current editor value for commit. |
applyValue(item, value) |
Writes the serialized value back to the item. |
validate() |
Validates the current value; returns { valid, msg }. |
isValueChanged() |
Whether the value differs from the loaded default. |
focus() |
Focuses the editor's input. |
destroy() |
Tears down the editor's DOM and listeners. |
Built-in Cell Editors
SleekGrid ships these editors:
| Editor | Description |
|---|---|
| TextCellEdit | Single-line text input. |
| IntegerCellEdit | Integer input. |
| FloatCellEdit | Decimal input with fixed precision. |
| DateCellEdit | Date picker. |
| YesNoSelectCellEdit | Yes/No dropdown. |
| CheckboxCellEdit | Checkbox. |
| PercentCompleteCellEdit | Percent slider with quick buttons. |
| LongTextCellEdit | Detached textarea overlay for long text. |
The Edit Flow
- The user activates a cell (click or keyboard navigation).
- The grid fires
onBeforeEditCell; if a handler cancels, editing is skipped. - The grid creates the editor via the column's
editorfactory and callsloadValue(item). - The user edits the value.
- On commit (Enter, tab, or clicking another cell), the grid calls
serializeValue(), thenvalidate(). - If valid,
applyValue(item, value)writes the value back, andonCellChangefires. - If invalid,
onValidationErrorfires and the edit is not committed.
EditorLock
EditorLock ensures only one edit is active at a time. It prevents concurrent edits and validation races — the grid queries the lock before navigating, sorting, or scrolling while an edit is open.
The grid uses the global GlobalEditorLock by default. You can access it via grid.getEditorLock().
Key methods:
| Method | Purpose |
|---|---|
isActive(controller?) |
Whether an edit controller holds the lock. |
activate(controller) |
Acquires the lock (throws if another is active). |
deactivate(controller) |
Releases the lock. |
commitCurrentEdit() |
Commits the active edit (returns false if validation failed). |
cancelCurrentEdit() |
Cancels the active edit. |
Committing and Cancelling from the Grid
The grid exposes editing methods:
editActiveCell(editor?)— starts editing the active cell with the given (or column's) editor.commitCurrentEdit()— commits the current edit.cancelCurrentEdit()— cancels the current edit.
Custom Cell Editors
A custom cell editor implements the Editor contract. The simplest approach is to extend BaseCellEdit (from the SleekGrid source) or implement Editor directly:
import { Editor, EditorOptions, ValidationResult } from "@serenity-is/sleekgrid";
export class MyCellEdit implements Editor {
private input: HTMLInputElement;
constructor(private args: EditorOptions) {
this.input = this.args.container.appendChild(
<input type="text" class="editor-text" /> as HTMLInputElement
);
this.input.focus();
}
destroy() { this.input.remove(); }
focus() { this.input.focus(); }
loadValue(item: any) { this.input.value = item[this.args.column.field] ?? ""; }
serializeValue() { return this.input.value; }
applyValue(item: any, value: any) { item[this.args.column.field] = value; }
isValueChanged() { return this.input.value !== this.args.item[this.args.column.field]; }
validate(): ValidationResult { return { valid: true }; }
}
See Also
- Editor (API reference) — the editor contract.
- EditorLock (API reference) — the edit lock.
- EditorOptions (API reference) — editor construction options.
- ValidationResult (API reference) — validation result.
- SleekGrid (API reference) — the grid's editing methods.
- DataGrid Architecture — how SleekGrid fits into the grid stack.
- Frontend Framework Overview — the three client-side packages and how they fit together.