Core Features

Advanced Features

Angular Data GridBatch Editing

Enterprise

Batch editing lets you queue edits across multiple cells or rows, then commit or discard them all at once.

Enabling Batch Editing Copy Link

  1. Start — call api.startBatchEdit() to start a batch edit.
  2. Edit — make one or more edits. Pending values are displayed in the grid but not written to the data.
  3. Commit or cancel — call api.commitBatchEdit() to apply all pending edits to the data. To discard the pending edits and revert the display to the original data values call api.cancelBatchEdit().

Batch editing is only available via the API and only compatible with the Client-Side Row Model.

Batch Editing Lifecycle Copy Link

Cell and row editing events (cellEditingStarted, cellEditingStopped, etc.) fire normally when editors open and close.

The key difference is that cellValueChanged and rowValueChanged are deferred — they only fire when commitBatchEdit() is called. If cancelBatchEdit() is called instead, pending values are discarded and no value-changed events fire.

Two batch-specific events are also available:

batchEditingStartedCopy Link
BatchEditingStartedEvent
Fired when the first edit is made after api.startBatchEdit() is called. This event fires lazily — not immediately on api.startBatchEdit(), but on the first cell value change or editor open within the batch session.
batchEditingStoppedCopy Link
BatchEditingStoppedEvent
Batch editing has stopped (when batch editing is enabled). Contains a list of edits if the batch was committed via api.commitBatchEdit().

Pending Values Copy Link

Edits made during a batch are stored as pending values — they are not applied to the data until committed.

  • Display features (cell rendering, copy/paste, fill handle) reflect pending values immediately.
  • Data features (sorting, filtering, grouping, aggregation) use committed data until the batch is committed.
  • Clipboard paste — pasted values during a batch are staged as pending edits rather than being written to data.
  • On cancel, all pending values are discarded and the grid reverts to the original data.

Reading Values Copy Link

There are two main APIs to read cell values but they differ in their default behaviour.

  • rowNode.getDataValue() — defaults to from: 'data' (ignores pending edits). Use for data-facing reads.
  • api.getCellValue() — defaults to from: 'edit' (shows pending edits). Use for UI-facing reads.

rowNode.getDataValue() Copy Link

getDataValueCopy Link
Function
Returns the data value from the rowNode for the specified column. By default, returns committed data ignoring any pending edits. For group rows, returns aggregated values or the group key. For formula cells, returns the computed result. To get the displayed value (with formatting and value formatter applied), use api.getCellValue() instead. In Pivot Mode, pivot columns on leaf rows resolve to their underlying value column. The from parameter controls value resolution.

The table below shows the impact of the from parameter on the value that is returned. The first non-empty source reading left-to-right is used. The Aggregation column only applies to group rows with an aggFunc.

fromActive Editor (if editing)Pending Batch (if batching)Aggregation (if present)Committed Data
'data' (default)Agg valueFallback
'edit'Used if presentUsed if no editorAgg valueFallback
'batch'Used if presentAgg valueFallback
'value'Scalar (unwrapped)Fallback
'data-raw'Always used

Aggregate Values

  • 'value' — same as 'data', but unwraps the aggregation result returned by avg and count to its scalar value.
  • 'data-raw' — same as 'data' but skips aggregation results (rowNode.aggData). For group rows the valueGetter or field value is returned instead, which is typically undefined since group rows do not hold leaf data.

Example getDataValue() Copy Link

                                             // 42 (original value)
api.startBatchEdit();                        // Start Batch

rowNode.setDataValue('price', 99, 'batch');  // Edit value to 99

rowNode.getDataValue('price')                // 42 (original data, default 'data')
rowNode.getDataValue('price', 'batch');      // 99 (pending value)
rowNode.getDataValue('price', 'edit');       // 99 (no editor open, same as 'batch')

api.commitBatchEdit();                       // Commit Batch

rowNode.getDataValue('price');               // 99 (now committed)
// Column 'revenue' uses aggFunc: 'avg' — average is 420 across 3 rows
groupRowNode.getDataValue('revenue');             // aggregation result object
groupRowNode.getDataValue('revenue', 'value');    // 420 (scalar)
groupRowNode.getDataValue('revenue', 'data-raw'); // undefined (skips aggData; group row has no raw field)

api.getCellValue() Copy Link

getCellValueCopy Link
Function
Gets the cell value for the given column and rowNode (row). Will return the cell value or the formatted value depending on the value of params.useFormatter.
fromActive EditorPending BatchAggregationCommitted Data
'edit' (default)Used if presentUsed if no editorAgg valueFallback
'batch'Used if presentAgg valueFallback
'data'Agg valueFallback

Example getCellValue() Copy Link

                                                              // 42 (original value)
api.startBatchEdit();                                         // Start Batch
api.startEditingCell({ rowIndex: 0, colKey: 'price' });       // Open editor

