表单事件

SpreadJS 提供了丰富的工作表事件机制,允许开发者在用户交互过程中捕获和处理各种操作,如单元格选择、编辑状态变化、行列增删等。通过事件监听,可以在特定操作发生时执行自定义业务逻辑,实现更灵活的表格交互功能。

概述 本 Demo 展示了如何使用 SpreadJS 工作表事件来监听和响应用户交互。Demo 演示了多种常用事件的监听,包括编辑状态变化、选区变化、行列操作等,并通过状态栏和文本区域实时显示事件信息。 实现思路 初始化工作簿并创建工作表 在工作表中设置提示信息,指导用户进行交互操作 绑定 EditorStatusChanged 事件,监听单元格编辑状态的变化 绑定 SelectionChanging 事件,监听选区的变化 绑定 ColumnChanging 和 ColumnChanged 事件,监听列的增删和显示隐藏操作 绑定 RowChanging 和 RowChanged 事件,监听行的增删和显示隐藏操作 在事件回调函数中,根据事件参数判断具体操作类型并显示相应信息 代码解析 监听编辑状态变化 EditorStatusChanged 事件在单元格编辑状态发生变化时触发。通过 sheet.editorStatus() 方法获取当前状态,状态包括: ready:就绪状态,单元格未被操作 enter:输入状态,在空单元格中输入时进入此状态,可以使用箭头键导航 edit:编辑状态,在非空单元格中编辑时进入此状态,无法使用箭头键导航 监听选区变化 SelectionChanging 事件在选区正在改变时触发,事件参数包含 newSelections 数组,提供新选区的行列索引和范围大小信息。 监听列操作 ColumnChanging 和 ColumnChanged 事件在列发生变化前后触发。通过 info.propertyName 判断操作类型: addColumns:插入列 deleteColumns:删除列 isVisible:显示或隐藏列(通过 info.newValue 判断) 监听行操作 RowChanging 和 RowChanged 事件的使用方式与列事件类似,用于监听行的增删和显示隐藏操作。propertyName 包括 addRows、deleteRows 和 isVisible。 运行效果 在表格上方的黑色边框单元格中点击并输入字符,状态栏会显示当前编辑状态(就绪、输入、编辑) 双击带有黑色边框的空单元格,可以观察编辑状态的变化 点击表格中的不同位置,文本区域会显示当前选区的行列信息和范围 右键点击列标题或行标题,选择插入或删除,可以触发相应的列/行事件 右键选择隐藏或显示列/行,也会触发对应的事件 所有事件信息都会实时显示在右侧的文本区域中 API 参考 bind 方法 type:事件类型,如 GC.Spread.Sheets.Events.SelectionChanging handler:事件处理函数,接收 sender 和 args 参数 unbind 方法 type:要移除的事件类型 fn:可选,指定要移除的处理函数 editorStatus 方法 返回当前编辑器状态,值为 GC.Spread.Sheets.EditorStatus 枚举之一:ready、enter 或 edit。
var spreadNS = GC.Spread.Sheets; window.onload = function () { var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 1 }); initSpread(spread); var statusBar = new GC.Spread.Sheets.StatusBar.StatusBar( document.getElementById('statusBar') ); statusBar.bind(spread); }; function initSpread(spread) { var sheet = spread.getSheet(0); sheet.suspendPaint(); setStatus(sheet); sheet.setValue(2, 2, "点击我,然后用键盘输入一个字符!"); sheet.addSpan(2, 2, 1, 5); sheet.getRange(2, 2, 1, 5).setBorder(new spreadNS.LineBorder("Black", spreadNS.LineStyle.thin), { all: true }); sheet.setValue(4, 2, "双击带有黑色边框的空单元格!"); sheet.addSpan(4, 2, 1, 5); sheet.addSpan(5, 2, 1, 5); sheet.getRange(5, 2, 1, 5).setBorder(new spreadNS.LineBorder("Black", spreadNS.LineStyle.thin), { all: true }); sheet.setValue(7, 2, "双击我!"); sheet.addSpan(7, 2, 1, 5); sheet.getRange(7, 2, 1, 5).setBorder(new spreadNS.LineBorder("Black", spreadNS.LineStyle.thin), { all: true }); sheet.setValue(9, 2, "双击带有黑色边框的空单元格,然后再次点击它!"); sheet.addSpan(9, 2, 1, 7); sheet.addSpan(10, 2, 1, 5); sheet.getRange(10, 2, 1, 5).setBorder(new spreadNS.LineBorder("Black", spreadNS.LineStyle.thin), { all: true }); sheet.setValue(12, 2, "按F2键开始编辑带有黑色边框的空单元格,然后再次按F2键切换编辑器状态。"); sheet.addSpan(13, 2, 1, 5); sheet.getRange(13, 2, 1, 5).setBorder(new spreadNS.LineBorder("Black", spreadNS.LineStyle.thin), { all: true }); sheet.resumePaint(); sheet.bind(GC.Spread.Sheets.Events.ColumnChanging, function (sender, info) { //insert column if (info.propertyName === "addColumns") { _getElementById("status").innerHTML = "调用了 ColumnChanging 事件!"; _getElementById("showSheetEvents").innerHTML = "ColumnChanging:增加列(" + "列:" + info.col + ")"; } //delete column if (info.propertyName === "deleteColumns") { _getElementById("status").innerHTML = "调用了 ColumnChanging 事件!"; _getElementById("showSheetEvents").innerHTML = "ColumnChanging:删除列(" + "列:" + info.col + ")"; } //unhide column if (info.propertyName === "isVisible" && info.newValue === true) { _getElementById("status").innerHTML = "调用了 ColumnChanging 事件!"; _getElementById("showSheetEvents").innerHTML = "ColumnChanging:显示列(" + "列:" + info.col + ")"; } //hide column if (info.propertyName === "isVisible" && info.newValue === false) { _getElementById("status").innerHTML = "调用了 ColumnChanging 事件!"; _getElementById("showSheetEvents").innerHTML = "ColumnChanging:隐藏列(" + "列:" + info.col + ")"; } }); sheet.bind(GC.Spread.Sheets.Events.ColumnChanged, function (sender, info) { //insert column if (info.propertyName === "addColumns") { _getElementById("status").innerHTML = "调用了 ColumnChanged 事件!"; _getElementById("showSheetEvents").innerHTML = "ColumnChanged:插入列(" + "列:" + info.col + ")"; } //delete column if (info.propertyName === "deleteColumns") { _getElementById("status").innerHTML = "调用了 ColumnChanged 事件!"; _getElementById("showSheetEvents").innerHTML = "ColumnChanged:删除列(" + "列:" + info.col + ")"; } //unhide column if (info.propertyName === "isVisible" && info.newValue === true) { _getElementById("status").innerHTML = "调用了 ColumnChanged 事件!"; _getElementById("showSheetEvents").innerHTML = "ColumnChanged:显示列(" + "列:" + info.col + ")"; } //hide column if (info.propertyName === "isVisible" && info.newValue === false) { _getElementById("status").innerHTML = "调用了 ColumnChanged 事件!"; _getElementById("showSheetEvents").innerHTML = "ColumnChanged:隐藏列(" + "列:" + info.col + ")"; } }); //RowChanging sheet.bind(GC.Spread.Sheets.Events.RowChanging, function (sender, info) { //insert row if (info.propertyName === "addRows") { _getElementById("status").innerHTML = "调用了 RowChanging 事件!"; _getElementById("showSheetEvents").innerHTML = "RowChanging:插入行(" + "行:" + info.row + ")"; } //delete row if (info.propertyName === "deleteRows") { _getElementById("status").innerHTML = "调用了 RowChanging 事件!"; _getElementById("showSheetEvents").innerHTML = "RowChanging:删除行(" + "行:" + info.row + ")"; } //unhide row if (info.propertyName === "isVisible" && info.newValue === true) { _getElementById("status").innerHTML = "调用了 RowChanging 事件!"; _getElementById("showSheetEvents").innerHTML = "RowChanging:显示行(" + "行:" + info.row + ")"; } //hide row if (info.propertyName === "isVisible" && info.newValue === false) { _getElementById("status").innerHTML = "调用了 RowChanging 事件!"; _getElementById("showSheetEvents").innerHTML = "RowChanging:隐藏行(" + "行:" + info.row + ")"; } }); sheet.bind(GC.Spread.Sheets.Events.RowChanged, function (sender, info) { //insert row if (info.propertyName === "addRows") { _getElementById("status").innerHTML = "调用了 RowChanged 事件!"; _getElementById("showSheetEvents").innerHTML = "RowChanged:插入行(" + "行:" + info.row + ")"; } //delete row if (info.propertyName === "deleteRows") { _getElementById("status").innerHTML = "调用了 RowChanged 事件!"; _getElementById("showSheetEvents").innerHTML = "RowChanged:删除行(" + "行:" + info.row + ")"; } //unhide row if (info.propertyName === "isVisible" && info.newValue === true) { _getElementById("status").innerHTML = "调用了 RowChanged 事件!"; _getElementById("showSheetEvents").innerHTML = "RowChanged:显示行(" + "行:" + info.row + ")"; } //hide row if (info.propertyName === "isVisible" && info.newValue === false) { _getElementById("status").innerHTML = "调用了 RowChanged 事件!"; _getElementById("showSheetEvents").innerHTML = "RowChanged:隐藏行(" + "行:" + info.row + ")"; } }); sheet.bind(spreadNS.Events.EditorStatusChanged, function () { setStatus(sheet); }); sheet.bind(spreadNS.Events.SelectionChanging, function (e, info) { _getElementById("status").innerHTML = "调用了 SelectionChanging 事件!"; _getElementById("showSheetEvents").innerHTML = "新的选区(" + "行: " + info.newSelections[0].row + ", " + "列: " + info.newSelections[0].col + ", " + "行数: " + info.newSelections[0].rowCount + ", " + "列数: " + info.newSelections[0].colCount + ")"; }) }; function setStatus(sheet) { var statusNow = sheet.editorStatus(); if (statusNow === spreadNS.EditorStatus.ready) { _getElementById("status").innerHTML = "编辑器状态:就绪!"; _getElementById("showSheetEvents").innerHTML = "单元格未处于编辑状态。"; } else if (statusNow === spreadNS.EditorStatus.enter) { _getElementById("status").innerHTML = "编辑器状态:进入!"; _getElementById("showSheetEvents").innerHTML = "单元格正在编辑中,您可以按任意一个箭头键离开该单元格。"; } else if (statusNow === spreadNS.EditorStatus.edit) { _getElementById("status").innerHTML = "编辑器状态:编辑!"; _getElementById("showSheetEvents").innerHTML = "单元格正在编辑中,您无法通过按任意一个箭头键离开该单元格。"; } } function _getElementById(id) { return document.getElementById(id); }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta name="spreadjs culture" content="zh-cn" /> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-resources-zh/dist/gc.spread.sheets.resources.zh.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 id="statusBar"></div> <div class="options-container"> <div class="option-row"> <label style="color:rgb(226,107,29);display:inline-block;font-family:Arial, Helvetica, sans-serif;font-size: 18px;font-weight: normal;height:30px;line-height: 30px " id="status">Settings</label> </div> <div class="option-row"> <textarea id="showSheetEvents" cols="40" rows="5" style="width: 80%"></textarea> </div> </div> </div> </body> </html>
.sample-tutorial { position: relative; height: 100%; overflow: hidden; } .sample-spreadsheets { width: calc(100% - 280px); height: calc(100% - 25px); overflow: hidden; float: left; } #statusBar { bottom: 0; height: 25px; width: 100%; position: relative; } .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; } label { display: block; margin-bottom: 6px; } input { padding: 4px 6px; } input[type=button] { margin-top: 6px; display: block; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; }