Navigation

SpreadJS supports navigation actions defined in GC.Spread.Sheets.Commands. These actions allow you to navigate the Spread instance in script code without needing to have the user do it.

This can be useful when you have business logic that may depend on navigating in the Spread instance. moveToNextCell: Moves to next cell (default action of Tab). moveToPreviousCell: Moves to previous cell (default action of Shift + Tab). selectNextControl: Selects spread.nextControl specified element or auto detected one if not set. selectPreviousControl: Selects spread.previousControl specified element or auto detected one if not set. moveToNextCellThenControl: Moves to next cell if the active cell is the last visible cell, then selects next control. moveToPreviousCellThenControl: Moves to previous cell if the active cell is the first visible cell, then selects previous control. Set the selected control using the nextControl and previousControl methods. For example: Spread allows creating custom commands. For example: Use the register method to set navigation keys and the corresponding actions. For example: The arguments of register in order are: name: The name of the command. execute: The execution function of the command. key: The unicode for the key. ctrl: True if the action uses the Ctrl key; otherwise, false. shift: True if the action uses the Shift key; otherwise, false. alt: True if the action uses the Alt key; otherwise, false. meta: True if the action uses the Command key on the Macintosh or the Windows key on Microsoft Windows; otherwise, false. Use the hideSelection option to hide the selection when Spread loses the focus. For example:
window.onload = function () { var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 1 }); initSpread(spread); }; function initSpread(spread) { var sheet = spread.getSheet(0); spread.suspendPaint(); sheet.setRowCount(20); sheet.setColumnCount(10); sheet.addSpan(0, 0, 1, 7); sheet.setValue(0, 0, "press the \'Tab\' or \'Shift + Tab\' key, the selction will move in accordance."); for (var i = 1; i < 20; i += 3) { for (var j = 1; j < 20; j += 3) { sheet.setValue(i, j, "Test"); } } spread.resumePaint(); var commandManager = spread.commandManager(); _getElementById("preButton").addEventListener('click', _alertHandle); _getElementById("nextButton").addEventListener('click', _alertHandle); function _alertHandle() { alert(this.value); } _getElementById("tabAction").addEventListener('change', _moveHandle); _getElementById("shiftTabAction").addEventListener('change', _moveHandle); function _moveHandle() { var id = this.id, isShift = id.indexOf("shift") === 0, value = parseInt(this.value, 10), actions = GC.Spread.Sheets.Commands, action; switch (value) { case 0: action = isShift ? actions.moveToPreviousCell : actions.moveToNextCell; break; case 1: action = isShift ? actions.selectPreviousControl : actions.selectNextControl; break; case 2: action = isShift ? actions.moveToPreviousCellThenControl : actions.moveToNextCellThenControl; break; } if (action) { commandManager.register("customCommand" + new Date().valueOf(), action, GC.Spread.Commands.Key.tab, false, isShift, false, false); } } _getElementById("nextControl").addEventListener('change', _handle); _getElementById("preControl").addEventListener('change', _handle); function _handle() { var id = this.id, isPre = id.indexOf("pre") === 0, value = this.value, control = value ? document.getElementById(value) : undefined; if (isPre) { spread.previousControl(control); } else { spread.nextControl(control); } } _getElementById("hideSelection").addEventListener('click', function () { spread.options.hideSelection = this.checked; }); function customSelectLeft(workbook, options) { var sheet = workbook.getSheetFromName(options.sheetName); var activeRowIndex = sheet.getActiveRowIndex(); var activeColIndex = sheet.getActiveColumnIndex(); var selNeedAdjust = getNeedAdjustSelection(sheet.getSelections(), activeRowIndex, activeColIndex); var findFirstNotNullColIndex = function (sheet, fixRow, offset, stop) { while (offset > stop) { if (sheet.getValue(fixRow, offset) !== null) { break; } offset--; } return offset; } var rangeChangeSmall = selNeedAdjust.col === activeColIndex && selNeedAdjust.colCount > 1 ? true : false; var stopSearchIndex = rangeChangeSmall ? activeColIndex : 0; var startSearchIndex = rangeChangeSmall ? selNeedAdjust.col + selNeedAdjust.colCount - 1 - 1 : selNeedAdjust.col - 1; var findResult = findFirstNotNullColIndex(sheet, activeRowIndex, startSearchIndex, stopSearchIndex); if (selNeedAdjust !== null && findResult >= 0) { selNeedAdjust.colCount = rangeChangeSmall ? findResult - selNeedAdjust.col + 1 : selNeedAdjust.col - findResult + selNeedAdjust.colCount; selNeedAdjust.col = rangeChangeSmall ? selNeedAdjust.col : findResult; sheet.repaint(); } } function customSelectRight(workbook, options) { var sheet = workbook.getSheetFromName(options.sheetName); var activeRowIndex = sheet.getActiveRowIndex(); var activeColIndex = sheet.getActiveColumnIndex(); var sheetColCount = sheet.getColumnCount(); var selNeedAdjust = getNeedAdjustSelection(sheet.getSelections(), activeRowIndex, activeColIndex); var findNextNotNullColIndex = function (sheet, fixRow, offset, stop) { while (offset < stop) { if (sheet.getValue(fixRow, offset) !== null) { break; } offset++; } return offset; } var rangeChangeSmall = selNeedAdjust.col + selNeedAdjust.colCount - 1 === activeColIndex && selNeedAdjust.colCount > 1 ? true : false; var stopSearchIndex = rangeChangeSmall ? activeColIndex : sheetColCount; var startSearchIndex = rangeChangeSmall ? selNeedAdjust.col + 1 : selNeedAdjust.col + selNeedAdjust.colCount; var findResult = findNextNotNullColIndex(sheet, activeRowIndex, startSearchIndex, stopSearchIndex); if (selNeedAdjust !== null && findResult <= sheetColCount) { selNeedAdjust.colCount = rangeChangeSmall ? selNeedAdjust.colCount + selNeedAdjust.col - findResult : findResult - selNeedAdjust.col + 1; selNeedAdjust.col = rangeChangeSmall ? findResult : selNeedAdjust.col; sheet.repaint(); } } function customSelectUp(workbook, options) { var sheet = workbook.getSheetFromName(options.sheetName); var activeRowIndex = sheet.getActiveRowIndex(); var activeColIndex = sheet.getActiveColumnIndex(); var selNeedAdjust = getNeedAdjustSelection(sheet.getSelections(), activeRowIndex, activeColIndex); var findFirstNotNullRowIndex = function (sheet, fixCol, offset, stop) { while (offset > stop) { if (sheet.getValue(offset, fixCol) !== null) { break; } offset--; } return offset; } var rangeChangeSmall = selNeedAdjust.row === activeRowIndex && selNeedAdjust.rowCount > 1 ? true : false; var stopSearchIndex = rangeChangeSmall ? activeRowIndex : 0; var startSearchIndex = rangeChangeSmall ? selNeedAdjust.row + selNeedAdjust.rowCount - 1 - 1 : selNeedAdjust.row - 1; var findResult = findFirstNotNullRowIndex(sheet, activeColIndex, startSearchIndex, stopSearchIndex); if (selNeedAdjust !== null && findResult >= 0) { selNeedAdjust.rowCount = rangeChangeSmall ? findResult - selNeedAdjust.row + 1 : selNeedAdjust.row - findResult + selNeedAdjust.rowCount; selNeedAdjust.row = rangeChangeSmall ? selNeedAdjust.row : findResult; sheet.repaint(); } } function customSelectDown(workbook, options) { var sheet = workbook.getSheetFromName(options.sheetName); var activeRowIndex = sheet.getActiveRowIndex(); var activeColIndex = sheet.getActiveColumnIndex(); var sheetRowCount = sheet.getRowCount(); var selNeedAdjust = getNeedAdjustSelection(sheet.getSelections(), activeRowIndex, activeColIndex); var findNextNotNullRowIndex = function (sheet, fixCol, offset, stop) { while (offset < stop) { if (sheet.getValue(offset, fixCol) !== null) { break; } offset++; } return offset; } var rangeChangeSmall = selNeedAdjust.row + selNeedAdjust.rowCount - 1 === activeRowIndex && selNeedAdjust.rowCount > 1 ? true : false; var stopSearchIndex = rangeChangeSmall ? activeRowIndex : sheetRowCount; var startSearchIndex = rangeChangeSmall ? selNeedAdjust.row + 1 : selNeedAdjust.row + selNeedAdjust.rowCount; var findResult = findNextNotNullRowIndex(sheet, activeColIndex, startSearchIndex, stopSearchIndex); if (selNeedAdjust !== null && findResult <= sheetRowCount) { selNeedAdjust.rowCount = rangeChangeSmall ? selNeedAdjust.rowCount + selNeedAdjust.row - findResult : findResult - selNeedAdjust.row + 1; selNeedAdjust.row = rangeChangeSmall ? findResult : selNeedAdjust.row; sheet.repaint(); } } function getNeedAdjustSelection(selections, rowIndex, colIndex) { var sel = null; for (var i = 0; i < selections.length; i++) { if (selections[i].contains(rowIndex, colIndex)) { sel = selections[i]; } } return sel; } commandManager.register("customSelectLeft", customSelectLeft); commandManager.register("customSelectRight", customSelectRight); commandManager.register("customSelectDown", customSelectDown); commandManager.register("customSelectUp", customSelectUp); commandManager.setShortcutKey(null, GC.Spread.Commands.Key.left, true, true, false, false); commandManager.setShortcutKey("customSelectLeft", GC.Spread.Commands.Key.left, true, true, false, false); commandManager.setShortcutKey(null, GC.Spread.Commands.Key.right, true, true, false, false); commandManager.setShortcutKey("customSelectRight", GC.Spread.Commands.Key.right, true, true, false, false); commandManager.setShortcutKey(null, GC.Spread.Commands.Key.down, true, true, false, false); commandManager.setShortcutKey("customSelectDown", GC.Spread.Commands.Key.down, true, true, false, false); commandManager.setShortcutKey(null, GC.Spread.Commands.Key.up, true, true, false, false); commandManager.setShortcutKey("customSelectUp", GC.Spread.Commands.Key.up, true, true, false, false); }; function _getElementById(id) { return document.getElementById(id); }
<!doctype html> <html 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"> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> <script src="app.js" type="text/javascript"></script> <link rel="stylesheet" type="text/css" href="styles.css"> </head> <body> <div class="sample-tutorial"> <div id="ss" class="sample-spreadsheets"></div> <div class="options-container"> <p>Change the “Tab for:” field to “Next Control” then click the Spread instance to give it focus.</p> <p>Hit the Tab key and observe that the focus moves to the “Previous Edit” text box on this page.</p> <p>You can utilize this functionality to change what specific navigation keys do in Spread.</p> <div class="option-row" style="margin-bottom: 10px;"> <input type="text" id="preEdit" placeholder="Previous Edit" title="Candidate previous control" /> <input type="button" id="preButton" title="Candidate previous control too" value="Previous Button" /> </div> <div class="option-row"> <input type="text" id="nextEdit" placeholder="Next Edit" title="Candidate next control" /> <input type="button" id="nextButton" title="Candidate next control too" value="Next Button" /> </div> <div class="option-row"> <label>Tab for:</label> <select id="tabAction"> <option value="0" selected="selected">Next cell</option> <option value="1">Next control</option> <option value="2">Next cell then control</option> </select> <label class="colorLabel">This controls which navigation action happens when the user presses Tab.</label> </div> <div class="option-row"> <label>Shift + Tab for:</label> <select id="shiftTabAction"> <option value="0" selected="selected">Previous cell</option> <option value="1">Previous control</option> <option value="2">Previous cell then control</option> </select> <label class="colorLabel">This controls which navigation action happens when the user presses Shift+Tab.</label> </div> <div class="option-row"> <label>Next control:</label> <select id="nextControl"> <option value="" selected="selected">Not set (auto detect)</option> <option value="nextEdit">Next Edit</option> <option value="nextButton">Next Button</option> </select> <label class="colorLabel">This defines which control is the next control in relation to the Spread instance.</label> </div> <div class="option-row"> <label>Previous control:</label> <select id="preControl"> <option value="" selected="selected">Not set (auto detect)</option> <option value="preEdit">Previous Edit</option> <option value="preButton">Previous Button</option> </select> <label class="colorLabel">This defines which control is the previous control in relation to the Spread instance.</label> </div> <div class="option-row"> <input type="checkbox" id="hideSelection" /> <label for="hideSelection">Hide Selection</label> <label class="colorLabel">Checking this box will hide the selection in the Spread instance.</label> </div> </div> </div> </body> </html>
.sample-tutorial { position: relative; height: 100%; overflow: hidden; } .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; } .options-toggle { display: none; } input, select { padding: 4px 6px; margin: 4px 0; width: 100%; box-sizing: border-box; } input[type=checkbox] { width: auto; } .colorLabel { width: auto; color: #606060; display: block; } .demo-options { margin-top: 5px; } p{ padding:2px 10px; background-color:#F4F8EB; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; }