This section covers how to allow users to undo / redo their cell edits.
When Cell Editing is enabled in the grid, it is usually desirable to allow users to undo / redo any edits.
Users can change the contents of cells through the following grid features:
This Undo / Redo feature is designed to be a recovery mechanism for user editing mistakes. Performing data updates (except for cell edits), or grid operations that change the row / column order, e.g. sorting, filtering and grouping, will clear the undo / redo stacks.
Enabling Undo / Redo
The following undo / redo properties are provided in the grid options interface:
<ag-grid-angular
[undoRedoCellEditing]="undoRedoCellEditing"
[undoRedoCellEditingLimit]="undoRedoCellEditingLimit"
/* other grid options ... */ />
this.undoRedoCellEditing = true;
this.undoRedoCellEditingLimit = 20;
As shown in the snippet above, undo / redo is enabled through the undoRedoCellEditing
property.
The default number of undo / redo steps is 10
. To change this default the undoRedoCellEditingLimit
property can be used.
Undo / Redo Shortcuts
The following keyboard shortcuts are available when undo / redo is enabled:
- ^ Ctrl+Z / Command+Z: will undo the last cell edit(s).
- ^ Ctrl+Y / Command+Y: will redo the last undo.
Note that the grid needs focus for these shortcuts to have an effect.
Undo / Redo API
It is also possible to programmatically control undo / redo and check the number of currently available undo / redo actions. These API methods are listed below:
Reverts the last cell edit. |
Re-applies the most recently undone cell edit. |
Returns current number of available cell edit undo operations. |
Returns current number of available cell edit redo operations. |
Undo / Redo Events
The following events are relevant to undo / redo:
Value has changed after editing (this event will not fire if editing was cancelled, eg ESC was pressed) or
if cell value has changed as a result of cut, paste, cell clear (pressing Delete key),
fill handle, copy range down, undo and redo. |
Undo operation has started. |
Undo operation has ended. |
Redo operation has started. |
Redo operation has ended. |
For an undo / redo, the events will be fired as:
- One
undoStarted
/redoStarted
event. - Zero to many
cellValueChanged
events. - One
undoEnded
/redoEnded
event.
When there are no undo / redo operations to perform, the started and ended events will still fire. However, the ended event will have a value of false
for the operationPerformed
property (compared to true
when an operation was performed).
If the application is doing work each time it receives a cellValueChanged
event, you can use the undoStarted
/ redoStarted
and undoEnded
/ redoEnded
events to suspend the application's work and then do the work for all cells impacted by the undo / redo operation afterwards.
If Read Only Edit is enabled, undo / redo will not perform any operations. The started and ended events will still fire, which means that you can implement your own undo / redo by keeping track of the cellEditRequest
events.
Example: Undo / Redo
The example below has the following grid options enabled to demonstrate undo / redo:
<ag-grid-angular
[defaultColDef]="defaultColDef"
[cellSelection]="cellSelection"
[undoRedoCellEditing]="undoRedoCellEditing"
[undoRedoCellEditingLimit]="undoRedoCellEditingLimit"
/* other grid options ... */ />
this.defaultColDef = {
// makes all cells editable
editable: true,
// enables flashing to help see cell changes
enableCellChangeFlash: true,
};
// allows copy / paste using cell ranges
this.cellSelection = {
// enables the fill handle
handle: {
mode: 'fill',
}
};
// enables undo / redo
this.undoRedoCellEditing = true;
// restricts the number of undo / redo steps to 5
this.undoRedoCellEditingLimit = 5;
To see undo / redo in action, try the following:
- Cell Editing: click and edit some cell values.
- Fill Handle: drag the fill handle to change a range of cells.
- Copy / Paste: use ^ Ctrl+C / ^ Ctrl+V to copy and paste a range of cells.
- Undo Shortcut: use ^ Ctrl+Z to undo the cell edits.
- Redo Shortcut: use ^ Ctrl+Y to redo the undone cell edits.
- Undo API: use the 'Undo' button to invoke
gridApi.undoCellEditing()
. - Redo API: use the 'Redo' button to invoke
gridApi.redoCellEditing()
. - Undo / Redo Limit: only 5 actions are allowed as
undoRedoCellEditingLimit=5
.
Complex Objects
If your cell values contain complex objects, there are a few steps necessary for undo / redo to work.
For manual editing, a Value Parser is required to convert string values back into complex objects.
<ag-grid-angular
[columnDefs]="columnDefs"
/* other grid options ... */ />
this.columnDefs = [
{
field: 'a',
editable: true,
valueParser: params => {
// convert `params.newValue` string value into complex object
return {
actualValue: params.newValue,
anotherProperty: params.data.anotherProperty,
}
}
}
];
If a Value Getter is being used to create complex objects, a Value Setter must be used to update the data. colDef.equals
is also needed when Comparing Values to determine if the cell value has changed for rendering.
<ag-grid-angular
[columnDefs]="columnDefs"
/* other grid options ... */ />
this.columnDefs = [
{
field: 'a',
editable: true,
valueGetter: params => {
// create complex object from data
return {
actualValue: params.data[params.colDef.field],
anotherProperty: params.data.anotherProperty,
}
},
valueSetter: params => {
// update data from complex object
params.data[params.colDef.field] = params.newValue.actualValue
return true
},
equals: (valueA, valueB) => {
// compare complex objects
return valueA.actualValue === valueB.actualValue
}
}
];
Complex object cell values must be immutable. If the cell values are mutated, undo / redo will not be able to restore the original values. This means that the Value Parser must return a new complex object.
Using the Cell Data Type object
presets many of the grid features to allow complex objects to work without further configuration by leveraging the Value Formatter and Value Parser.
The following example demonstrates how to use complex objects with undo / redo.
- For column A:
- A Value Getter is used to create complex objects from the data.
- A Value Formatter is used to convert the complex objects into strings for rendering.
- A Value Setter is used to update the data from the complex objects (the inverse of the Value Getter).
- A Value Parser is used to convert the string values produced from cell editing into complex objects (the inverse of the Value Formatter).
- A Column Definition
equals
function is provided to compare the complex objects (without this the grid would use reference equality, but this won't work here as the Value Getter returns a new object each time).
- For column B:
- The column values are complex objects.
- A Value Formatter is used to convert the complex objects into strings for rendering.
- A Value Parser is used to convert the string values produced from cell editing into complex objects (the inverse of the Value Formatter).
- For all columns:
- The cell data type is set to
object
to allow other grid features to work, such as the fill handle, copy, paste, etc.
- The cell data type is set to
- Try the following actions:
- Cell Editing: click and edit some cell values.
- Fill Handle: drag the fill handle to change a range of cells.
- Copy / Paste: use ^ Ctrl+C / ^ Ctrl+V to copy and paste a range of cells.
- Undo Shortcut: use ^ Ctrl+Z to undo the cell edits.
- Redo Shortcut: use ^ Ctrl+Y to redo the undone cell edits.
- Undo API: use the 'Undo' button to invoke
gridApi.undoCellEditing()
. - Redo API: use the 'Redo' button to invoke
gridApi.redoCellEditing()
. - Undo / Redo Limit: only 5 actions are allowed as
undoRedoCellEditingLimit=5
.