找回密码
 立即注册

QQ登录

只需一步,快速开始

Joestar.Xu SpreadJS 开发认证
超级版主   /  发表于:2024-11-18 15:11  /   查看:68  /  回复:0
本帖最后由 Joestar.Xu 于 2024-11-25 11:35 编辑

当表格中有许多需要引用的参数时,我们会倾向于将其作为一个外部的表格引入来使用,但是在SpreadJS中想要给单元格的指定位置插入引用却不是那么的简单。


在点击外部表格时会由于焦点的变化,会导致单元格退出编辑状态,进而无法顺利将我们想要插入的引用插入到单元格的指定位置。

如下图:

image.png509139098.png

进入编辑状态后,点击右侧的加号,打开外部表格进行引入操作。

image.png460195006.png

在点击了外部的表格后,编辑状态就会退出。

此时,如果我们还想要实现插入的效果,就只能使用浏览器原生的光标API来实现这个需求。

整体的实现思路是:记录下插入的索引位置=》弹出外部表格并且获取要插入的值(或其他的数据,结合自己的业务场景来选择)=》通过API重新进入编辑状态=》根据之前记录下的索引位置插入需要插入的值。

最终的实现效果为下图:

20241118105049.gif175292052.png

实现源码:

  1. window.onload = async () => {
  2.   let designer, spread, sheet;

  3.   let designerConfig = JSON.parse(
  4.     JSON.stringify(GC.Spread.Sheets.Designer.DefaultConfig)
  5.   );

  6.   designer = new GC.Spread.Sheets.Designer.Designer(
  7.     "gc-designer-container",
  8.     designerConfig
  9.   );

  10.   spread = designer.getWorkbook();

  11.   sheet = spread.getActiveSheet();

  12.   let cursorPos = -1;
  13.   sheet.bind(GC.Spread.Sheets.Events.EditStarting, (e, info) => {
  14.     let editor = document.querySelector("div[gcuielement='gcEditingInput']");
  15.     editor.addEventListener("click", () => {
  16.       getCursorIndex(editor);
  17.     });
  18.   });

  19.   let style = new GC.Spread.Sheets.Style();
  20.   style.cellButtons = [
  21.     {
  22.       imageType: GC.Spread.Sheets.ButtonImageType.plus,
  23.       command: (sheet, row, col, option) => {
  24.         let div = document.createElement("div");
  25.         div.className = "testDiv";
  26.         div.style.border = "3px solid red";
  27.         div.style.x = "300px";
  28.         div.style.y = "300px";
  29.         div.style.display = "block";
  30.         div.style.position = "absolute";
  31.         div.style.width = "500px";
  32.         div.style.height = "500px";
  33.         div.setAttribute("gcUIElement", "gcEditingInput");

  34.         let button = document.createElement("button");
  35.         button.innerText = "确定";
  36.         button.style.position = "absolute";
  37.         button.style.right = "0";
  38.         button.style.top = "0";
  39.         button.style.width = "100px";
  40.         button.style.height = "30px";

  41.         div.appendChild(button);

  42.         sheet.getParent().getHost().appendChild(div);

  43.         let newSpread = new GC.Spread.Sheets.Workbook(
  44.           document.querySelector(".testDiv"),
  45.           { sheetCount: 1 }
  46.         );

  47.         let newSheet = newSpread.getActiveSheet();

  48.         button.addEventListener("click", () => {
  49.           if (cursorPos == -1) {
  50.             cursorPos = sheet.getValue(
  51.               sheet.getActiveRowIndex(),
  52.               sheet.getActiveColumnIndex()
  53.             ).length;
  54.             console.log("cursorPos == -1", cursorPos);
  55.           }

  56.           let selection = newSheet.getSelections()[0];
  57.           console.log(selection);

  58.           sheet.getParent().getHost().removeChild(div);
  59.           newSpread.destroy();

  60.           sheet.startEdit();
  61.           let gcEditingInput = document.querySelector(
  62.             "div[gcuielement='gcEditingInput']"
  63.           );
  64.           moveCursorToIndex(gcEditingInput, cursorPos);
  65.           insertAtCursorInDiv("INSERT");
  66.         });
  67.       },
  68.     },
  69.   ];
  70.   sheet.setStyle(0, 0, style);
  71.   sheet.setValue(0, 0, "Test");

  72.   function getCursorIndex(editor) {
  73.     const selection = window.getSelection();
  74.     const range = selection.getRangeAt(0);
  75.     const preCaretRange = range.cloneRange();
  76.     preCaretRange.selectNodeContents(editor);
  77.     preCaretRange.setEnd(range.endContainer, range.endOffset);
  78.     cursorPos = preCaretRange.toString().length;
  79.     console.log(`光标位置: ${cursorPos}`);
  80.   }

  81.   function moveCursorToIndex(div, index) {
  82.     let currentIndex = 0;
  83.     let targetNode = div.firstChild.childNodes[0].firstChild;

  84.     if (targetNode.textContent == "=") {
  85.       for (let i = 0; i < div.firstChild.childNodes.length; i++) {
  86.         let node = div.firstChild.childNodes[i];
  87.         let nodeTextLength = node.textContent.length;

  88.         if (currentIndex + nodeTextLength > index) {
  89.           targetNode = node;
  90.           break;
  91.         }
  92.         currentIndex += nodeTextLength;
  93.       }
  94.     }

  95.     let range = document.createRange();
  96.     let offset = index - currentIndex;
  97.     range.setStart(targetNode, offset);
  98.     range.setEnd(targetNode, offset);
  99.     let selection = document.getSelection();
  100.     selection.removeAllRanges();
  101.     selection.addRange(range);
  102.   }

  103.   function insertAtCursorInDiv(string) {
  104.     let selection = document.getSelection();
  105.     let textNode = document.createTextNode(string);
  106.     selection.getRangeAt(0).insertNode(textNode);
  107.     selection.collapseToEnd();
  108.   }
  109. };
复制代码

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部