Undo/Redo Management: Automatically tracks user changes with the ability to undo/redo actions using keyboard shortcuts.
Configurable Stack Size: Tracks up to 200 changes by default, and accepts partial history config when you only need to override one option.
Provider Persistence: Can load and save stack state through local cache and custom server providers for same-dataset sessions.
Custom Event Hooks: Supports custom behavior via beforeundo and beforeredo events, allowing full control over the undo/redo process.
Pro Editing Coverage: Tracks regular cell edits, Pro editor templates, textarea editors, range edits, clipboard paste, autofill, row-edit saves, and audit restore replays. HistoryPlugin installs its Event Manager dependency automatically.
Context-menu Transactions: Tracks each built-in Cut, Paste, Clear, row mutation, or column-schema mutation as one chronological undo/redo action. Copy remains non-mutating and is not recorded.
Register HistoryPlugin to enable undo/redo. It automatically installs
EventManagerPlugin when an Event Manager instance is not already present, so
normal edit events enter the undo stack without a second undocumented plugin.
1
import {
2
HistoryPlugin,
3
createLocalStorageHistoryAdapter,
4
} from'@revolist/revogrid-pro';
5
6
plugins = [HistoryPlugin];
Undo, redo, and public replay operations emit beforehistedit. The Event
Manager installed by History handles that event and emits the normal gridedit
flow. If your application already registers EventManagerPlugin, History
reuses that instance rather than creating a duplicate.
AuditHistoryPlugin automatically reuses or installs HistoryPlugin for restore replay, keyboard shortcuts, and existing History integrations. Keep History configuration on grid.history; Audit History does not define a nested History config.
When HistoryPlugin and DataGridContextMenuPlugin are installed together,
each built-in mutating command is atomic: a multi-cell Cut, Paste, cell Clear,
or row Clear creates one history entry, and undo restores all affected cells in
reverse edit order. Redo reapplies them in forward order.
History also snapshots the affected authored structure for these commands:
Rows: insert above/below, duplicate, delete, pin top/bottom, and unpin.
Plain Copy and Copy with headers do not create entries because they do not
mutate the grid. A commandHandlers override is application-owned and is also
excluded: if a custom handler changes remote or application state, record and
restore that state in the application instead. Canceled, unavailable, and no-op
commands leave both stacks unchanged.
In-memory structural entries retain row object identity, nested column groups,
renderers, editors, and other function-valued column fields. Persisted entries
should use serializable row and column definitions; storage formats such as
JSON cannot restore functions. Context-menu replay temporarily bypasses
clearOnSourceChange only for its own row-source replacements. Unrelated
application source replacements continue to use the configured clearing policy.
grid.history is optional. Add it only when you need custom stacks, a smaller
or larger stack limit, or an initially disabled plugin.
Undo and redo stacks are index-based, so persisted history is safe only when the user returns to the same dataset, row order, and compatible column schema. Structural context-menu entries additionally require serializable row and column definitions. For long-term recovery across changing data, use AuditHistoryPlugin, which restores by stable row identity.
Use sourceId to reject stale server states. With multiple providers, the plugin loads the first provider immediately, then applies later providers only when their updatedAt state is newer and their sourceId is compatible.
When storage is configured, clearOnSourceChange defaults to false so the initial data load does not erase the restored stack. Set it to true only when your app wants every source replacement to clear persisted undo/redo state.
For custom controls, listen to historychanged instead of reading plugin
internals. The event detail includes undoStackSize, redoStackSize,
canUndo, canRedo, and disabled.
When HistoryPlugin and RowOrderPlugin are installed together, every
successful row drop is one undo/redo action by default. This includes selected
row blocks and grouped drops that update group fields.
1
grid.history = {
2
rowOrderHistory:'track', // default
3
};
Use rowOrderHistory: 'clear' to discard existing history after a committed
drop, or rowOrderHistory: 'preserve' when another integration records a richer
domain snapshot. Gantt uses preserve and records canonical tasks and
dependencies together.
Undo/redo does not record changes: ensure HistoryPlugin is present in the
grid’s plugins array. Event Manager setup and keyboard shortcuts are
automatic.
Restore flashes are missing in Audit History: install EventManagerPlugin and CellFlashPlugin; Audit restore replay flows through beforehistedit and the normal edit event path.
Calling plugin methods does not work: call getPlugins() first, then find
HistoryPlugin.
History clears after sort, filter, or source replacement: this is intentional
because those operations can change visible row indexes. Successful row
reorders are tracked unless rowOrderHistory is clear or preserve.
Persisted history was skipped: check the historyerror event for a
storage-source-mismatch phase and update the configured sourceId.
Need a known-good reference: see code in:
revogrid-pro/src/components/history/**.**.
The plugin listens to edit events (onEditEvent) and tracks changes in undo and redo stacks. Keyboard shortcuts like Ctrl+Z for undo and Ctrl+Y (or Ctrl+Shift+Z) for redo are supported out of the box. You can customize its behavior by using the BEFORE_UNDO_EVENT and BEFORE_REDO_EVENT hooks.
Here’s a quick snippet showing how the plugin processes undo actions:
replayChange() emits beforehistedit first. If no integration handles that event, History falls back to providers.data.setRangeData(...).
Try it Out!
Add the History Plugin to your RevoGrid instance and experience seamless undo/redo functionality. This plugin is especially useful in applications that handle complex data operations, ensuring users can easily revert or reapply changes as needed.