Home/Editing/Global Undo / Redo
Editing

Global Undo / Redo

One keystroke undoes any grid action — sort, filter, quick search, column resize/reorder/hide — not just cell edits, all on a single history. Ctrl+Z to step back, Ctrl+Y to step forward.

…or press Ctrl+Z / Ctrl+Y
Name
Department
City
Role
Salary
Amira Hassan
Engineering
Cairo
Lead
$42,000
Omar Nabil
Design
Remote
Senior
$43,700
Lena Rashid
Sales
London
Mid
$45,400
Yusuf Zaki
Marketing
Tokyo
Junior
$47,100
Nadia Farouk
Support
Austin
Manager
$48,800
Karim Salem
Finance
Berlin
Lead
$50,500
Sara Fahmy
Engineering
Cairo
Senior
$52,200
Hana Khaled
Design
Remote
Mid
$53,900
Tarek Aziz
Sales
London
Junior
$55,600
Maya Mansour
Marketing
Tokyo
Manager
$57,300
Amira Hassan
Support
Austin
Lead
$59,000
Omar Nabil
Finance
Berlin
Senior
$60,700
Lena Rashid
Engineering
Cairo
Mid
$62,400
Yusuf Zaki
Design
Remote
Junior
$64,100
Nadia Farouk
Sales
London
Manager
$65,800
Karim Salem
Marketing
Tokyo
Lead
$67,500
Sara Fahmy
Support
Austin
Senior
$69,200
Hana Khaled
Finance
Berlin
Mid
$70,900
Tarek Aziz
Engineering
Cairo
Junior
$72,600
Maya Mansour
Design
Remote
Manager
$74,300
Amira Hassan
Sales
London
Lead
$76,000
Omar Nabil
Marketing
Tokyo
Senior
$77,700
Lena Rashid
Support
Austin
Mid
$79,400
Yusuf Zaki
Finance
Berlin
Junior
$81,100
Nadia Farouk
Engineering
Cairo
Manager
$82,800
Karim Salem
Design
Remote
Lead
$84,500
All records loaded
40 / 40 records

One history for every action — not just edits

Set config.undoRedo: true and Ctrl+Z walks back the things you actually did to the grid: a sort you didn't mean to click, a filter you spent a minute building, a column dragged to the wrong place. Ctrl+Y (or Ctrl+Shift+Z) replays them. Sorting, filtering, quick search and column resize/reorder/hide all share one ordered timeline, so undo follows your real sequence instead of two separate stacks.

Try it

Sort a column, type in the search box, drag a column header, resize one — then press Ctrl+Z a few times and watch each change peel back in order. The Undo / Redo buttons above the grid do the same thing.

Build your own buttons

There are no built-in toolbar buttons — instead the grid exposes everything you need to render your own, so they match your app. Bind to the canUndo() / canRedo() signals for the disabled state and call undo() / redo() on click:

<button (click)="grid.undo()" [disabled]="!grid.canUndo()">Undo</button>
<button (click)="grid.redo()" [disabled]="!grid.canRedo()">Redo</button>

<gridcraft #grid [columns]="columns" [dataSource]="ds" [config]="{ undoRedo: true }" />

On a touch device those buttons are how people reach undo — there is no keyboard, so render controls if your users are on tablets or phones.

It respects a cell editor

While you're typing in a cell, Ctrl+Z undoes your text, not the grid — the editor keeps its own undo. The grid's history only takes over once the editor is closed. And undo is scoped to the grid you're working in: two grids on one page don't undo each other.

Off by default

Grid-operation undo is opt-in — set undoRedo: true to turn it on. Existing cell-edit undo is unaffected: it keeps working with or without this flag.

Cap the depth or narrow the scope

Pass an object instead of true:

readonly config: GridConfig<Person> = {
  undoRedo: {
    depth: 20,                       // keep the last 20 steps (default 50)
    operations: ['sort', 'filter'],  // record only these (default: all)
  },
};

Client vs server. With rows in memory (filterApplyMode: 'client', as here) undo reverts instantly. With a server data source, undoing a sort or filter re-runs the fetch that restores the earlier view — the same request a fresh sort would make.

Live updates. If a streamed update changes a row that an earlier edit would restore, that step is dropped from the history rather than writing a stale value over newer data — and the change is announced, never silent.

Undo / redo API

PropertyTypeDefaultDescription
config.undoRedoboolean | UndoRedoConfigfalseEnable undo/redo for grid operations (sort, filter, quick filter, column changes, grouping, row move). true for defaults, or an object to configure. Cell-edit undo is unaffected by this flag.
undoRedo.depthnumber50Maximum number of steps kept; the oldest are dropped past this.
undoRedo.operationsGcUndoableOp[]allRestrict which operation kinds are recorded. Cell edits are always recorded regardless.
grid.canUndo()Signal<boolean>—True when there is a step to undo — bind it to a custom button’s disabled state.
grid.canRedo()Signal<boolean>—True when there is a step to redo.
grid.nextUndoOp()Signal<GcUndoableOp | null>—The kind of operation the next undo would reverse — for labelling a button.
grid.undo()() => void—Reverse the most recent recorded operation.
grid.redo()() => void—Re-apply the most recently undone operation.
grid.clearHistory()() => void—Drop all recorded steps.