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

### Enabling Batch Editing
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](/content/angular-data-grid/row-models/index.html).

### Batch Editing Lifecycle
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:

| Event | Description |
| --- | --- |
| batchEditingStarted | 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. |
| batchEditingStopped | Batch editing has stopped (when batch editing is enabled). Contains a list of edits if the batch was committed via `api.commitBatchEdit()`. |

### Pending Values
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
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.

### Example getDataValue()
```js
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)
api.commitBatchEdit(); // Commit Batch
rowNode.getDataValue('price'); // 99 (now committed)
```

### Example getCellValue()
```js
api.startBatchEdit(); // Start Batch
api.startEditingCell({ rowIndex: 0, colKey: 'price' }); // Open editor
api.getCellValue({ rowNode, colKey: 'price', from: 'edit' }); // live editor value
```

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

| `eventSource` | Active Editor | Pending Batch | Committed Data |
| --- | --- | --- | --- |
| (default) | Closed | Written | Written if no batch |
| 'edit' | Written | Written if no editor | Written if no editor, no batch |
| 'batch' | Left open | Written | Written if no batch |
| 'data' | Left open | — | Always written |

```js
api.startBatchEdit(); // Start Batch
rowNode.setDataValue('price', 99, 'batch'); // Update price
```

### Undo / Redo
When [Undo / Redo](/content/angular-data-grid/undo-redo-edits/index.html) 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
In [Full Row](/content/angular-data-grid/cell-editing-full-row/index.html) 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
#### Custom Renderers & Editors
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
Pending edit styles can be overridden using CSS, via the `.ag-cell-batch-edit` and `.ag-row-batch-edit` classes.
```scss
.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);
}
```

## API
| Function | Description |
| --- | --- |
| startBatchEdit | 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. |
| commitBatchEdit | Commits all pending batch edits to the row data and ends the batch editing session. |
| cancelBatchEdit | Cancels all pending batch edits, reverting cells to their original values, and ends the batch editing session. |
| isBatchEditing | Returns `true` if a batch editing session is currently active. |
