Home/Editing/Row Editing
Editing

Row Editing

Open every editable cell in a row at once and commit them as one change — one write for your API, one entry in the undo history, and one validation verdict for the whole row.

Edit a whole row

Double-click any cell: the row opens. Enter commits it, Escape discards it, Tab wraps inside it — and one Ctrl+Z takes the whole row back.

Guest
Room
Nights
Rate
Paid
Nadia Rashad
101
3
1200
Yes
Omar Fahmy
204
1
950
No
Leila Sabry
310
7
2100
Yes
Karim Adel
112
2
780
Yes
Mona Zaki
215
5
1500
No
Hany Salem
318
4
1350
Yes
Dalia Nour
120
10
2400
Yes
Tarek Amin
221
2
890
No
Rania Fouad
330
6
1750
Yes
Sami Gaber
140
1
640
Yes
All records loaded
10 / 10 records

One gesture, one change

Double-click any cell: every editable cell in that row opens at once, and the row is banded so you can see what you are about to save. Enter from any of them writes the whole row, Escape discards all of it, and Tab moves between the row's own cells and wraps at the end — it never leaves you with half a row open.

One undo, not five

Change the guest and the rate, press Enter, then press Ctrl+Z once: both cells go back. A row is one entry in the history, because it was one decision.

Validation is all-or-nothing

Nights accepts 1–30 and Guest is required. Put 99 in Nights, change the guest too, and press Enter: nothing is written, the row stays open, and the failing cell shows why. A half-written row is the surprise this mode exists to avoid — fix the cell and press Enter again.

Driven from your own buttons

Sort the grid first, then press Edit next unpaid — it still opens the booking it meant, because the API takes the row's id and not its position.

Last saved: —
Guest
Room
Nights
Rate
Paid
Nadia Rashad
101
3
1200
Yes
Omar Fahmy
204
1
950
No
Leila Sabry
310
7
2100
Yes
Karim Adel
112
2
780
Yes
Mona Zaki
215
5
1500
No
Hany Salem
318
4
1350
Yes
Dalia Nour
120
10
2400
Yes
Tarek Amin
221
2
890
No
Rania Fouad
330
6
1750
Yes
Sami Gaber
140
1
640
Yes
All records loaded
10 / 10 records

Editing from your own button — by identity

Sort the grid first, then press Edit next unpaid. It still opens the booking it meant, because startEditing() takes the row's id — the same key selection and keyboard focus use — not its position on screen.

grid.startEditing(booking.id);          // the whole row
grid.startEditing(booking.id, 'rate');  // just one cell, even in fullRow mode

Save and Cancel are your buttons

stopEditing(true) commits — atomically, so a refused row stays open with its message — and stopEditing(false) discards. Both return whether anything was open, and editingRowId() is a signal, so a Save button can be disabled from real state instead of a guess.

When to use it

Row editing suits records people change as a unit — a booking, an invoice line, a contact. The user opens the row, fixes what needs fixing, and commits once: one write for your API, one entry in the undo history, and one validation verdict for the whole row.

readonly config: GridConfig<Booking> = { editMode: 'fullRow', trackBy: 'id' };

What changes, and what does not

  • Your column definitions do not. The same editable, editor and validate rules drive the row's cells.
  • Your existing events keep firing. A committed row emits (cellEditCommit) for each changed cell and one (rowEditCommit) summary — switching a grid to row editing never leaves a listener silently dead.
  • Single-cell editing is still available from the API: startEditing(rowId, colKey) opens exactly that cell.

Keyboard

  • Enter — commit the row (from any of its cells).
  • Escape — discard the whole row.
  • Tab / Shift+Tab — move between the row's editable cells; wraps at the ends.
  • Ctrl+Z — one press takes the committed row back (needs undoRedo: true).

trackBy is required: sessions, undo entries and the imperative API are all keyed by row identity, which is what makes them survive sorting, filtering and scrolling.

Row editing options

PropertyTypeDefaultDescription
config.editMode'cell' | 'fullRow''cell''fullRow' opens every editable cell of a row together and commits them as one change. editTrigger still chooses click vs double-click.
(rowEditCommit)RowEditCommit<T>—Fires once per committed row, after that row's per-cell (cellEditCommit)s. Carries rowId, changes (only the cells that changed), oldRow and newRow.
startEditing(rowId, colKey?)(rowId, colKey?) => boolean—Open an editor by row identity. No colKey: the whole row in fullRow mode, otherwise the first editable cell. Returns false for an unknown row, a group row, or a row with no editable columns.
stopEditing(commit?)(commit?: boolean) => booleancommit = trueCommit (atomically, for a row) or discard the open session. Returns whether anything was open. A refused commit leaves the session open with its messages.
editingRowId()Signal<unknown | null>nullThe row open as a full-row session — drive your own Save/Cancel buttons from it.
editingCell()Signal<{ rowId, colKey } | null>nullThe single cell being edited. Null while a row session is open.
column.validateValidationRules—Unchanged by this mode, and applied per cell. In the default editValidation: 'block' a single failure refuses the WHOLE row. See Edit Validation.
--gc-row-editing-bg / --gc-row-editing-outlineCSS valueblue tint / blue outlineThe band on a row being edited. See Theming.