Batch / Bulk Editing
Apply one value to many rows at once — through the same validated commit path as a single edit, as one undoable action. Drive it from the applyToSelectedRows API or with a spreadsheet-style Ctrl/Cmd+Enter while editing.
Apply one value to the selection
Tick a few rows, choose a column and a value, and press Apply. One call — grid.applyToSelectedRows(colKey, value) — writes every selected row and returns { committed, skipped }. Wire it to any toolbar, bulk-action menu or shortcut you like.
applyToSelectedRows(colKey, value) returns
{ committed, skipped } — the numbers, not a boolean, because a mixed selection is the
normal case. With no selection it is a no-op returning { committed: 0, skipped: 0 }
rather than throwing, so a toolbar button needs no guard of its own.
Per-row (cellEditCommit) is suppressed inside a batch. One
(batchEditCommit) carries rowIds, so the server sees one request instead of
N — which is the point of a bulk action.
Ctrl/Cmd+Enter fills the selection
The spreadsheet gesture, and the same code path underneath. Select rows, start editing a cell in one of them, pick a value, then press Ctrl (or Cmd) + Enter instead of Enter — every selected row takes it. No wiring needed: config.batchEdit turns the modifier on.
There is one code path. The modifier and the API raise the same
(batchEditCommit) and write through the same commit gate; the gesture is only a second
way to reach it.
config.batchEdit: false removes the modifier and leaves the API working — useful when
Ctrl+Enter already means something in your app. Plain Enter always commits just the one
cell, so nothing is filled by accident.
One batch, one undo step
A batch of any size is a single entry in the history, so one Ctrl+Z takes all of it back — not one row per press. That is the difference between a bulk action and a loop that happens to call commit N times.
The history records the batch as one compound entry, so undo and redo move over the whole set. A loop calling commit per row would record N entries and leave the reader pressing Ctrl+Z ten times — with a half-reverted table at every step in between.
Undo here is the grid's ordinary edit history: Ctrl+Z works without
config.undoRedo, which is about widening the history to sorts, filters and column
moves — a different question.
Validation runs per row, inside the batch
Salary declares validate: { min: 0 }. Push a negative value across the whole selection and the rule refuses those rows individually — the batch is neither all-or-nothing nor unchecked. Switch to allow mode and the same rows commit, but stay marked.
The rule is declared once on the column and runs at the commit gate, so a single inline edit and a thousand-row batch pass exactly the same check. Nothing about the batch path is special-cased, which is why this claim is worth stating: bulk operations are where validation is usually skipped.
The check is per row. In block mode a failing row is left exactly as
it was and counted in skipped, while its valid neighbours in the same selection still
commit — the batch is neither all-or-nothing nor unchecked. In allow mode every row
commits and the failing ones stay marked until a valid value replaces them.
Client-side rules are a courtesy, not a boundary. Persist from
(batchEditCommit) and revalidate on the server before writing — a bulk endpoint is
exactly where one bad row is most expensive.
Why this is one action and not many
A bulk edit that loops over the selection calling commit per row gives you N history entries, N events for the server, and N chances to end up half-applied. Everything on this page is the other thing: one validated pass, one history entry, one event, one screen-reader announcement. A batch of any size lands as a single grid update and speaks once, never once per row.
Both routes in — the API and Ctrl/Cmd+Enter — are the same code path, and both are free. Row selection, which supplies the target set, is free too.
Batch Editing API
| Property | Type | Default | Description |
|---|---|---|---|
| applyToSelectedRows(colKey, value) | (string, any) => BatchEditResult | — | Apply value to colKey across all selected rows as one undoable batch. Returns { committed, skipped }. No selection → no-op. |
| (batchEditCommit) | BatchEditEvent | — | Fired once per batch: { colKey, value, rowIds, committed, skipped }. Per-row (cellEditCommit) is suppressed inside a batch. |
| config.batchEdit | boolean | true (with row selection) | Enables the Ctrl/Cmd+Enter in-editor shortcut. The API works regardless of this flag. |
| config.editValidation | 'block' | 'allow' | 'block' | block — invalid rows are skipped and counted. allow — invalid rows commit but stay marked. Checked per row, inside the batch. |
| config.rowSelection | RowSelectionConfig | — | The (free) selection is the batch target set. Multi-select the rows, then apply. |