From 439dff4330ab5053643331286091d44ae910fb8d Mon Sep 17 00:00:00 2001 From: wpxp123456 <2677556700@qq.com> Date: Wed, 28 Oct 2020 17:23:41 +0800 Subject: [PATCH] feat(hyperlink): add hyperlink function --- src/controllers/constant.js | 22 ++- src/controllers/controlHistory.js | 7 + src/controllers/handler.js | 22 +++ src/controllers/hyperlinkCtrl.js | 265 ++++++++++++++++++++++++++++++ src/controllers/resize.js | 2 + src/controllers/sheetmanage.js | 5 + src/css/luckysheet-core.css | 34 ++++ src/locale/en.js | 16 ++ src/locale/zh.js | 16 ++ 9 files changed, 387 insertions(+), 2 deletions(-) create mode 100644 src/controllers/hyperlinkCtrl.js diff --git a/src/controllers/constant.js b/src/controllers/constant.js index d320325..2aacaad 100644 --- a/src/controllers/constant.js +++ b/src/controllers/constant.js @@ -384,6 +384,9 @@ function rightclickHTML(){
${toolbar.insertImage}
+
${toolbar.dataVerification}
@@ -1229,6 +1232,23 @@ function menuToolBar (){ +
@@ -1239,7 +1259,6 @@ function menuToolBar (){
@@ -1272,7 +1291,6 @@ function menuToolBar (){
diff --git a/src/controllers/controlHistory.js b/src/controllers/controlHistory.js index 3a95a4c..d3940df 100644 --- a/src/controllers/controlHistory.js +++ b/src/controllers/controlHistory.js @@ -5,6 +5,7 @@ import conditionformat from './conditionformat'; import luckysheetPostil from './postil'; import imageCtrl from './imageCtrl'; import dataVerificationCtrl from './dataVerificationCtrl'; +import hyperlinkCtrl from './hyperlinkCtrl'; import {zoomRefreshView,zoomNumberDomBind} from './zoom'; import { createFilter, createFilterOptions, labelFilterOptionState } from './filter'; import formula from '../global/formula'; @@ -344,6 +345,9 @@ const controlHistory = { else if (ctr.type == "updateDataVerificationOfCheckbox"){ dataVerificationCtrl.refOfCheckbox(ctr.currentDataVerification, ctr.historyDataVerification, ctr.sheetIndex, ctr.data, ctr.range); } + else if (ctr.type == "updateHyperlink"){ + hyperlinkCtrl.ref(ctr.currentHyperlink, ctr.historyHyperlink, ctr.sheetIndex, ctr.data, ctr.range); + } else if (ctr.type == "updateCF"){ let historyRules = ctr["data"]["historyRules"]; @@ -650,6 +654,9 @@ const controlHistory = { else if (ctr.type == "updateDataVerificationOfCheckbox"){ dataVerificationCtrl.refOfCheckbox(ctr.historyDataVerification, ctr.currentDataVerification, ctr.sheetIndex, ctr.curData, ctr.range); } + else if (ctr.type == "updateHyperlink") { + hyperlinkCtrl.ref(ctr.historyHyperlink, ctr.currentHyperlink, ctr.sheetIndex, ctr.curData, ctr.range); + } else if (ctr.type == "updateCF"){ let currentRules = ctr["data"]["currentRules"]; diff --git a/src/controllers/handler.js b/src/controllers/handler.js index 432681d..f7d72fa 100644 --- a/src/controllers/handler.js +++ b/src/controllers/handler.js @@ -5,6 +5,7 @@ import pivotTable from './pivotTable'; import luckysheetDropCell from './dropCell'; import luckysheetPostil from './postil'; import imageCtrl from './imageCtrl'; +import hyperlinkCtrl from './hyperlinkCtrl'; import dataVerificationCtrl from './dataVerificationCtrl'; import menuButton from './menuButton'; import conditionformat from './conditionformat'; @@ -338,6 +339,9 @@ export default function luckysheetHandler() { //数据验证 单元格聚焦 dataVerificationCtrl.cellFocus(row_index, col_index, true); + //链接 单元格聚焦 + hyperlinkCtrl.cellFocus(row_index, col_index); + //若点击单元格部分不在视图内 if (col_pre < $("#luckysheet-cell-main").scrollLeft()) { $("#luckysheet-scrollbar-x").scrollLeft(col_pre); @@ -4531,6 +4535,24 @@ export default function luckysheetHandler() { } }); + //菜单栏 插入链接按钮 + $("#luckysheet-insertLink-btn-title").click(function () { + if(!checkProtectionNotEnable(Store.currentSheetIndex)){ + return; + } + + if (Store.luckysheet_select_save == null || Store.luckysheet_select_save.length == 0) { + return; + } + + hyperlinkCtrl.createDialog(); + hyperlinkCtrl.init(); + }) + $("#luckysheetInsertLink").click(function () { + $("#luckysheet-insertLink-btn-title").click(); + $("#luckysheet-rightclick-menu").hide(); + }) + //菜单栏 数据验证按钮 $("#luckysheet-dataVerification-btn-title").click(function () { if(!checkProtectionNotEnable(Store.currentSheetIndex)){ diff --git a/src/controllers/hyperlinkCtrl.js b/src/controllers/hyperlinkCtrl.js new file mode 100644 index 0000000..a906031 --- /dev/null +++ b/src/controllers/hyperlinkCtrl.js @@ -0,0 +1,265 @@ +import { replaceHtml } from '../utils/util'; +import { getcellvalue } from '../global/getdata'; +import { luckysheetrefreshgrid } from '../global/refresh'; +import formula from '../global/formula'; +import tooltip from '../global/tooltip'; +import editor from '../global/editor'; +import { modelHTML } from './constant'; +import server from './server'; +import { getSheetIndex } from '../methods/get'; +import locale from '../locale/locale'; +import Store from '../store'; + +const hyperlinkCtrl = { + item: { + linkType: 'external', //链接类型 external外部链接,internal内部链接 + linkAddress: '', //链接地址 网页地址或工作表单元格引用 + linkTooltip: '', //提示 + }, + hyperlink: null, + createDialog: function(){ + let _this = this; + + const _locale = locale(); + const hyperlinkText = _locale.insertLink; + const toolbarText = _locale.toolbar; + const buttonText = _locale.button; + + $("#luckysheet-modal-dialog-mask").show(); + $("#luckysheet-insertLink-dialog").remove(); + + let sheetListOption = ''; + Store.luckysheetfile.forEach(item => { + sheetListOption += ``; + }) + + let content = `
+
+ + +
+
+ + +
+
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+ + +
+
`; + + $("body").append(replaceHtml(modelHTML, { + "id": "luckysheet-insertLink-dialog", + "addclass": "luckysheet-insertLink-dialog", + "title": toolbarText.insertLink, + "content": content, + "botton": ` + `, + "style": "z-index:100003" + })); + let $t = $("#luckysheet-insertLink-dialog").find(".luckysheet-modal-dialog-content").css("min-width", 350).end(), + myh = $t.outerHeight(), + myw = $t.outerWidth(); + let winw = $(window).width(), + winh = $(window).height(); + let scrollLeft = $(document).scrollLeft(), + scrollTop = $(document).scrollTop(); + $("#luckysheet-insertLink-dialog").css({ + "left": (winw + scrollLeft - myw) / 2, + "top": (winh + scrollTop - myh) / 3 + }).show(); + + _this.dataAllocation(); + }, + init: function (){ + let _this = this; + + const _locale = locale(); + const hyperlinkText = _locale.insertLink; + + //链接类型 + $(document).off("change.linkType").on("change.linkType", "#luckysheet-insertLink-dialog-linkType", function(e){ + let value = this.value; + + $("#luckysheet-insertLink-dialog .show-box").hide(); + $("#luckysheet-insertLink-dialog .show-box-" + value).show(); + }) + + //确认按钮 + $(document).off("click.confirm").on("click.confirm", "#luckysheet-insertLink-dialog-confirm", function(e){ + let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1]; + let rowIndex = last.row_focus || last.row[0]; + let colIndex = last.column_focus || last.column[0]; + + //文本 + let linkText = $("#luckysheet-insertLink-dialog-linkText").val(); + + let linkType = $("#luckysheet-insertLink-dialog-linkType").val(); + let linkAddress = $("#luckysheet-insertLink-dialog-linkAddress").val(); + let linkSheet = $("#luckysheet-insertLink-dialog-linkSheet").val(); + let linkCell = $("#luckysheet-insertLink-dialog-linkCell").val(); + let linkTooltip = $("#luckysheet-insertLink-dialog-linkTooltip").val(); + + if(linkType == 'external'){ + if(!/^http[s]?:\/\/([\w\-\.]+)+[\w-]*([\w\-\.\/\?%&=]+)?$/ig.test(linkAddress)){ + tooltip.info('', hyperlinkText.tooltipInfo1); + return; + } + } + else{ + if(!formula.iscelldata(linkCell)){ + tooltip.info('', hyperlinkText.tooltipInfo2); + return; + } + + linkAddress = linkSheet + "!" + linkCell; + } + + if(linkText == null || linkText.replace(/\s/g, '') == ''){ + linkText = linkAddress; + } + + let item = { + linkType: linkType, + linkAddress: linkAddress, + linkTooltip: linkTooltip, + } + + let historyHyperlink = $.extend(true, {}, _this.hyperlink); + let currentHyperlink = $.extend(true, {}, _this.hyperlink); + + currentHyperlink[rowIndex + "_" + colIndex] = item; + + let d = editor.deepCopyFlowData(Store.flowdata); + let cell = d[rowIndex][colIndex]; + + if(cell == null){ + cell = {}; + } + + cell.fc = 'rgb(0, 0, 255)'; + cell.un = 1; + cell.v = linkText; + + d[rowIndex][colIndex] = cell; + + _this.ref( + historyHyperlink, + currentHyperlink, + Store.currentSheetIndex, + d, + { row: [rowIndex, rowIndex], column: [colIndex, colIndex] } + ); + + $("#luckysheet-modal-dialog-mask").hide(); + $("#luckysheet-insertLink-dialog").hide(); + }) + }, + dataAllocation: function(){ + let _this = this; + + let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1]; + let rowIndex = last.row_focus || last.row[0]; + let colIndex = last.column_focus || last.column[0]; + + let hyperlink = _this.hyperlink || {}; + let item = hyperlink[rowIndex + "_" + colIndex] || {}; + + //文本 + let text = getcellvalue(rowIndex, colIndex, null, 'm'); + $("#luckysheet-insertLink-dialog-linkText").val(text); + + //链接类型 + let linkType = item.linkType || 'external'; + $("#luckysheet-insertLink-dialog-linkType").val(linkType); + + $("#luckysheet-insertLink-dialog .show-box").hide(); + $("#luckysheet-insertLink-dialog .show-box-" + linkType).show(); + + //链接地址 + let linkAddress = item.linkAddress || ''; + + if(linkType == 'external'){ + $("#luckysheet-insertLink-dialog-linkAddress").val(linkAddress); + } + else{ + if(formula.iscelldata(linkAddress)){ + let sheettxt = linkAddress.split("!")[0]; + let rangetxt = linkAddress.split("!")[1]; + + $("#luckysheet-insertLink-dialog-linkSheet").val(sheettxt); + $("#luckysheet-insertLink-dialog-linkCell").val(rangetxt); + } + } + + //提示 + let linkTooltip = item.linkTooltip || ''; + $("#luckysheet-insertLink-dialog-linkTooltip").val(linkTooltip); + }, + cellFocus: function(r, c){ + let _this = this; + + if(_this.hyperlink == null || _this.hyperlink[r + '_' + c] == null){ + return; + } + + + }, + ref: function(historyHyperlink, currentHyperlink, sheetIndex, d, range){ + let _this = this; + + if (Store.clearjfundo) { + Store.jfundo = []; + + let redo = {}; + redo["type"] = "updateHyperlink"; + redo["sheetIndex"] = sheetIndex; + redo["historyHyperlink"] = historyHyperlink; + redo["currentHyperlink"] = currentHyperlink; + redo["data"] = Store.flowdata; + redo["curData"] = d; + redo["range"] = range; + Store.jfredo.push(redo); + } + + _this.hyperlink = currentHyperlink; + Store.luckysheetfile[getSheetIndex(sheetIndex)].hyperlink = currentHyperlink; + + Store.flowdata = d; + editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据 + Store.luckysheetfile[getSheetIndex(sheetIndex)].data = Store.flowdata; + + //共享编辑模式 + if(server.allowUpdate){ + server.saveParam("all", sheetIndex, currentHyperlink, { "k": "hyperlink" }); + server.historyParam(Store.flowdata, sheetIndex, range); + } + + setTimeout(function () { + luckysheetrefreshgrid(); + }, 1); + } +} + +export default hyperlinkCtrl; \ No newline at end of file diff --git a/src/controllers/resize.js b/src/controllers/resize.js index 5ca3935..4e909ca 100644 --- a/src/controllers/resize.js +++ b/src/controllers/resize.js @@ -318,6 +318,7 @@ export function menuToolBarWidth() { $('#luckysheet-icon-textwrap').offset().left, $('#luckysheet-icon-rotation').offset().left, $('#luckysheet-insertImg-btn-title').offset().left, + $('#luckysheet-insertLink-btn-title').offset().left, $('#luckysheet-chart-btn-title').offset().left, $('#luckysheet-icon-postil').offset().left, $('#luckysheet-pivot-btn-title').offset().left, @@ -356,6 +357,7 @@ export function menuToolBarWidth() { ['#luckysheet-icon-textwrap','#luckysheet-icon-textwrap-menu'], ['#luckysheet-icon-rotation','#luckysheet-icon-rotation-menu','#toolbar-separator-text-rotate'], '#luckysheet-insertImg-btn-title', + '#luckysheet-insertLink-btn-title', '#luckysheet-chart-btn-title', '#luckysheet-icon-postil', ['#luckysheet-pivot-btn-title','#toolbar-separator-pivot-table'], diff --git a/src/controllers/sheetmanage.js b/src/controllers/sheetmanage.js index deaaf2f..36cd089 100644 --- a/src/controllers/sheetmanage.js +++ b/src/controllers/sheetmanage.js @@ -19,6 +19,7 @@ import luckysheetsizeauto from './resize'; import luckysheetPostil from './postil'; import imageCtrl from './imageCtrl'; import dataVerificationCtrl from './dataVerificationCtrl'; +import hyperlinkCtrl from './hyperlinkCtrl'; import luckysheetFreezen from './freezen'; import { createFilterOptions, labelFilterOptionState } from './filter'; import { selectHightlightShow, selectionCopyShow } from './select'; @@ -930,6 +931,10 @@ const sheetmanage = { //数据验证 dataVerificationCtrl.dataVerification = file.dataVerification; dataVerificationCtrl.init(); + + //链接 + hyperlinkCtrl.hyperlink = file.hyperlink; + hyperlinkCtrl.init(); createFilterOptions(file["filter_select"], file["filter"]); }, diff --git a/src/css/luckysheet-core.css b/src/css/luckysheet-core.css index 6b72126..6068da1 100644 --- a/src/css/luckysheet-core.css +++ b/src/css/luckysheet-core.css @@ -7065,6 +7065,40 @@ fieldset[disabled] .btn-danger.focus { position: absolute; display: none; } +/* 插入链接 */ +#luckysheet-insertLink-dialog{ + user-select: none; +} +#luckysheet-insertLink-dialog .box{ + font-size: 12px; +} +#luckysheet-insertLink-dialog .box-item{ + height: 30px; + line-height: 30px; + margin-bottom: 10px; +} +#luckysheet-insertLink-dialog .box-item label{ + display: inline-block; + width: 80px; + text-align: right; + margin-right: 10px; +} +#luckysheet-insertLink-dialog .box-item input{ + width: 200px; + height: 30px; + padding: 0 10px; + border: 1px solid #d4d4d4; + outline-style: none; + box-sizing: border-box; +} +#luckysheet-insertLink-dialog .box-item select{ + width: 200px; + height: 30px; + padding: 0 5px; + border: 1px solid #d4d4d4; + outline-style: none; + box-sizing: border-box; +} /* 数据验证 */ #luckysheet-dataVerification-dialog{ user-select: none; diff --git a/src/locale/en.js b/src/locale/en.js index 05a87fd..b279da0 100644 --- a/src/locale/en.js +++ b/src/locale/en.js @@ -8859,6 +8859,7 @@ export default { screenshot: 'Screenshot', splitColumn: 'Split text', insertImage: 'Insert image', + insertLink: 'Insert link', dataVerification: 'Data verification', protection:"Protect the sheet", @@ -9689,6 +9690,21 @@ export default { fiveQuadrantDiagram: 'Five-quadrant diagram', fiveBoxes: '5 Boxes', }, + insertLink: { + linkText: "Text", + linkType: "Link type", + external: "External link", + internal: "Internal link", + linkAddress: "Link address", + linkSheet: "Worksheet", + linkCell: "Cell reference", + linkTooltip: "Tooltip", + placeholder1: "Please enter the web link address", + placeholder2: "Please enter the cell to be quoted, example A1", + placeholder3: "Please enter the prompt content", + tooltipInfo1: "Please enter a valid link", + tooltipInfo2: "Please enter the correct cell reference", + }, dataVerification: { cellRange: 'Cell range', selectCellRange: 'Click to select a cell range', diff --git a/src/locale/zh.js b/src/locale/zh.js index 6818780..494f786 100644 --- a/src/locale/zh.js +++ b/src/locale/zh.js @@ -9085,6 +9085,7 @@ export default { screenshot: '截图', splitColumn: '分列', insertImage: '插入图片', + insertLink: '插入链接', dataVerification: '数据验证', protection:"保护工作表内容", @@ -9933,6 +9934,21 @@ export default { fiveQuadrantDiagram: '五象限图', fiveBoxes: '5个框', }, + insertLink: { + linkText: "文本", + linkType: "链接类型", + external: "外部链接", + internal: "内部链接", + linkAddress: "链接地址", + linkSheet: "工作表", + linkCell: "单元格引用", + linkTooltip: "提示", + placeholder1: "请输入网页链接地址", + placeholder2: "请输入要引用的单元格,例A1", + placeholder3: "请输入提示内容", + tooltipInfo1: "请输入有效的链接", + tooltipInfo2: "请输入正确的单元格引用", + }, dataVerification: { cellRange: '单元格范围', selectCellRange: '点击选择单元格范围',