给单元格的指定位置插入字符
本帖最后由 Joestar.Xu 于 2024-11-25 11:35 编辑当表格中有许多需要引用的参数时,我们会倾向于将其作为一个外部的表格引入来使用,但是在SpreadJS中想要给单元格的指定位置插入引用却不是那么的简单。
在点击外部表格时会由于焦点的变化,会导致单元格退出编辑状态,进而无法顺利将我们想要插入的引用插入到单元格的指定位置。
如下图:
进入编辑状态后,点击右侧的加号,打开外部表格进行引入操作。
在点击了外部的表格后,编辑状态就会退出。
此时,如果我们还想要实现插入的效果,就只能使用浏览器原生的光标API来实现这个需求。
整体的实现思路是:记录下插入的索引位置=》弹出外部表格并且获取要插入的值(或其他的数据,结合自己的业务场景来选择)=》通过API重新进入编辑状态=》根据之前记录下的索引位置插入需要插入的值。
最终的实现效果为下图:
实现源码:
window.onload = async () => {
let designer, spread, sheet;
let designerConfig = JSON.parse(
JSON.stringify(GC.Spread.Sheets.Designer.DefaultConfig)
);
designer = new GC.Spread.Sheets.Designer.Designer(
"gc-designer-container",
designerConfig
);
spread = designer.getWorkbook();
sheet = spread.getActiveSheet();
let cursorPos = -1;
sheet.bind(GC.Spread.Sheets.Events.EditStarting, (e, info) => {
let editor = document.querySelector("div");
editor.addEventListener("click", () => {
getCursorIndex(editor);
});
});
let style = new GC.Spread.Sheets.Style();
style.cellButtons = [
{
imageType: GC.Spread.Sheets.ButtonImageType.plus,
command: (sheet, row, col, option) => {
let div = document.createElement("div");
div.className = "testDiv";
div.style.border = "3px solid red";
div.style.x = "300px";
div.style.y = "300px";
div.style.display = "block";
div.style.position = "absolute";
div.style.width = "500px";
div.style.height = "500px";
div.setAttribute("gcUIElement", "gcEditingInput");
let button = document.createElement("button");
button.innerText = "确定";
button.style.position = "absolute";
button.style.right = "0";
button.style.top = "0";
button.style.width = "100px";
button.style.height = "30px";
div.appendChild(button);
sheet.getParent().getHost().appendChild(div);
let newSpread = new GC.Spread.Sheets.Workbook(
document.querySelector(".testDiv"),
{ sheetCount: 1 }
);
let newSheet = newSpread.getActiveSheet();
button.addEventListener("click", () => {
if (cursorPos == -1) {
cursorPos = sheet.getValue(
sheet.getActiveRowIndex(),
sheet.getActiveColumnIndex()
).length;
console.log("cursorPos == -1", cursorPos);
}
let selection = newSheet.getSelections();
console.log(selection);
sheet.getParent().getHost().removeChild(div);
newSpread.destroy();
sheet.startEdit();
let gcEditingInput = document.querySelector(
"div"
);
moveCursorToIndex(gcEditingInput, cursorPos);
insertAtCursorInDiv("INSERT");
});
},
},
];
sheet.setStyle(0, 0, style);
sheet.setValue(0, 0, "Test");
function getCursorIndex(editor) {
const selection = window.getSelection();
const range = selection.getRangeAt(0);
const preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(editor);
preCaretRange.setEnd(range.endContainer, range.endOffset);
cursorPos = preCaretRange.toString().length;
console.log(`光标位置: ${cursorPos}`);
}
function moveCursorToIndex(div, index) {
let currentIndex = 0;
let targetNode = div.firstChild.childNodes.firstChild;
if (targetNode.textContent == "=") {
for (let i = 0; i < div.firstChild.childNodes.length; i++) {
let node = div.firstChild.childNodes;
let nodeTextLength = node.textContent.length;
if (currentIndex + nodeTextLength > index) {
targetNode = node;
break;
}
currentIndex += nodeTextLength;
}
}
let range = document.createRange();
let offset = index - currentIndex;
range.setStart(targetNode, offset);
range.setEnd(targetNode, offset);
let selection = document.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
function insertAtCursorInDiv(string) {
let selection = document.getSelection();
let textNode = document.createTextNode(string);
selection.getRangeAt(0).insertNode(textNode);
selection.collapseToEnd();
}
};
页:
[1]