Undo redo in EJ2 TypeScript Spreadsheet control

4 Jul 20247 minutes to read

Undo option helps you to undone the last action performed and Redo option helps you to do the same action which is reverted in the Spreadsheet. You can use the allowUndoRedo property to enable or disable undo redo functionality in spreadsheet.

  • The default value for allowUndoRedo property is true.

By default, the UndoRedo module is injected internally into Spreadsheet to perform undo redo.


It reverses the last action you performed with Spreadsheet. Undo can be done by any of the following ways:

  • Select the undo item from HOME tab in Ribbon toolbar.
  • Use Ctrl + Z keyboard shortcut to perform the undo.
  • Use the undo method programmatically.


It reverses the last undo action you performed with Spreadsheet. Redo can be done by any of the following ways:

  • Select the redo item from HOME tab in Ribbon toolbar.
  • Use Ctrl + Y keyboard shortcut to perform the redo.
  • Use the redo method programmatically.

Update custom actions in UndoRedo collection

You can update your own custom actions in UndoRedo collection, by using the updateUndoRedoCollection method. And also customize the undo redo operations of your custom action by using actionComplete event.

The following code example shows How to update and customize your own actions for undo redo functionality in the Spreadsheet control.

import { Spreadsheet, getRangeIndexes, ColumnModel } from '@syncfusion/ej2-spreadsheet';
import { defaultData } from './datasource.ts';
import { enableRipple, addClass, removeClass } from '@syncfusion/ej2-base';

let columns: ColumnModel[] = [
        width: 130
        width: 92
        width: 96

let spreadsheet: Spreadsheet = new Spreadsheet({
    sheets: [{ ranges: [{ dataSource: defaultData }], columns: columns }],
    actionComplete: (args): void => {
        let actionEvents: any = args;
        if (actionEvents.eventArgs.action == "customCSS") {
            let Element:HTMLElement = spreadsheet.getCell(actionEvents.eventArgs.rowIdx,actionEvents.eventArgs.colIdx);
            if (actionEvents.eventArgs.requestType == "undo") {
                removeClass([Element],'customClass'); // To remove the custom class in undo action
            else {
                addClass([Element],'customClass');// To add the custom class in redo action

//Render the initialized Spreadsheet
document.getElementById("customBtn").addEventListener('click', updateCollection);

function updateCollection() {
    let cell: string = spreadsheet.getActiveSheet().activeCell;
    let cellIdx: number[] = getRangeIndexes(cell);
    let Element: HTMLElement = spreadsheet.getCell(cellIdx[0], cellIdx[1]);
    if (!Element.classList.contains("customClass")) {
        addClass([Element], 'customClass'); // To add the custom class in active cell element
        spreadsheet.updateUndoRedoCollection({ eventArgs: { class: 'customClass', rowIdx: cellIdx[0], colIdx: cellIdx[1], action: 'customCSS' } }); // To update the undo redo collection
<!DOCTYPE html>
<html lang="en">

        <title>EJ2 SpreadSheet</title>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta name="description" content="Typescript UI Controls" />
        <meta name="author" content="Syncfusion" />
        <link rel="shortcut icon" href="resources/favicon.ico" />
        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
        <link href="https://cdn.syncfusion.com/ej2/26.2.4/ej2-base/styles/material.css" rel="stylesheet" />
        <link href="https://cdn.syncfusion.com/ej2/26.2.4/ej2-inputs/styles/material.css" rel="stylesheet" />
        <link href="https://cdn.syncfusion.com/ej2/26.2.4/ej2-buttons/styles/material.css" rel="stylesheet" />
        <link href="https://cdn.syncfusion.com/ej2/26.2.4/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
        <link href="https://cdn.syncfusion.com/ej2/26.2.4/ej2-lists/styles/material.css" rel="stylesheet" />
        <link href="https://cdn.syncfusion.com/ej2/26.2.4/ej2-navigations/styles/material.css" rel="stylesheet" />
        <link href="https://cdn.syncfusion.com/ej2/26.2.4/ej2-popups/styles/material.css" rel="stylesheet" />
        <link href="https://cdn.syncfusion.com/ej2/26.2.4/ej2-dropdowns/styles/material.css" rel="stylesheet" />
        <link href="https://cdn.syncfusion.com/ej2/26.2.4/ej2-grids/styles/material.css" rel="stylesheet" />
        <link href="https://cdn.syncfusion.com/ej2/26.2.4/ej2-spreadsheet/styles/material.css" rel="stylesheet" />
        <link href="styles.css" rel="stylesheet" />
        <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.4.1/shim.min.js"></script>
        <script src="system.config.js"></script>
        <script src="es5-datasource.js" type="text/javascript"></script>
                .customClass.e-cell {
                        background-color: red;
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>

        <!--Element which is going to render-->
        <button id="customBtn" class="e-btn"> add/remove Class</button>
        <div id='loader'>Loading....</div>
       <div id='container'>
       <div id="spreadsheet"></div>


See Also