Undo Manager

SpreadJS allows you to have better control over the undo/redo stack, including setting the maximum size of actions to record.

You can get the redoStack of SpreadJS using the getRedoStack method. You can get the undoStack of SpreadJS using the getUndoStack method. You can get or set the max size of the redoStack/undoStack using the maxSize method.
window.onload = function () { var spread = new GC.Spread.Sheets.Workbook(_getElementById('ss')); initSpread(spread); } function initSpread(spread) { spread.fromJSON(data[0]); var sheet = spread.getActiveSheet(); attachEvent(spread); executeCommand(spread); updateInfo(spread); } function attachEvent(spread) { var events = GC.Spread.Sheets.Events; spread.bind(events.ValueChanged, updateInfoHandle); spread.bind(events.ViewZoomed, updateInfoHandle); spread.bind(events.ColumnChanged, updateInfoHandle); spread.bind(events.ColumnWidthChanged, updateInfoHandle); spread.bind(events.RowChanged, updateInfoHandle); spread.bind(events.RowHeightChanged, updateInfoHandle); let setButton = _getElementById("gc-max-size-set"); let maxSizeDom = _getElementById("gc-max-size"); let redoButton = _getElementById("gc-redo-button"); let undoButton = _getElementById("gc-undo-button"); let undoManager = spread.undoManager(); setButton.addEventListener("click", () => { let value = Number(maxSizeDom.value); if (!isNaN(value)) { spread.undoManager().maxSize(value); } }) redoButton.addEventListener("click", () => { undoManager.redo(); updateInfo(spread); }) undoButton.addEventListener("click", () => { undoManager.undo(); updateInfo(spread); }) } function executeCommand(spread) { var commandManager = spread.commandManager(); let sheet = spread.getActiveSheet(); let sheetName = sheet.name(); spread.suspendPaint() commandManager.execute({ cmd: "resizeColumn", sheetName: sheetName, size: 70, rowHeader: false, columns: [{ firstCol: 0, lastCol: 5 }], }); commandManager.execute({ cmd: "editCell", sheetName: sheetName, row: 0, col: 0, newValue: "Edit Cell", autoFormat: true, }); commandManager.execute({ cmd: "resizeRow", sheetName: sheetName, rows: [{ firstRow: 0, lastRow: 5, }], size: 30, columnHeader: false, }) spread.undoManager().undo(); spread.resumePaint(); } function updateInfoHandle(sender, info) { var sheet = info.sheet; var spread = sheet.parent; updateInfo(spread); } function updateInfo(spread) { var undoManager = spread.undoManager(); setTimeout(() => { updateUndoInfo(undoManager); updateRedoInfo(undoManager); }, 0); } function updateUndoInfo(undoManager) { var undoStack = undoManager.getUndoStack(); var description = getDescription(undoStack); let undoContainer = _getElementById("gc-undo-stack-container"); undoContainer.value = description; } function updateRedoInfo(undoManager) { var redoStack = undoManager.getRedoStack(); let description = getDescription(redoStack); let redoContainer = _getElementById("gc-redo-stack-container"); redoContainer.value = description; } function getDescription(actionStack) { let description = ""; for (var i = 0; i < actionStack.length; i++) { description = description + (i + 1) + '.' + actionStack[i].cmd + "\r\n"; } return description; } function _getElementById(id) { return document.getElementById(id); }
<!doctype html> <html lang="en" style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <link rel="stylesheet" type="text/css" href="styles.css"> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="app.js" type="text/javascript"></script> <script src="data.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> </head> <body> <div class="sample-tutorial"> <!-- Workbook host element --> <div id="ss" class="sample-spreadsheets"></div> <div class="options-container"> <label>Make any changes such as editing text or resizing row and cols then undo or redo your actions using the below buttons.</label> <div class="option-row"> <input type="button" value="Redo" class="gc-stack-button" id="gc-redo-button"> <input type="button" value="Undo" class="gc-stack-button" id="gc-undo-button"> </div> <div class="gc-undo-stack-container option-row"> <label>The undoStack includes the following command:</label> <textarea type="text" class="gc-stack-list" id="gc-undo-stack-container" cols="30"></textarea> </div> <div class="gc-redo-stack-container option-row"> <label>The redoStack includes the following command:</label> <textarea type="text" class="gc-stack-list" id="gc-redo-stack-container" cols="30"></textarea> </div> <div class="option-row"> <label>Undo/Redo Stack Max Size</label> <input type="number" min="0" max="2147483647" id="gc-max-size" class="gc-max-size" value="10"> <input type="button" id="gc-max-size-set" value="set"> </div> </div> </div> </body> </html>
var data = [{ "version":"12.0.0", "tabStripRatio":0.6, "sheetCount":1, "sheets":{ "Sheet1":{ "name":"Sheet1", "rowCount":114, "columnCount":21, "activeRow":2, "activeCol":2, "data":{ "dataTable":{ "2":{ "2":{ "value":"Student", "style": { "foreColor" : "#FFFFFF", "backColor" : "#82BC00", "hAlign" : 1 } }, "3":{ "value":"Language", "style": { "foreColor" : "#FFFFFF", "backColor" : "#82BC00", "hAlign" : 1 } }, "4":{ "value":"Math", "style": { "foreColor" : "#FFFFFF", "backColor" : "#82BC00", "hAlign" : 1 } }, "5":{ "value":"Science", "style": { "foreColor" : "#FFFFFF", "backColor" : "#82BC00", "hAlign" : 1 } }, "6":{ "value":"Music", "style": { "foreColor" : "#FFFFFF", "backColor" : "#82BC00", "hAlign" : 1 } }, "7":{ "value":"History", "style": { "foreColor" : "#FFFFFF", "backColor" : "#82BC00", "hAlign" : 1 } } }, "3":{ "2":{ "value":"Ally", "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "3":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "4":{ "value":65.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "5":{ "value":75.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "6":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "7":{ "value":91.8, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} } }, "4":{ "2":{ "value":"Tom", "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "3":{ "value":81.8, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "4":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "5":{ "value":95, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "6":{ "value":75.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "7":{ "value":88, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} } }, "5":{ "2":{ "value":"Jack", "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "3":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "4":{ "value":68.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "5":{ "value":65.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "6":{ "value":88, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "7":{ "value":79, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} } }, "6":{ "2":{ "value":"John", "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "3":{ "value":68.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "4":{ "value":81.8, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "5":{ "value":86, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "6":{ "value":75, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "7":{ "value":86, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} } }, "7":{ "2":{ "value":"Lily", "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "3":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "4":{ "value":65.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "5":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "6":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "7":{ "value":91.8, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} } }, "8":{ "2":{ "value":"Linda", "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "3":{ "value":75.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "4":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "5":{ "value":88, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "6":{ "value":65.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "7":{ "value":65.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} } }, "9":{ "2":{ "value":"Will", "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "3":{ "value":95.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "4":{ "value":94.8, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "5":{ "value":94, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "6":{ "value":55.2, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} }, "7":{ "value":88, "style":{"backColor" : "#F4F8EB", "hAlign" : 1} } } } }, } } }]
.sample-tutorial { position: relative; height: 100%; overflow: hidden; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .sample-spreadsheets { width: calc(100% - 280px); height: 100%; overflow: hidden; float: left; } .options-container{ float: right; width: 280px; padding: 12px; height: 100%; box-sizing: border-box; background: #fbfbfb; overflow: auto; } .option-row { font-size: 14px; padding: 5px; margin-top: 10px; } .gc-stack-list{ width: 100%; height: 150px; margin-top: 10px; } .gc-stack-button{ margin: 0 5px; }