// getCellValue reads the live editor value
api.getCellValue({ rowNode, colKey: 'price', from: 'edit' }); // live editor value
api.getCellValue({ rowNode, colKey: 'price', from: 'data' }); // 42 (original data)

Writing Values Copy Link

rowNode.setDataValue() Copy Link

rowNode.setDataValue(colKey, newValue, eventSource?) writes a value programmatically. The eventSource parameter controls how.

eventSourceActive EditorPending BatchCommitted Data
(default)ClosedWrittenWritten if no batch
'edit'WrittenWritten if no editorWritten if no editor, no batch
'batch'Left openWrittenWritten if no batch
'data'Left openAlways written

With 'edit', the active editor receives the new value via refresh() if implemented; otherwise the editor is recreated with focus preserved.

api.startBatchEdit();                                         // Start Batch
api.startEditingCell({ rowIndex: 0, colKey: 'price' });       // Open editor

rowNode.setDataValue('price', 99, 'edit');                    // Update open editor without closing
api.getCellValue({ rowNode, colKey: 'price', from: 'edit' }); // 99 (live edit value)
rowNode.data.price;                                           // 42 (unchanged)

api.stopEditing();                                            // Close editor
api.commitBatchEdit();                                        // Commit Batch
rowNode.getDataValue('price');                                // 99 (committed)
api.startBatchEdit();                       // Start Batch
rowNode.setDataValue('price', 99, 'batch'); // Update price
rowNode.setDataValue('qty', 5, 'batch');    // Update qty

rowNode.getDataValue('price');              // 42 (committed data)
rowNode.getDataValue('price', 'batch');     // 99 (pending)

api.commitBatchEdit();                      // Commit Batch
rowNode.getDataValue('price');              // 99 (committed data)
api.startBatchEdit();                       // Start Batch
rowNode.setDataValue('price', 99, 'data');  // 'data' — bypass batch, write immediately
rowNode.data.price;                         // 99 (already committed)
api.cancelBatchEdit();                      // 'data' writes are permanent

Undo / Redo Copy Link

When Undo / Redo is enabled, a committed batch is treated as a single undo action. Calling undo after commitBatchEdit() reverts all changes from that batch at once — no extra API calls are needed.

If cancelBatchEdit() is called instead, the pending edits are discarded without touching the undo history. The undo stack remains unchanged, as though the batch never happened.

Full Row Batch Editing Copy Link

In Full Row Batch Editing, starting an edit in any cell opens all editors for the current row. When row editing is completed, only the changed cells are included in the pending batch edits.

Customisation Copy Link

Custom Renderers & Editors Copy Link

Implement refresh() in your custom cell renderers and editors to receive updated values during a batch. The params passed to refresh() include the latest pending value.

Styling Copy Link

Pending edit styles can be overridden using CSS, via the .ag-cell-batch-edit and .ag-row-batch-edit classes.

.ag-cell-batch-edit {
    background-color: var(--ag-cell-batch-edit-background-color);
    color: var(--ag-cell-batch-edit-text-color);
}

.ag-row-batch-edit {
    background-color: var(--ag-row-batch-edit-background-color);
    color: var(--ag-row-batch-edit-text-color);
}

The following example shows the custom batch styling:

  • A batch is started automatically via api.startBatchEdit()
  • Two rows have data updated via rowNode.setDataValue()
  • Note how the styles are removed when the batch is committed or reverted

API Copy Link

startBatchEditCopy Link
Function
Starts a batch editing session. While batch editing is active, cell edits are accumulated as pending values without being committed to the row data. The pending values are only written when commitBatchEdit() is called, or discarded when cancelBatchEdit() is called. Calling startBatchEdit() while a batch is already active is a no-op. Use isBatchEditing() to check whether a batch session is currently active. Any active cell editor is cancelled when the batch session starts. The batchEditingStarted event is fired lazily on the first actual cell edit within the batch session, not when startBatchEdit() is called. Only supported with the Client-Side Row Model.
commitBatchEditCopy Link
Function
Commits all pending batch edits to the row data and ends the batch editing session. Each accumulated pending value is written via rowNode.setDataValue(), and the batchEditingStopped event is fired with the committed edits. Calling commitBatchEdit() when no batch is active is a no-op. If no cells were edited during the batch session (i.e. batchEditingStarted was never fired), batchEditingStopped is not fired either. Only supported with the Client-Side Row Model.
cancelBatchEditCopy Link
Function
Cancels all pending batch edits, reverting cells to their original values, and ends the batch editing session. The batchEditingStopped event is fired with an empty edit map. Calling cancelBatchEdit() when no batch is active is a no-op. If no cells were edited during the batch session (i.e. batchEditingStarted was never fired), batchEditingStopped is not fired either. Only supported with the Client-Side Row Model.
isBatchEditingCopy Link
Function
Returns true if a batch editing session is currently active (i.e. startBatchEdit() has been called and neither commitBatchEdit() nor cancelBatchEdit() has been called yet).
getEditingCellsCopy Link
Function
getEditRowValuesCopy Link
Function