From 9cbbbce556444182536bf0a0641c5db22d4a6007 Mon Sep 17 00:00:00 2001 From: wpxp123456 <2677556700@qq.com> Date: Thu, 17 Sep 2020 15:05:59 +0800 Subject: [PATCH 1/2] feat(data verification): data verification data verification --- src/controllers/constant.js | 6 + src/controllers/controlHistory.js | 93 +- src/controllers/dataVerificationCtrl.js | 1390 +++++++++++++++++++++++ src/controllers/dropCell.js | 23 +- src/controllers/handler.js | 273 ++++- src/controllers/pivotTable.js | 2 +- src/controllers/select.js | 3 + src/controllers/selection.js | 245 ++-- src/controllers/sheetmanage.js | 4 + src/controllers/updateCell.js | 11 + src/css/luckysheet-core.css | 174 ++- src/global/draw.js | 103 +- src/global/extend.js | 169 ++- src/global/formula.js | 6 +- src/global/refresh.js | 63 +- src/locale/en.js | 1 + src/locale/zh.js | 1 + 17 files changed, 2427 insertions(+), 140 deletions(-) create mode 100644 src/controllers/dataVerificationCtrl.js diff --git a/src/controllers/constant.js b/src/controllers/constant.js index 52c8528..d2ae6c7 100644 --- a/src/controllers/constant.js +++ b/src/controllers/constant.js @@ -181,6 +181,9 @@ const gridHTML = function(){
+
+
+
\${flow} @@ -1267,6 +1270,9 @@ function menuToolBar (){
${toolbar.insertImage} +
+
+ ${toolbar.dataVerification}
`; } diff --git a/src/controllers/controlHistory.js b/src/controllers/controlHistory.js index d0d962e..9d26669 100644 --- a/src/controllers/controlHistory.js +++ b/src/controllers/controlHistory.js @@ -4,6 +4,7 @@ import pivotTable from './pivotTable'; import conditionformat from './conditionformat'; import luckysheetPostil from './postil'; import imageCtrl from './imageCtrl'; +import dataVerificationCtrl from './dataVerificationCtrl'; import {zoomRefreshView,zoomNumberDomBind} from './zoom'; import { createFilter, createFilterOptions, labelFilterOptionState } from './filter'; import formula from '../global/formula'; @@ -58,7 +59,7 @@ const controlHistory = { } formula.execFunctionGroup(null, null, null, null, ctr.data);//取之前的数据 - jfrefreshgrid(ctr.data, ctr.range, ctr.config, ctr.cdformat, ctr.RowlChange); + jfrefreshgrid(ctr.data, ctr.range, ctr.config, ctr.cdformat, ctr.RowlChange, ctr.dataVerification); } else if (ctr.type == "pasteCut") { let s = { @@ -69,6 +70,8 @@ const controlHistory = { "curConfig": ctr.source["config"], "cdformat": ctr.source["curCdformat"], "curCdformat": ctr.source["cdformat"], + "dataVerification": ctr.source["curDataVerification"], + "curDataVerification": ctr.source["dataVerification"], "range": ctr.source["range"] } let t = { @@ -79,6 +82,8 @@ const controlHistory = { "curConfig": ctr.target["config"], "cdformat": ctr.target["curCdformat"], "curCdformat": ctr.target["cdformat"], + "dataVerification": ctr.target["curDataVerification"], + "curDataVerification": ctr.target["dataVerification"], "range": ctr.target["range"] } jfrefreshgrid_pastcut(s, t, ctr.RowlChange); @@ -139,17 +144,47 @@ const controlHistory = { ctrlValue.index = ctrlValue.index + 1; } - jfrefreshgrid_adRC(ctr.data, ctr.config, "delRC", ctrlValue, ctr.calc, ctr.filterObj, ctr.cf, ctr.af, ctr.freezen); + jfrefreshgrid_adRC( + ctr.data, + ctr.config, + "delRC", + ctrlValue, + ctr.calc, + ctr.filterObj, + ctr.cf, + ctr.af, + ctr.freezen, + ctr.dataVerification + ); } else if (ctr.type == "delRC") { //删除行列撤销操作 let ctrlValue = $.extend(true, {}, ctr.ctrlValue); ctrlValue.restore = true; ctrlValue.direction = "lefttop"; - jfrefreshgrid_adRC(ctr.data, ctr.config, "addRC", ctrlValue, ctr.calc, ctr.filterObj, ctr.cf, ctr.af, ctr.freezen); + jfrefreshgrid_adRC( + ctr.data, + ctr.config, + "addRC", + ctrlValue, + ctr.calc, + ctr.filterObj, + ctr.cf, + ctr.af, + ctr.freezen, + ctr.dataVerification + ); } else if (ctr.type == "deleteCell") { //删除单元格撤销操作 - jfrefreshgrid_deleteCell(ctr.data, ctr.config, ctr.ctrl, ctr.calc, ctr.filterObj, ctr.cf); + jfrefreshgrid_deleteCell( + ctr.data, + ctr.config, + ctr.ctrl, + ctr.calc, + ctr.filterObj, + ctr.cf, + ctr.dataVerification + ); } else if (ctr.type == "showHidRows") { // 隐藏、显示行 撤销操作 //config @@ -287,6 +322,12 @@ const controlHistory = { else if (ctr.type == "mergeChange") { jfrefreshgrid(ctr.data, ctr.range, ctr.config); } + else if (ctr.type == "updateDataVerification"){ + dataVerificationCtrl.ref(ctr.currentDataVerification, ctr.historyDataVerification, ctr.sheetIndex); + } + else if (ctr.type == "updateDataVerificationOfCheckbox"){ + dataVerificationCtrl.refOfCheckbox(ctr.currentDataVerification, ctr.historyDataVerification, ctr.sheetIndex, ctr.data, ctr.range); + } else if (ctr.type == "updateCF"){ let historyRules = ctr["data"]["historyRules"]; @@ -375,7 +416,7 @@ const controlHistory = { if (ctr.type == "datachange") { formula.execFunctionGroup(); - jfrefreshgrid(ctr.curdata, ctr.range, ctr.curConfig, ctr.curCdformat, ctr.RowlChange); + jfrefreshgrid(ctr.curdata, ctr.range, ctr.curConfig, ctr.curCdformat, ctr.RowlChange, ctr.curDataVerification); } else if (ctr.type == "pasteCut") { jfrefreshgrid_pastcut(ctr.source, ctr.target, ctr.RowlChange); @@ -415,13 +456,43 @@ const controlHistory = { jfrefreshgridall(ctr.curdata[0].length, ctr.curdata.length, ctr.curdata, ctr.curconfig, ctr.currange, ctr.ctrlType, ctr.ctrlValue); } else if (ctr.type == "addRC") { //增加行列重做操作 - jfrefreshgrid_adRC(ctr.curData, ctr.curConfig, "addRC", ctr.ctrlValue, ctr.curCalc, ctr.curFilterObj, ctr.curCf, ctr.curAf, ctr.curFreezen); + jfrefreshgrid_adRC( + ctr.curData, + ctr.curConfig, + "addRC", + ctr.ctrlValue, + ctr.curCalc, + ctr.curFilterObj, + ctr.curCf, + ctr.curAf, + ctr.curFreezen, + ctr.curDataVerification + ); } else if (ctr.type == "delRC") { //删除行列重做操作 - jfrefreshgrid_adRC(ctr.curData, ctr.curConfig, "delRC", ctr.ctrlValue, ctr.curCalc, ctr.curFilterObj, ctr.curCf, ctr.curAf, ctr.curFreezen); + jfrefreshgrid_adRC( + ctr.curData, + ctr.curConfig, + "delRC", + ctr.ctrlValue, + ctr.curCalc, + ctr.curFilterObj, + ctr.curCf, + ctr.curAf, + ctr.curFreezen, + ctr.curDataVerification + ); } else if (ctr.type == "deleteCell") { //删除单元格重做操作 - jfrefreshgrid_deleteCell(ctr.curData, ctr.curConfig, ctr.ctrl, ctr.curCalc, ctr.curFilterObj, ctr.curCf); + jfrefreshgrid_deleteCell( + ctr.curData, + ctr.curConfig, + ctr.ctrl, + ctr.curCalc, + ctr.curFilterObj, + ctr.curCf, + ctr.curDataVerification + ); } else if (ctr.type == "showHidRows") { // 隐藏、显示行 重做操作 //config @@ -542,6 +613,12 @@ const controlHistory = { else if (ctr.type == "mergeChange") { jfrefreshgrid(ctr.curData, ctr.range, ctr.curConfig); } + else if (ctr.type == "updateDataVerification"){ + dataVerificationCtrl.ref(ctr.historyDataVerification, ctr.currentDataVerification, ctr.sheetIndex); + } + else if (ctr.type == "updateDataVerificationOfCheckbox"){ + dataVerificationCtrl.refOfCheckbox(ctr.historyDataVerification, ctr.currentDataVerification, ctr.sheetIndex, ctr.curData, ctr.range); + } else if (ctr.type == "updateCF"){ let currentRules = ctr["data"]["currentRules"]; diff --git a/src/controllers/dataVerificationCtrl.js b/src/controllers/dataVerificationCtrl.js new file mode 100644 index 0000000..95572da --- /dev/null +++ b/src/controllers/dataVerificationCtrl.js @@ -0,0 +1,1390 @@ +import { replaceHtml } from '../utils/util'; +import formula from '../global/formula'; +import { isRealNum } from '../global/validate'; +import { isdatetime, diff } from '../global/datecontroll'; +import { luckysheetrefreshgrid } from '../global/refresh'; +import tooltip from '../global/tooltip'; +import { setcellvalue } from '../global/setdata'; +import { getcellvalue } from '../global/getdata'; +import editor from '../global/editor'; +import { modelHTML } from './constant'; +import { selectionCopyShow } from './select'; +import server from './server'; +import menuButton from './menuButton'; +import { getSheetIndex, getRangetxt } from '../methods/get'; +import Store from '../store'; + +const dataVerificationCtrl = { + defaultItem: { + type: 'dropdown', //类型 + type2: null, // + value1: '', // + value2: '', // + checked: false, + remote: false, //自动远程获取选项 + prohibitInput: false, //输入数据无效时禁止输入 + hintShow: false, //选中单元格时显示提示语 + hintText: '', // + }, + curItem: null, + dataVerification: null, + selectRange: [], + selectStatus: false, + optionLabel: { + 'number': '数值', + 'number_integer': '整数', + 'number_decimal': '小数', + 'bw': '介于', + 'nb': '不介于', + 'eq': '等于', + 'ne': '不等于', + 'gt': '大于', + 'lt': '小于', + 'gte': '大于等于', + 'lte': '小于等于', + 'include': '包括', + 'exclude': '不包括', + 'equal': '等于', + 'bf': '早于', + 'nbf': '不早于', + 'af': '晚于', + 'naf': '不晚于', + 'card': '身份证号码', + 'phone': '手机号' + }, + createDialog: function(){ + let _this = this; + + $("#luckysheet-modal-dialog-mask").show(); + $("#luckysheet-dataVerification-dialog").remove(); + + let content = `
+
+
单元格范围
+
+ + +
+
+
+
验证条件
+ +
+
+
+ + +
+
+
+
+ 选择时 —— + +
+
+ 未选择 —— + +
+
+
+ +
+ + - + +
+
+ +
+
+
+ +
+ +
+
+
+ +
+ + - + +
+
+ +
+
+
+ +
+ + - + +
+
+ +
+
+
+ +
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
`; + + $("body").append(replaceHtml(modelHTML, { + "id": "luckysheet-dataVerification-dialog", + "addclass": "luckysheet-dataVerification-dialog", + "title": "数据验证", + "content": content, + "botton": ` + + `, + "style": "z-index:100003" + })); + let $t = $("#luckysheet-dataVerification-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-dataVerification-dialog").css({ + "left": (winw + scrollLeft - myw) / 2, + "top": (winh + scrollTop - myh) / 3 + }).show(); + + _this.dataAllocation(); + }, + init: function(){ + let _this = this; + + //单元格数据验证 类型是 下拉列表 + $(document).off("click.dropdownBtn").on("click.dropdownBtn", "#luckysheet-dataVerification-dropdown-btn", function(e) { + _this.dropdownListShow(); + e.stopPropagation(); + }); + $(document).off("click.dropdownListItem").on("click.dropdownListItem", "#luckysheet-dataVerification-dropdown-List .dropdown-List-item", function(e) { + $("#luckysheet-dataVerification-dropdown-List").hide(); + + let value = e.target.innerText; + let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1]; + let rowIndex = last.row_focus; + let colIndex = last.column_focus; + + $("#luckysheet-rich-text-editor").text(value); + formula.updatecell(rowIndex, colIndex); + + e.stopPropagation(); + }); + + //单元格范围 + $(document).off("click.dvRange").on("click.dvRange", "#data-verification-range .fa-table", function(e) { + $("#luckysheet-dataVerification-dialog").hide(); + + let dataSource = "0"; + let txt = $(this).siblings("input").val().trim(); + + _this.rangeDialog(dataSource, txt); + + _this.selectRange = []; + + let range = _this.getRangeByTxt(txt); + if(range.length > 0){ + for(let s = 0; s < range.length; s++){ + let r1 = range[s].row[0], r2 = range[s].row[1]; + let c1 = range[s].column[0], c2 = range[s].column[1]; + + let row = Store.visibledatarow[r2], + row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1]; + let col = Store.visibledatacolumn[c2], + col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1]; + + _this.selectRange.push({ + "left": col_pre, + "width": col - col_pre - 1, + "top": row_pre, + "height": row - row_pre - 1, + "left_move": col_pre, + "width_move": col - col_pre - 1, + "top_move": row_pre, + "height_move": row - row_pre - 1, + "row": [r1, r2], + "column": [c1, c2], + "row_focus": r1, + "column_focus": c1 + }); + } + } + + selectionCopyShow(_this.selectRange); + }); + $(document).off("click.dvRange2").on("click.dvRange2", "#luckysheet-dataVerification-dialog .show-box-item-dropdown .range .fa-table", function(e) { + $("#luckysheet-dataVerification-dialog").hide(); + + let dataSource = "1"; + let txt = $(this).siblings("input").val().trim(); + + _this.rangeDialog(dataSource, txt); + + _this.selectRange = []; + + let range = _this.getRangeByTxt(txt); + if(range.length > 0){ + for(let s = 0; s < range.length; s++){ + let r1 = range[s].row[0], r2 = range[s].row[1]; + let c1 = range[s].column[0], c2 = range[s].column[1]; + + let row = Store.visibledatarow[r2], + row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1]; + let col = Store.visibledatacolumn[c2], + col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1]; + + _this.selectRange.push({ + "left": col_pre, + "width": col - col_pre - 1, + "top": row_pre, + "height": row - row_pre - 1, + "left_move": col_pre, + "width_move": col - col_pre - 1, + "top_move": row_pre, + "height_move": row - row_pre - 1, + "row": [r1, r2], + "column": [c1, c2], + "row_focus": r1, + "column_focus": c1 + }); + } + } + + selectionCopyShow(_this.selectRange); + }); + $(document).off("click.dvRangeConfirm").on("click.dvRangeConfirm", "#luckysheet-dataVerificationRange-dialog-confirm", function(e) { + let dataSource = $(this).attr("data-source"); + let txt = $(this).parents("#luckysheet-dataVerificationRange-dialog").find("input").val(); + + if(_this.getRangeByTxt(txt).length > 1){ + tooltip.info('', '不能对多重选择区域执行此操作,请选择单个区域,然后再试'); + return; + } + + if(dataSource == '0'){ + $("#luckysheet-dataVerification-dialog #data-verification-range input").val(txt); + } + else if(dataSource == '1'){ + $("#luckysheet-dataVerification-dialog .show-box-item-dropdown .range input").val(txt); + } + + $("#luckysheet-dataVerificationRange-dialog").hide(); + $("#luckysheet-modal-dialog-mask").show(); + $("#luckysheet-dataVerification-dialog").show(); + + let range = []; + selectionCopyShow(range); + }); + $(document).off("click.dvRangeClose").on("click.dvRangeClose", "#luckysheet-dataVerificationRange-dialog-close", function(e) { + $("#luckysheet-dataVerificationRange-dialog").hide(); + $("#luckysheet-modal-dialog-mask").show(); + $("#luckysheet-dataVerification-dialog").show(); + + let range = []; + selectionCopyShow(range); + }); + $(document).on("click", "#luckysheet-dataVerificationRange-dialog .luckysheet-modal-dialog-title-close", function(e) { + $("#luckysheet-dataVerificationRange-dialog").hide(); + $("#luckysheet-modal-dialog-mask").show(); + $("#luckysheet-dataVerification-dialog").show(); + + let range = []; + selectionCopyShow(range); + }) + + //验证条件 下拉框 + $(document).off("change.typeSelect").on("change.typeSelect", "#data-verification-type-select", function(e) { + $("#luckysheet-dataVerification-dialog .show-box .show-box-item").hide(); + + let value = this.value; + let item = _this.curItem; + + if(value == 'dropdown'){ + $("#luckysheet-dataVerification-dialog .show-box .show-box-item-dropdown").show(); + + let value1 = ""; + + if(value == item.type){ + value1 = item.value1; + } + + $("#luckysheet-dataVerification-dialog .show-box-item-dropdown .data-verification-value1").val(value1); + } + else if(value == 'checkbox'){ + $("#luckysheet-dataVerification-dialog .show-box .show-box-item-checkbox").show(); + + let value1 = ""; + let value2 = ""; + + if(value == item.type){ + value1 = item.value1; + value2 = item.value2; + } + + $("#luckysheet-dataVerification-dialog .show-box-item-checkbox .data-verification-value1").val(value1); + $("#luckysheet-dataVerification-dialog .show-box-item-checkbox .data-verification-value2").val(value2); + } + else if(value == 'number' || value == 'number_integer' || value == 'number_decimal'){ + $("#luckysheet-dataVerification-dialog .show-box-item-number").show(); + $("#luckysheet-dataVerification-dialog .show-box-item-number .input").hide(); + + let type2 = "bw"; + let value1 = ""; + let value2 = ""; + + if(item.type == 'number' || item.type == 'number_integer' || item.type == 'number_decimal'){ + type2 = item.type2; + value1 = item.value1; + value2 = item.value2; + } + + $("#luckysheet-dataVerification-dialog #data-verification-number-select").val(type2); + + if(type2 == 'bw' || type2 == 'nb'){ + $("#luckysheet-dataVerification-dialog .show-box-item-number .input1").show(); + } + else{ + $("#luckysheet-dataVerification-dialog .show-box-item-number .input2").show(); + } + + $("#luckysheet-dataVerification-dialog .show-box-item-number .data-verification-value1").val(value1); + $("#luckysheet-dataVerification-dialog .show-box-item-number .data-verification-value2").val(value2); + } + else if(value == 'text_content'){ + $("#luckysheet-dataVerification-dialog .show-box-item-text").show(); + + let type2 = "include"; + let value1 = ""; + + if(value == item.type){ + type2 = item.type2; + value1 = item.value1; + } + + $("#luckysheet-dataVerification-dialog #data-verification-text-select").val(type2); + $("#luckysheet-dataVerification-dialog .show-box-item-text .data-verification-value1").val(value1); + } + else if(value == 'text_length'){ + $("#luckysheet-dataVerification-dialog .show-box-item-textLength").show(); + $("#luckysheet-dataVerification-dialog .show-box-item-textLength .input").hide(); + + let type2 = "bw"; + let value1 = ""; + let value2 = ""; + + if(value == item.type){ + type2 = item.type2; + value1 = item.value1; + value2 = item.value2; + } + + $("#luckysheet-dataVerification-dialog #data-verification-textLength-select").val(type2); + + if(type2 == 'bw' || type2 == 'nb'){ + $("#luckysheet-dataVerification-dialog .show-box-item-textLength .input1").show(); + } + else{ + $("#luckysheet-dataVerification-dialog .show-box-item-textLength .input2").show(); + } + + $("#luckysheet-dataVerification-dialog .show-box-item-textLength .data-verification-value1").val(value1); + $("#luckysheet-dataVerification-dialog .show-box-item-textLength .data-verification-value2").val(value2); + } + else if(value == 'date'){ + $("#luckysheet-dataVerification-dialog .show-box-item-date").show(); + $("#luckysheet-dataVerification-dialog .show-box-item-date .input").hide(); + + let type2 = "bw"; + let value1 = ""; + let value2 = ""; + + if(value == item.type){ + type2 = item.type2; + value1 = item.value1; + value2 = item.value2; + } + + $("#luckysheet-dataVerification-dialog #data-verification-date-select").val(type2); + + if(type2 == 'bw' || type2 == 'nb'){ + $("#luckysheet-dataVerification-dialog .show-box-item-date .input1").show(); + } + else{ + $("#luckysheet-dataVerification-dialog .show-box-item-date .input2").show(); + } + + $("#luckysheet-dataVerification-dialog .show-box-item-date .data-verification-value1").val(value1); + $("#luckysheet-dataVerification-dialog .show-box-item-date .data-verification-value2").val(value2); + } + else if(value == 'validity'){ + $("#luckysheet-dataVerification-dialog .show-box .show-box-item-validity").show(); + + let type2 = "card"; + + if(value == item.type){ + type2 = item.type2; + } + + $("#luckysheet-dataVerification-dialog #data-verification-validity-select").val(type2); + } + }); + + $(document).off("change.numberSelect").on("change.numberSelect", "#data-verification-number-select", function(e) { + $("#luckysheet-dataVerification-dialog .show-box-item-number .input").hide(); + + let value = this.value; + + if(value == 'bw' || value == 'nb'){ + $("#luckysheet-dataVerification-dialog .show-box-item-number .input1").show(); + } + else{ + $("#luckysheet-dataVerification-dialog .show-box-item-number .input2").show(); + } + }); + + $(document).off("change.dateSelect").on("change.dateSelect", "#data-verification-date-select", function(e) { + $("#luckysheet-dataVerification-dialog .show-box-item-date .input").hide(); + + let value = this.value; + + if(value == 'bw' || value == 'nb'){ + $("#luckysheet-dataVerification-dialog .show-box-item-date .input1").show(); + } + else{ + $("#luckysheet-dataVerification-dialog .show-box-item-date .input2").show(); + } + }); + + //选中单元格时显示提示语 + $(document).off("change.hintShow").on("change.hintShow", "#data-verification-hint-show", function(e) { + if(this.checked){ + $("#luckysheet-dataVerification-dialog .data-verification-hint-text").show(); + } + else{ + $("#luckysheet-dataVerification-dialog .data-verification-hint-text").hide(); + } + }); + + //确认按钮 + $(document).off("click.confirm").on("click.confirm", "#luckysheet-dataVerification-dialog-confirm", function(e) { + let rangeTxt = $("#luckysheet-dataVerification-dialog #data-verification-range input").val().trim(); + let range = _this.getRangeByTxt(rangeTxt); + + if(range.length == 0){ + tooltip.info('', '请选择单元格范围'); + return; + } + + let type = $("#luckysheet-dataVerification-dialog #data-verification-type-select").val(); + let type2 = null, value1 = "", value2 = ""; + + if(type == 'dropdown'){ + value1 = $("#luckysheet-dataVerification-dialog .show-box-item-dropdown .data-verification-value1").val().trim(); + + if(value1.length == 0){ + tooltip.info('', '下拉列表选项不可为空'); + return; + } + } + else if(type == 'checkbox'){ + value1 = $("#luckysheet-dataVerification-dialog .show-box-item-checkbox .data-verification-value1").val().trim(); + value2 = $("#luckysheet-dataVerification-dialog .show-box-item-checkbox .data-verification-value2").val().trim(); + + if(value1.length == 0 || value2.length == 0){ + tooltip.info('', '复选框内容不可为空'); + return; + } + } + else if(type == 'number' || type == 'number_integer' || type == 'number_decimal'){ + type2 = $("#luckysheet-dataVerification-dialog #data-verification-number-select").val(); + value1 = $("#luckysheet-dataVerification-dialog .show-box-item-number .data-verification-value1").val().trim(); + + if(!isRealNum(value1)){ + tooltip.info('', '输入的值不是数值类型'); + return; + } + + if(type2 == 'bw' || type2 == 'nb'){ + value2 = $("#luckysheet-dataVerification-dialog .show-box-item-number .data-verification-value2").val().trim(); + + if(!isRealNum(value2)){ + tooltip.info('', '输入的值不是数值类型'); + return; + } + + if(Number(value2) < Number(value1)){ + tooltip.info('', '数值2不能小于数值1'); + return; + } + } + } + else if(type == 'text_content'){ + type2 = $("#luckysheet-dataVerification-dialog #data-verification-text-select").val(); + value1 = $("#luckysheet-dataVerification-dialog .show-box-item-text .data-verification-value1").val().trim(); + + if(value1.length == 0){ + tooltip.info('', '文本内容不能为空'); + return; + } + } + else if(type == 'text_length'){ + type2 = $("#luckysheet-dataVerification-dialog #data-verification-textLength-select").val(); + value1 = $("#luckysheet-dataVerification-dialog .show-box-item-textLength .data-verification-value1").val().trim(); + + if(!isRealNum(value1)){ + tooltip.info('', '输入的值不是数值类型'); + return; + } + + if(type2 == 'bw' || type2 == 'nb'){ + value2 = $("#luckysheet-dataVerification-dialog .show-box-item-textLength .data-verification-value2").val().trim(); + + if(!isRealNum(value2)){ + tooltip.info('', '输入的值不是数值类型'); + return; + } + + if(Number(value2) < Number(value1)){ + tooltip.info('', '数值2不能小于数值1'); + return; + } + } + } + else if(type == 'date'){ + type2 = $("#luckysheet-dataVerification-dialog #data-verification-date-select").val(); + value1 = $("#luckysheet-dataVerification-dialog .show-box-item-date .data-verification-value1").val().trim(); + + if(!isdatetime(value1)){ + tooltip.info('', '输入的值不是日期类型'); + return; + } + + if(type2 == 'bw' || type2 == 'nb'){ + value2 = $("#luckysheet-dataVerification-dialog .show-box-item-date .data-verification-value2").val().trim(); + + if(!isdatetime(value2)){ + tooltip.info('', '输入的值不是日期类型'); + return; + } + + if(diff(value1, value2) > 0){ + tooltip.info('', '日期2不能小于日期1'); + return; + } + } + } + else if(type == 'validity'){ + type2 = $("#luckysheet-dataVerification-dialog #data-verification-validity-select").val(); + } + + let remote = $("#luckysheet-dataVerification-dialog #data-verification-remote").is(":checked"); + let prohibitInput = $("#luckysheet-dataVerification-dialog #data-verification-prohibitInput").is(":checked"); + let hintShow = $("#luckysheet-dataVerification-dialog #data-verification-hint-show").is(":checked"); + let hintText = ""; + + if(hintShow){ + hintText = $("#luckysheet-dataVerification-dialog .data-verification-hint-text input").val().trim(); + } + + let item = { + type: type, + type2: type2, + value1: value1, + value2: value2, + checked: false, + remote: remote, + prohibitInput: prohibitInput, + hintShow: hintShow, + hintText: hintText, + } + + let historyDataVerification = $.extend(true, {}, _this.dataVerification); + let currentDataVerification = $.extend(true, {}, _this.dataVerification); + + let str = range[range.length - 1].row[0], + edr = range[range.length - 1].row[1], + stc = range[range.length - 1].column[0], + edc = range[range.length - 1].column[1]; + + let d = editor.deepCopyFlowData(Store.flowdata); + + for(let r = str; r <= edr; r++){ + for(let c = stc; c <= edc; c++){ + currentDataVerification[r + '_' + c] = item; + + if(type == 'checkbox'){ + setcellvalue(r, c, d, item.value2); + } + } + } + + if(type == 'checkbox'){ + _this.refOfCheckbox(historyDataVerification, currentDataVerification, Store.currentSheetIndex, d, range[range.length - 1]); + } + else{ + _this.ref(historyDataVerification, currentDataVerification, Store.currentSheetIndex); + } + + $("#luckysheet-modal-dialog-mask").hide(); + $("#luckysheet-dataVerification-dialog").hide(); + }); + + //删除验证按钮 + $(document).off("click.delete").on("click.delete", "#luckysheet-dataVerification-dialog-delete", function(e) { + $("#luckysheet-modal-dialog-mask").hide(); + $("#luckysheet-dataVerification-dialog").hide(); + }); + + //info提示弹框 关闭 + $(document).on("click", "#luckysheet-info .luckysheet-modal-dialog-title-close, #luckysheet-info .luckysheet-model-close-btn", function(e) { + $(this).parents("#luckysheet-info").hide(); + + if($("#luckysheet-dataVerification-dialog").is(":visible")){ + $("#luckysheet-modal-dialog-mask").show(); + } + e.stopPropagation(); + }); + }, + dataAllocation: function(){ + let _this = this; + + //单元格范围 + let range = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1]; + let rangeTxt = getRangetxt(Store.currentSheetIndex, range, Store.currentSheetIndex); + $("#luckysheet-dataVerification-dialog #data-verification-range input").val(rangeTxt); + + //focus单元格 + let rowIndex = range.row_focus || range.row[0]; + let colIndex = range.column_focus || range.column[0]; + let dataVerification = $.extend(true, {}, _this.dataVerification); + let item = dataVerification[rowIndex + '_' + colIndex]; + + if(item == null){ + item = $.extend(true, {}, _this.defaultItem); + } + + _this.curItem = item; + + //验证条件 + $("#luckysheet-dataVerification-dialog #data-verification-type-select").val(item.type); + $("#luckysheet-dataVerification-dialog .show-box .show-box-item").hide(); + + if(item.type == 'dropdown'){ + $("#luckysheet-dataVerification-dialog .show-box .show-box-item-dropdown").show(); + $("#luckysheet-dataVerification-dialog .show-box-item-dropdown .data-verification-value1").val(item.value1); + } + else if(item.type == 'checkbox'){ + $("#luckysheet-dataVerification-dialog .show-box .show-box-item-checkbox").show(); + $("#luckysheet-dataVerification-dialog .show-box-item-checkbox .data-verification-value1").val(item.value1); + $("#luckysheet-dataVerification-dialog .show-box-item-checkbox .data-verification-value2").val(item.value2); + } + else if(item.type == 'number' || item.type == 'number_integer' || item.type == 'number_decimal'){ + $("#luckysheet-dataVerification-dialog .show-box-item-number").show(); + $("#luckysheet-dataVerification-dialog #data-verification-number-select").val(item.type2); + $("#luckysheet-dataVerification-dialog .show-box-item-number .input").hide(); + + if(item.type2 == 'bw' || item.type2 == 'nb'){ + $("#luckysheet-dataVerification-dialog .show-box-item-number .input1").show(); + } + else{ + $("#luckysheet-dataVerification-dialog .show-box-item-number .input2").show(); + } + + $("#luckysheet-dataVerification-dialog .show-box-item-number .data-verification-value1").val(item.value1); + $("#luckysheet-dataVerification-dialog .show-box-item-number .data-verification-value2").val(item.value2); + } + else if(item.type == 'text_content'){ + $("#luckysheet-dataVerification-dialog .show-box-item-text").show(); + $("#luckysheet-dataVerification-dialog #data-verification-text-select").val(item.type2); + $("#luckysheet-dataVerification-dialog .show-box-item-text .data-verification-value1").val(item.value1); + } + else if(item.type == 'text_length'){ + $("#luckysheet-dataVerification-dialog .show-box-item-textLength").show(); + $("#luckysheet-dataVerification-dialog #data-verification-textLength-select").val(item.type2); + $("#luckysheet-dataVerification-dialog .show-box-item-textLength .input").hide(); + + if(item.type2 == 'bw' || item.type2 == 'nb'){ + $("#luckysheet-dataVerification-dialog .show-box-item-textLength .input1").show(); + } + else{ + $("#luckysheet-dataVerification-dialog .show-box-item-textLength .input2").show(); + } + + $("#luckysheet-dataVerification-dialog .show-box-item-textLength .data-verification-value1").val(item.value1); + $("#luckysheet-dataVerification-dialog .show-box-item-textLength .data-verification-value2").val(item.value2); + } + else if(item.type == 'date'){ + $("#luckysheet-dataVerification-dialog .show-box-item-date").show(); + $("#luckysheet-dataVerification-dialog #data-verification-date-select").val(item.type2); + $("#luckysheet-dataVerification-dialog .show-box-item-date .input").hide(); + + if(item.type2 == 'bw' || item.type2 == 'nb'){ + $("#luckysheet-dataVerification-dialog .show-box-item-date .input1").show(); + } + else{ + $("#luckysheet-dataVerification-dialog .show-box-item-date .input2").show(); + } + + $("#luckysheet-dataVerification-dialog .show-box-item-date .data-verification-value1").val(item.value1); + $("#luckysheet-dataVerification-dialog .show-box-item-date .data-verification-value2").val(item.value2); + } + else if(item.type == 'validity'){ + $("#luckysheet-dataVerification-dialog .show-box .show-box-item-validity").show(); + $("#luckysheet-dataVerification-dialog #data-verification-validity-select").val(item.type2); + } + + //自动远程获取选项 + $("#luckysheet-dataVerification-dialog #data-verification-remote").prop("checked", item.remote); + + //输入数据无效时禁止输入 + $("#luckysheet-dataVerification-dialog #data-verification-prohibitInput").prop("checked", item.prohibitInput); + + //选中单元格时显示提示语 + $("#luckysheet-dataVerification-dialog #data-verification-hint-show").prop("checked", item.hintShow); + + if(item.hintShow){ + $("#luckysheet-dataVerification-dialog .data-verification-hint-text").show(); + } + else{ + $("#luckysheet-dataVerification-dialog .data-verification-hint-text").hide(); + } + + $("#luckysheet-dataVerification-dialog .data-verification-hint-text input").val(item.hintText); + }, + rangeDialog: function(dataSource, txt){ + let _this = this; + + $("#luckysheet-modal-dialog-mask").hide(); + $("#luckysheet-dataVerificationRange-dialog").remove(); + + $("body").append(replaceHtml(modelHTML, { + "id": "luckysheet-dataVerificationRange-dialog", + "addclass": "luckysheet-dataVerificationRange-dialog", + "title": "点击选择单元格范围", + "content": ``, + "botton": ` + `, + "style": "z-index:100003" + })); + let $t = $("#luckysheet-dataVerificationRange-dialog") + .find(".luckysheet-modal-dialog-content") + .css("min-width", 300) + .end(), + myh = $t.outerHeight(), + myw = $t.outerWidth(); + let winw = $(window).width(), winh = $(window).height(); + let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop(); + $("#luckysheet-dataVerificationRange-dialog").css({ + "left": (winw + scrollLeft - myw) / 2, + "top": (winh + scrollTop - myh) / 3 + }).show(); + }, + getTxtByRange: function(range){ + if(range.length > 0){ + let txt = []; + + for(let s = 0; s < range.length; s++){ + let r1 = range[s].row[0], r2 = range[s].row[1]; + let c1 = range[s].column[0], c2 = range[s].column[1]; + + txt.push(getRangetxt(Store.currentSheetIndex, { "row": [r1, r2], "column": [c1, c2] }, Store.currentSheetIndex)); + } + + return txt.join(","); + } + }, + getRangeByTxt: function(txt){ + let range = []; + + if(txt.indexOf(",") != -1){ + let arr = txt.split(","); + for(let i = 0; i < arr.length; i++){ + if(formula.iscelldata(arr[i])){ + range.push(formula.getcellrange(arr[i])); + } + else{ + range = []; + break; + } + } + } + else{ + if(formula.iscelldata(txt)){ + range.push(formula.getcellrange(txt)); + } + } + + return range; + }, + cellFocus: function(r, c, clickMode){ + $("#luckysheet-dataVerification-dropdown-btn").hide(); + $("#luckysheet-dataVerification-showHintBox").hide(); + + let _this = this; + + if(_this.dataVerification == null || _this.dataVerification[r + '_' + c] == null){ + $("#luckysheet-dataVerification-dropdown-List").hide(); + return; + } + + let row = Store.visibledatarow[r], + row_pre = r == 0 ? 0 : Store.visibledatarow[r - 1]; + let col = Store.visibledatacolumn[c], + col_pre = c == 0 ? 0 : Store.visibledatacolumn[c - 1]; + + let margeset = menuButton.mergeborer(Store.flowdata, r, c); + if(!!margeset){ + row = margeset.row[1]; + row_pre = margeset.row[0]; + + col = margeset.column[1]; + col_pre = margeset.column[0]; + } + + let item = _this.dataVerification[r + '_' + c]; + + //单元格数据验证 类型是 复选框 + if(clickMode && item.type == 'checkbox'){ + _this.checkboxChange(r, c); + return; + } + + //单元格数据验证 类型是 下拉列表 + if(item.type == 'dropdown'){ + $("#luckysheet-dataVerification-dropdown-btn").show().css({ + 'max-width': col - col_pre, + 'max-height': row - row_pre, + 'left': col - 20, + 'top': row_pre + (row - row_pre - 20) / 2 + }) + } + else{ + $("#luckysheet-dataVerification-dropdown-List").hide(); + } + + //提示语 + if(item.hintShow){ + let hintText = item.hintText; + + if(hintText.length == 0){ + hintText += '提示:'; + + if(item.type == 'dropdown'){ + hintText += '请选择下拉列表中的选项'; + } + else if(item.type == 'checkbox'){ + + } + else if(item.type == 'number' || item.type == 'number_integer' || item.type == 'number_decimal'){ + hintText += '请输入' + _this.optionLabel[item.type2] + item.value1; + + if(item.type2 == 'bw' || item.type2 == 'nb'){ + hintText += '和' + item.value2 + '之间'; + } + + hintText += '的' + _this.optionLabel[item.type]; + } + else if(item.type == 'text_content'){ + hintText += '请输入内容' + _this.optionLabel[item.type2] + item.value1 + '的文本'; + } + else if(item.type == 'text_length'){ + hintText += '请输入长度' + _this.optionLabel[item.type2] + item.value1; + + if(item.type2 == 'bw' || item.type2 == 'nb'){ + hintText += '和' + item.value2 + '之间'; + } + + hintText += '的文本'; + } + else if(item.type == 'date'){ + hintText += '请输入' + _this.optionLabel[item.type2] + item.value1; + + if(item.type2 == 'bw' || item.type2 == 'nb'){ + hintText += '和' + item.value2 + '之间'; + } + + hintText += '的日期'; + } + else if(item.type == 'validity'){ + hintText += '请输入正确的' + _this.optionLabel[item.type2]; + } + } + else{ + hintText = '提示:' + hintText; + } + + $("#luckysheet-dataVerification-showHintBox").html(hintText).show().css({ + 'left': col_pre, + 'top': row + }); + + return; + } + + //数据验证未通过 + let cellValue = getcellvalue(r, c, null, 'm'); + + if(cellValue == null || cellValue == ""){ + return; + } + + let validate = _this.validateCellData(cellValue, item); + + if(!validate){ + let hintText = '失效:'; + + if(item.type == 'dropdown'){ + hintText += '你选择的不是下拉列表中的选项'; + } + else if(item.type == 'checkbox'){ + + } + else if(item.type == 'number' || item.type == 'number_integer' || item.type == 'number_decimal'){ + hintText += '你输入的不是' + _this.optionLabel[item.type2] + item.value1; + + if(item.type2 == 'bw' || item.type2 == 'nb'){ + hintText += '和' + item.value2 + '之间'; + } + + hintText += '的' + _this.optionLabel[item.type]; + } + else if(item.type == 'text_content'){ + hintText += '你输入的不是内容' + _this.optionLabel[item.type2] + item.value1 + '的文本'; + } + else if(item.type == 'text_length'){ + hintText += '你输入的不是长度' + _this.optionLabel[item.type2] + item.value1; + + if(item.type2 == 'bw' || item.type2 == 'nb'){ + hintText += '和' + item.value2 + '之间'; + } + + hintText += '的文本'; + } + else if(item.type == 'date'){ + hintText += '你输入的不是' + _this.optionLabel[item.type2] + item.value1; + + if(item.type2 == 'bw' || item.type2 == 'nb'){ + hintText += '和' + item.value2 + '之间'; + } + + hintText += '的日期'; + } + else if(item.type == 'validity'){ + hintText += '你输入的不是一个正确的' + _this.optionLabel[item.type2]; + } + + $("#luckysheet-dataVerification-showHintBox").html(hintText).show().css({ + 'left': col_pre, + 'top': row + }); + } + }, + validateCellData: function(cellValue, item){ + let _this = this; + + let type = item.type, + type2 = item.type2, + value1 = item.value1, + value2 = item.value2; + + if(type == 'dropdown'){ + let list = _this.getDropdownList(value1); + + if(!list.includes(cellValue)){ + return false; + } + } + else if(type == 'checkbox'){ + + } + else if(type == 'number' || type == 'number_integer' || type == 'number_decimal'){ + if(!isRealNum(cellValue)){ + return false; + } + + cellValue = Number(cellValue); + + if(type == 'number_integer' && cellValue % 1 !== 0){ + return false; + } + + if(type == 'number_decimal' && cellValue % 1 === 0){ + return false; + } + + value1 = Number(value1); + value2 = Number(value2); + + if(type2 == 'bw' && (cellValue < value1 || cellValue > value2)){ + return false; + } + + if(type2 == 'nb' && (cellValue >= value1 && cellValue <= value2)){ + return false; + } + + if(type2 == 'eq' && cellValue != value1){ + return false; + } + + if(type2 == 'ne' && cellValue == value1){ + return false; + } + + if(type2 == 'gt' && cellValue <= value1){ + return false; + } + + if(type2 == 'lt' && cellValue >= value1){ + return false; + } + + if(type2 == 'gte' && cellValue < value1){ + return false; + } + + if(type2 == 'lte' && cellValue > value1){ + return false; + } + } + else if(type == 'text_content'){ + cellValue = cellValue.toString(); + value1 = value1.toString(); + + if(type2 == 'include' && cellValue.indexOf(value1) == -1){ + return false; + } + + if(type2 == 'exclude' && cellValue.indexOf(value1) > -1){ + return false; + } + + if(type2 == 'equal' && cellValue != value1){ + return false; + } + } + else if(type == 'text_length'){ + cellValue = cellValue.toString().length; + + value1 = Number(value1); + value2 = Number(value2); + + if(type2 == 'bw' && (cellValue < value1 || cellValue > value2)){ + return false; + } + + if(type2 == 'nb' && (cellValue >= value1 && cellValue <= value2)){ + return false; + } + + if(type2 == 'eq' && cellValue != value1){ + return false; + } + + if(type2 == 'ne' && cellValue == value1){ + return false; + } + + if(type2 == 'gt' && cellValue <= value1){ + return false; + } + + if(type2 == 'lt' && cellValue >= value1){ + return false; + } + + if(type2 == 'gte' && cellValue < value1){ + return false; + } + + if(type2 == 'lte' && cellValue > value1){ + return false; + } + } + else if(type == 'date'){ + if(!isdatetime(cellValue)){ + return false; + } + + if(type2 == 'bw' && (diff(cellValue, value1) < 0 || diff(cellValue, value2) > 0)){ + return false; + } + + if(type2 == 'nb' && (diff(cellValue, value1) >= 0 && diff(cellValue, value2) <= 0)){ + return false; + } + + if(type2 == 'eq' && diff(cellValue, value1) != 0){ + return false; + } + + if(type2 == 'ne' && diff(cellValue, value1) == 0){ + return false; + } + + if(type2 == 'bf' && diff(cellValue, value1) >= 0){ + return false; + } + + if(type2 == 'nbf' && diff(cellValue, value1) < 0){ + return false; + } + + if(type2 == 'af' && diff(cellValue, value1) <= 0){ + return false; + } + + if(type2 == 'naf' && diff(cellValue, value1) > 0){ + return false; + } + } + else if(type == 'validity'){ + if(type2 == 'card' && !/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(cellValue)){ + return false; + } + + if(type2 == 'phone' && !/^[1][3,4,5,7,8][0-9]{9}$/.test(cellValue)){ + return false; + } + } + + return true; + }, + dropdownListShow: function(){ + $("#luckysheet-dataVerification-showHintBox").hide(); + + let _this = this; + + let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1]; + let rowIndex = last.row_focus; + let colIndex = last.column_focus; + + let row = Store.visibledatarow[rowIndex], + row_pre = rowIndex == 0 ? 0 : Store.visibledatarow[rowIndex - 1]; + let col = Store.visibledatacolumn[colIndex], + col_pre = colIndex == 0 ? 0 : Store.visibledatacolumn[colIndex - 1]; + + let margeset = menuButton.mergeborer(Store.flowdata, rowIndex, colIndex); + if(!!margeset){ + row = margeset.row[1]; + row_pre = margeset.row[0]; + + col = margeset.column[1]; + col_pre = margeset.column[0]; + } + + let item = _this.dataVerification[rowIndex + '_' + colIndex]; + let list = _this.getDropdownList(item.value1); + + let optionHtml = ''; + list.forEach(i => { + optionHtml += ``; + }) + + $("#luckysheet-dataVerification-dropdown-List").html(optionHtml).show().css({ + 'width': col - col_pre - 1, + 'left': col_pre, + 'top': row, + }); + }, + getDropdownList: function(txt){ + let list = []; + + if(formula.iscelldata(txt)){ + let range = formula.getcellrange(txt); + let d = Store.luckysheetfile[getSheetIndex(range.sheetIndex)].data; + + for(let r = range.row[0]; r <= range.row[1]; r++){ + for(let c = range.column[0]; c <= range.column[1]; c++){ + if(d[r] == null){ + continue; + } + + let cell = d[r][c]; + + if(cell == null || cell.v == null){ + continue; + } + + let v = cell.m || cell.v; + + if(!list.includes(v)){ + list.push(v); + } + } + } + } + else{ + let arr = txt.split(","); + + for(let i = 0; i < arr.length; i++){ + let v = arr[i]; + + if(v.length == 0){ + continue; + } + + if(!list.includes(v)){ + list.push(v); + } + } + } + + return list; + }, + checkboxChange: function(r, c){ + let _this = this; + + let historyDataVerification = $.extend(true, {}, _this.dataVerification); + let currentDataVerification = $.extend(true, {}, _this.dataVerification); + + let item = currentDataVerification[r + '_' + c]; + item.checked = !item.checked; + + let value = item.value2; + if(item.checked){ + value = item.value1; + } + + let d = editor.deepCopyFlowData(Store.flowdata); + setcellvalue(r, c, d, value); + + _this.refOfCheckbox( + historyDataVerification, + currentDataVerification, + Store.currentSheetIndex, + d, + { "row": [r, r], "column": [c, c] } + ); + }, + ref: function(historyDataVerification, currentDataVerification, sheetIndex){ + let _this = this; + + if (Store.clearjfundo) { + Store.jfundo = []; + + let redo = {}; + redo["type"] = "updateDataVerification"; + redo["sheetIndex"] = sheetIndex; + redo["historyDataVerification"] = historyDataVerification; + redo["currentDataVerification"] = currentDataVerification; + Store.jfredo.push(redo); + } + + _this.dataVerification = currentDataVerification; + Store.luckysheetfile[getSheetIndex(sheetIndex)].dataVerification = currentDataVerification; + + //共享编辑模式 + if(server.allowUpdate){ + server.saveParam("all", sheetIndex, currentDataVerification, { "k": "dataVerification" }); + } + + setTimeout(function () { + luckysheetrefreshgrid(); + }, 1); + }, + refOfCheckbox: function(historyDataVerification, currentDataVerification, sheetIndex, d, range){ + let _this = this; + + if (Store.clearjfundo) { + Store.jfundo = []; + + let redo = {}; + redo["type"] = "updateDataVerificationOfCheckbox"; + redo["sheetIndex"] = sheetIndex; + redo["historyDataVerification"] = historyDataVerification; + redo["currentDataVerification"] = currentDataVerification; + redo["data"] = Store.flowdata; + redo["curData"] = d; + redo["range"] = range; + Store.jfredo.push(redo); + } + + _this.dataVerification = currentDataVerification; + Store.luckysheetfile[getSheetIndex(sheetIndex)].dataVerification = currentDataVerification; + + Store.flowdata = d; + editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据 + Store.luckysheetfile[getSheetIndex(sheetIndex)].data = Store.flowdata; + + //共享编辑模式 + if(server.allowUpdate){ + server.saveParam("all", sheetIndex, currentDataVerification, { "k": "dataVerification" }); + server.historyParam(Store.flowdata, sheetIndex, range); + } + + setTimeout(function () { + luckysheetrefreshgrid(); + }, 1); + }, +} + +export default dataVerificationCtrl; \ No newline at end of file diff --git a/src/controllers/dropCell.js b/src/controllers/dropCell.js index 0c728a3..550be2c 100644 --- a/src/controllers/dropCell.js +++ b/src/controllers/dropCell.js @@ -450,6 +450,7 @@ const luckysheetDropCell = { let cfg = $.extend(true, {}, Store.config); let borderInfoCompute = getBorderInfoCompute(); + let dataVerification = $.extend(true, {}, file["dataVerification"]); let direction = _this.direction; let type = _this.applyType; @@ -563,6 +564,11 @@ const luckysheetDropCell = { cfg["borderInfo"].push(bd_obj); } + + //数据验证 + if(dataVerification[bd_r + "_" + bd_c]){ + dataVerification[j + "_" + i] = dataVerification[bd_r + "_" + bd_c]; + } } } if(direction == "up"){ @@ -647,6 +653,11 @@ const luckysheetDropCell = { cfg["borderInfo"].push(bd_obj); } + + //数据验证 + if(dataVerification[bd_r + "_" + bd_c]){ + dataVerification[j + "_" + i] = dataVerification[bd_r + "_" + bd_c]; + } } } } @@ -741,6 +752,11 @@ const luckysheetDropCell = { cfg["borderInfo"].push(bd_obj); } + + //数据验证 + if(dataVerification[bd_r + "_" + bd_c]){ + dataVerification[i + "_" + j] = dataVerification[bd_r + "_" + bd_c]; + } } } if(direction == "left"){ @@ -825,6 +841,11 @@ const luckysheetDropCell = { cfg["borderInfo"].push(bd_obj); } + + //数据验证 + if(dataVerification[bd_r + "_" + bd_c]){ + dataVerification[i + "_" + j] = dataVerification[bd_r + "_" + bd_c]; + } } } } @@ -852,7 +873,7 @@ const luckysheetDropCell = { } //刷新一次表格 - jfrefreshgrid(d, Store.luckysheet_select_save, cfg, cdformat); + jfrefreshgrid(d, Store.luckysheet_select_save, cfg, cdformat, null, dataVerification); selectHightlightShow(); }, diff --git a/src/controllers/handler.js b/src/controllers/handler.js index a4c7fc4..17e2795 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 dataVerificationCtrl from './dataVerificationCtrl'; import menuButton from './menuButton'; import conditionformat from './conditionformat'; import alternateformat from './alternateformat'; @@ -233,6 +234,10 @@ export default function luckysheetHandler() { //表格mousedown $("#luckysheet-cell-main, #luckysheetTableContent").mousedown(function (event) { + if($(event.target).hasClass('luckysheet-mousedown-cancel')){ + return; + } + $("#luckysheet-cell-selected").find(".luckysheet-cs-fillhandle") .css("cursor","default") .end() @@ -289,6 +294,9 @@ export default function luckysheetHandler() { col_index_ed = margeset.column[3]; } + //数据验证 单元格聚焦 + dataVerificationCtrl.cellFocus(row_index, col_index, true); + //若点击单元格部分不在视图内 if (col_pre < $("#luckysheet-cell-main").scrollLeft()) { $("#luckysheet-scrollbar-x").scrollLeft(col_pre); @@ -300,6 +308,8 @@ export default function luckysheetHandler() { //mousedown是右键 if (event.which == "3") { + $("#luckysheet-dataVerification-showHintBox").hide(); + let isright = false; for (let s = 0; s < Store.luckysheet_select_save.length; s++) { @@ -669,6 +679,134 @@ export default function luckysheetHandler() { return; } + //数据验证 单元格范围选择 + if($("#luckysheet-dataVerificationRange-dialog").is(":visible")){ + dataVerificationCtrl.selectStatus = true; + Store.luckysheet_select_status = false; + + if (event.shiftKey) { + let last = dataVerificationCtrl.selectRange[dataVerificationCtrl.selectRange.length - 1]; + + let top = 0, height = 0, rowseleted = []; + if (last.top > row_pre) { + top = row_pre; + height = last.top + last.height - row_pre; + + if (last.row[1] > last.row_focus) { + last.row[1] = last.row_focus; + } + + rowseleted = [row_index, last.row[1]]; + } + else if (last.top == row_pre) { + top = row_pre; + height = last.top + last.height - row_pre; + rowseleted = [row_index, last.row[0]]; + } + else { + top = last.top; + height = row - last.top - 1; + + if (last.row[0] < last.row_focus) { + last.row[0] = last.row_focus; + } + + rowseleted = [last.row[0], row_index]; + } + + let left = 0, width = 0, columnseleted = []; + if (last.left > col_pre) { + left = col_pre; + width = last.left + last.width - col_pre; + + if (last.column[1] > last.column_focus) { + last.column[1] = last.column_focus; + } + + columnseleted = [col_index, last.column[1]]; + } + else if (last.left == col_pre) { + left = col_pre; + width = last.left + last.width - col_pre; + columnseleted = [col_index, last.column[0]]; + } + else { + left = last.left; + width = col - last.left - 1; + + if (last.column[0] < last.column_focus) { + last.column[0] = last.column_focus; + } + + columnseleted = [last.column[0], col_index]; + } + + let changeparam = menuButton.mergeMoveMain(columnseleted, rowseleted, last, top, height, left, width); + if (changeparam != null) { + columnseleted = changeparam[0]; + rowseleted = changeparam[1]; + top = changeparam[2]; + height = changeparam[3]; + left = changeparam[4]; + width = changeparam[5]; + } + + last["row"] = rowseleted; + last["column"] = columnseleted; + + last["left_move"] = left; + last["width_move"] = width; + last["top_move"] = top; + last["height_move"] = height; + + dataVerificationCtrl.selectRange[dataVerificationCtrl.selectRange.length - 1] = last; + } + else if (event.ctrlKey) { + dataVerificationCtrl.selectRange.push({ + "left": col_pre, + "width": col - col_pre - 1, + "top": row_pre, + "height": row - row_pre - 1, + "left_move": col_pre, + "width_move": col - col_pre - 1, + "top_move": row_pre, + "height_move": row - row_pre - 1, + "row": [row_index, row_index_ed], + "column": [col_index, col_index_ed], + "row_focus": row_index, + "column_focus": col_index + }); + } + else { + dataVerificationCtrl.selectRange = []; + dataVerificationCtrl.selectRange.push({ + "left": col_pre, + "width": col - col_pre - 1, + "top": row_pre, + "height": row - row_pre - 1, + "left_move": col_pre, + "width_move": col - col_pre - 1, + "top_move": row_pre, + "height_move": row - row_pre - 1, + "row": [row_index, row_index_ed], + "column": [col_index, col_index_ed], + "row_focus": row_index, + "column_focus": col_index + }); + } + + selectionCopyShow(dataVerificationCtrl.selectRange); + + let range = dataVerificationCtrl.getTxtByRange(dataVerificationCtrl.selectRange); + $("#luckysheet-dataVerificationRange-dialog input").val(range); + + return; + } + else{ + dataVerificationCtrl.selectStatus = false; + dataVerificationCtrl.selectRange = []; + } + //if公式生成器 if (ifFormulaGenerator.singleRangeFocus) { $("#luckysheet-ifFormulaGenerator-dialog .singRange").click(); @@ -1023,6 +1161,10 @@ export default function luckysheetHandler() { showrightclickmenu($("#luckysheet-rightclick-menu"), x, y); } }).dblclick(function (event) { + if($(event.target).hasClass('luckysheet-mousedown-cancel')){ + return; + } + //禁止前台编辑(只可 框选单元格、滚动查看表格) if (!Store.allowEdit) { return; @@ -1569,6 +1711,101 @@ export default function luckysheetHandler() { let range = conditionformat.getTxtByRange(conditionformat.selectRange); $("#luckysheet-multiRange-dialog input").val(range); } + else if (dataVerificationCtrl.selectStatus) { + let mouse = mouseposition(event.pageX, event.pageY); + let x = mouse[0] + $("#luckysheet-cell-main").scrollLeft(); + let y = mouse[1] + $("#luckysheet-cell-main").scrollTop(); + + let row_location = rowLocation(y), + row = row_location[1], + row_pre = row_location[0], + row_index = row_location[2]; + let col_location = colLocation(x), + col = col_location[1], + col_pre = col_location[0], + col_index = col_location[2]; + + let last = dataVerificationCtrl.selectRange[dataVerificationCtrl.selectRange.length - 1]; + + let top = 0, height = 0, rowseleted = []; + if (last.top > row_pre) { + top = row_pre; + height = last.top + last.height - row_pre; + + if (last.row[1] > last.row_focus) { + last.row[1] = last.row_focus; + } + + rowseleted = [row_index, last.row[1]]; + } + else if (last.top == row_pre) { + top = row_pre; + height = last.top + last.height - row_pre; + rowseleted = [row_index, last.row[0]]; + } + else { + top = last.top; + height = row - last.top - 1; + + if (last.row[0] < last.row_focus) { + last.row[0] = last.row_focus; + } + + rowseleted = [last.row[0], row_index]; + } + + let left = 0, width = 0, columnseleted = []; + if (last.left > col_pre) { + left = col_pre; + width = last.left + last.width - col_pre; + + if (last.column[1] > last.column_focus) { + last.column[1] = last.column_focus; + } + + columnseleted = [col_index, last.column[1]]; + } + else if (last.left == col_pre) { + left = col_pre; + width = last.left + last.width - col_pre; + columnseleted = [col_index, last.column[0]]; + } + else { + left = last.left; + width = col - last.left - 1; + + if (last.column[0] < last.column_focus) { + last.column[0] = last.column_focus; + } + + columnseleted = [last.column[0], col_index]; + } + + let changeparam = menuButton.mergeMoveMain(columnseleted, rowseleted, last, top, height, left, width); + if (changeparam != null) { + columnseleted = changeparam[0]; + rowseleted = changeparam[1]; + top = changeparam[2]; + height = changeparam[3]; + left = changeparam[4]; + width = changeparam[5]; + } + + last["row"] = rowseleted; + last["column"] = columnseleted; + + last["left_move"] = left; + last["width_move"] = width; + last["top_move"] = top; + last["height_move"] = height; + + dataVerificationCtrl.selectRange[dataVerificationCtrl.selectRange.length - 1] = last; + + selectionCopyShow(dataVerificationCtrl.selectRange); + + let range = dataVerificationCtrl.getTxtByRange(dataVerificationCtrl.selectRange); + $("#luckysheet-dataVerificationRange-dialog input").val(range); + } else if (formula.rangestart) { formula.rangedrag(event); } @@ -4055,6 +4292,16 @@ export default function luckysheetHandler() { } }); + //菜单栏 数据验证按钮 + $("#luckysheet-dataVerification-btn-title").click(function () { + if (Store.luckysheet_select_save == null || Store.luckysheet_select_save.length == 0) { + return; + } + + dataVerificationCtrl.createDialog(); + dataVerificationCtrl.init(); + }) + //冻结行列 $("#luckysheet-freezen-btn-horizontal").click(function () { if ($.trim($(this).text()) == locale().freezen.freezenCancel) { @@ -4396,19 +4643,6 @@ export default function luckysheetHandler() { clipboardData = e.originalEvent.clipboardData; } - //复制的是图片 - if(clipboardData.files.length == 1 && clipboardData.files[0].type.indexOf('image') > -1){ - let render = new FileReader(); - render.readAsDataURL(clipboardData.files[0]); - - render.onload = function(event){ - let src = event.target.result; - imageCtrl.inserImg(src); - } - - return; - } - let txtdata = clipboardData.getData("text/html"); //如果标示是qksheet复制的内容,判断剪贴板内容是否是当前页面复制的内容 @@ -4490,7 +4724,6 @@ export default function luckysheetHandler() { } } - const locale_fontjson = locale().fontjson; if (txtdata.indexOf("luckysheet_copy_action_table") > - 1 && Store.luckysheet_copy_save["copyRange"] != null && Store.luckysheet_copy_save["copyRange"].length > 0 && isEqual) { @@ -4726,6 +4959,18 @@ export default function luckysheetHandler() { selection.pasteHandler(data, borderInfo); $("#luckysheet-copy-content").empty(); } + //复制的是图片 + else if(clipboardData.files.length == 1 && clipboardData.files[0].type.indexOf('image') > -1){ + let render = new FileReader(); + render.readAsDataURL(clipboardData.files[0]); + + render.onload = function(event){ + let src = event.target.result; + imageCtrl.inserImg(src); + } + + return; + } else { txtdata = clipboardData.getData("text/plain"); selection.pasteHandler(txtdata); diff --git a/src/controllers/pivotTable.js b/src/controllers/pivotTable.js index 3cb8692..87c0f1c 100644 --- a/src/controllers/pivotTable.js +++ b/src/controllers/pivotTable.js @@ -733,7 +733,7 @@ const pivotTable = { jfrefreshgridall(data[0].length, data.length, data, null, Store.luckysheet_select_save, "datachangeAll", undefined, undefined,isRefreshCanvas); } else { - jfrefreshgrid(data, Store.luckysheet_select_save, undefined, undefined, undefined, undefined,isRefreshCanvas); + jfrefreshgrid(data, Store.luckysheet_select_save, undefined, undefined, undefined, undefined, undefined,isRefreshCanvas); selectHightlightShow(); } diff --git a/src/controllers/select.js b/src/controllers/select.js index 2ab6b17..88f71a8 100644 --- a/src/controllers/select.js +++ b/src/controllers/select.js @@ -3,6 +3,7 @@ import formula from '../global/formula'; import { dynamicArrayHightShow } from '../global/dynamicArray'; import { rowLocationByIndex, colLocationByIndex } from '../global/location'; import browser from '../global/browser'; +import dataVerificationCtrl from './dataVerificationCtrl'; import { getSheetIndex, getRangetxt } from '../methods/get'; import Store from '../store'; import locale from '../locale/locale'; @@ -163,6 +164,8 @@ function selectHightlightShow() { ); //左上角选择区域框 formula.fucntionboxshow(rf, cf); + //focus单元格数据验证 + dataVerificationCtrl.cellFocus(rf, cf); } } diff --git a/src/controllers/selection.js b/src/controllers/selection.js index 73ac1c0..f9d37f9 100644 --- a/src/controllers/selection.js +++ b/src/controllers/selection.js @@ -799,9 +799,10 @@ const selection = { } }, pasteHandlerOfCutPaste: function(copyRange){ - if(Store.allowEdit===false){ + if(Store.allowEdit === false){ return; } + let cfg = $.extend(true, {}, Store.config); if(cfg["merge"] == null){ cfg["merge"] = {}; @@ -810,9 +811,14 @@ const selection = { //复制范围 let copyHasMC = copyRange["HasMC"]; let copyRowlChange = copyRange["RowlChange"]; - let copySheetIndex = copyRange["dataSheetIndex"]; - let copyData = $.extend(true, [], getdatabyselection({"row": copyRange["copyRange"][0].row, "column": copyRange["copyRange"][0].column}, copySheetIndex)); + + let c_r1 = copyRange["copyRange"][0].row[0], + c_r2 = copyRange["copyRange"][0].row[1], + c_c1 = copyRange["copyRange"][0].column[0], + c_c2 = copyRange["copyRange"][0].column[1]; + + let copyData = $.extend(true, [], getdatabyselection({"row": [c_r1, c_r2], "column": [c_c1, c_c2]}, copySheetIndex)); let copyh = copyData.length, copyc = copyData[0].length; @@ -847,11 +853,13 @@ const selection = { } let borderInfoCompute = getBorderInfoCompute(copySheetIndex); + let c_dataVerification = $.extend(true, {}, Store.luckysheetfile[getSheetIndex(copySheetIndex)]["dataVerification"]); + let dataVerification = $.extend(true, {}, Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dataVerification"]); - //剪切粘贴在当前表操作,删除剪切范围内数据和合并单元格 + //剪切粘贴在当前表操作,删除剪切范围内数据、合并单元格和数据验证 if(Store.currentSheetIndex == copySheetIndex){ - for(let i = copyRange["copyRange"][0].row[0]; i <= copyRange["copyRange"][0].row[1]; i++){ - for(let j = copyRange["copyRange"][0].column[0]; j <= copyRange["copyRange"][0].column[1]; j++){ + for(let i = c_r1; i <= c_r2; i++){ + for(let j = c_c1; j <= c_c2; j++){ let cell = d[i][j]; if(getObjType(cell) == "object" && ("mc" in cell)){ @@ -862,6 +870,8 @@ const selection = { } d[i][j] = null; + + delete dataVerification[i + "_" + j]; } } @@ -877,7 +887,12 @@ const selection = { let bd_emptyRange = []; for(let j = 0; j < bd_range.length; j++){ - bd_emptyRange = bd_emptyRange.concat(conditionformat.CFSplitRange(bd_range[j], {"row": copyRange["copyRange"][0].row, "column": copyRange["copyRange"][0].column}, {"row": [minh, maxh], "column": [minc, maxc]}, "restPart")); + bd_emptyRange = bd_emptyRange.concat(conditionformat.CFSplitRange( + bd_range[j], + {"row": [c_r1, c_r2], "column": [c_c1, c_c2]}, + {"row": [minh, maxh], "column": [minc, maxc]}, + "restPart" + )); } cfg["borderInfo"][i].range = bd_emptyRange; @@ -888,7 +903,7 @@ const selection = { let bd_r = cfg["borderInfo"][i].value.row_index; let bd_c = cfg["borderInfo"][i].value.col_index; - if(!(bd_r >= copyRange["copyRange"][0].row[0] && bd_r <= copyRange["copyRange"][0].row[1] && bd_c >= copyRange["copyRange"][0].column[0] && bd_c <= copyRange["copyRange"][0].column[1])){ + if(!(bd_r >= c_r1 && bd_r <= c_r2 && bd_c >= c_c1 && bd_c <= c_c2)){ source_borderInfo.push(cfg["borderInfo"][i]); } } @@ -903,16 +918,16 @@ const selection = { let x = [].concat(d[h]); for (let c = minc; c <= maxc; c++) { - if(borderInfoCompute[(copyRange["copyRange"][0].row[0] + h - minh) + "_" + (copyRange["copyRange"][0].column[0] + c - minc)]){ + if(borderInfoCompute[(c_r1 + h - minh) + "_" + (c_c1 + c - minc)]){ let bd_obj = { "rangeType": "cell", "value": { "row_index": h, "col_index": c, - "l": borderInfoCompute[(copyRange["copyRange"][0].row[0] + h - minh) + "_" + (copyRange["copyRange"][0].column[0] + c - minc)].l, - "r": borderInfoCompute[(copyRange["copyRange"][0].row[0] + h - minh) + "_" + (copyRange["copyRange"][0].column[0] + c - minc)].r, - "t": borderInfoCompute[(copyRange["copyRange"][0].row[0] + h - minh) + "_" + (copyRange["copyRange"][0].column[0] + c - minc)].t, - "b": borderInfoCompute[(copyRange["copyRange"][0].row[0] + h - minh) + "_" + (copyRange["copyRange"][0].column[0] + c - minc)].b + "l": borderInfoCompute[(c_r1 + h - minh) + "_" + (c_c1 + c - minc)].l, + "r": borderInfoCompute[(c_r1 + h - minh) + "_" + (c_c1 + c - minc)].r, + "t": borderInfoCompute[(c_r1 + h - minh) + "_" + (c_c1 + c - minc)].t, + "b": borderInfoCompute[(c_r1 + h - minh) + "_" + (c_c1 + c - minc)].b } } @@ -942,6 +957,11 @@ const selection = { cfg["borderInfo"].push(bd_obj); } + //数据验证 剪切 + if(c_dataVerification[(c_r1 + h - minh) + "_" + (c_c1 + c - minc)]){ + dataVerification[h + "_" + c] = c_dataVerification[(c_r1 + h - minh) + "_" + (c_c1 + c - minc)]; + } + if(getObjType(x[c]) == "object" && ("mc" in x[c])){ if("rs" in x[c].mc){ delete cfg["merge"][x[c]["mc"].r + "_" + x[c]["mc"].c]; @@ -983,7 +1003,7 @@ const selection = { cfg = rowlenByRange(d, minh, maxh, cfg); } else{ - cfg = rowlenByRange(d, copyRange["copyRange"][0].row[0], copyRange["copyRange"][0].row[1], cfg); + cfg = rowlenByRange(d, c_r1, c_r2, cfg); cfg = rowlenByRange(d, minh, maxh, cfg); } } @@ -1000,13 +1020,8 @@ const selection = { sourceCurConfig["merge"] = {}; } - let source_r1 = copyRange["copyRange"][0].row[0], - source_r2 = copyRange["copyRange"][0].row[1]; - let source_c1 = copyRange["copyRange"][0].column[0], - source_c2 = copyRange["copyRange"][0].column[1]; - - for(let source_r = source_r1; source_r <= source_r2; source_r++){ - for(let source_c = source_c1; source_c <= source_c2; source_c++){ + for(let source_r = c_r1; source_r <= c_r2; source_r++){ + for(let source_c = c_c1; source_c <= c_c2; source_c++){ let cell = sourceCurData[source_r][source_c]; if(getObjType(cell) == "object" && ("mc" in cell)){ @@ -1020,7 +1035,7 @@ const selection = { } if(copyRowlChange){ - sourceCurConfig = rowlenByRange(sourceCurData, source_r1, source_r2, sourceCurConfig); + sourceCurConfig = rowlenByRange(sourceCurData, c_r1, c_r2, sourceCurConfig); } //边框 @@ -1035,7 +1050,12 @@ const selection = { let bd_emptyRange = []; for(let j = 0; j < bd_range.length; j++){ - bd_emptyRange = bd_emptyRange.concat(conditionformat.CFSplitRange(bd_range[j], {"row": copyRange["copyRange"][0].row, "column": copyRange["copyRange"][0].column}, {"row": [minh, maxh], "column": [minc, maxc]}, "restPart")); + bd_emptyRange = bd_emptyRange.concat(conditionformat.CFSplitRange( + bd_range[j], + {"row": [c_r1, c_r2], "column": [c_c1, c_c2]}, + {"row": [minh, maxh], "column": [minc, maxc]}, + "restPart" + )); } sourceCurConfig["borderInfo"][i].range = bd_emptyRange; @@ -1046,7 +1066,7 @@ const selection = { let bd_r = sourceCurConfig["borderInfo"][i].value.row_index; let bd_c = sourceCurConfig["borderInfo"][i].value.col_index; - if(!(bd_r >= copyRange["copyRange"][0].row[0] && bd_r <= copyRange["copyRange"][0].row[1] && bd_c >= copyRange["copyRange"][0].column[0] && bd_c <= copyRange["copyRange"][0].column[1])){ + if(!(bd_r >= c_r1 && bd_r <= c_r2 && bd_c >= c_c1 && bd_c <= c_c2)){ source_borderInfo.push(sourceCurConfig["borderInfo"][i]); } } @@ -1066,10 +1086,22 @@ const selection = { let emptyRange2 = []; for(let j = 0; j < source_curCdformat_cellrange.length; j++){ - let range = conditionformat.CFSplitRange(source_curCdformat_cellrange[j], {"row": copyRange["copyRange"][0].row, "column": copyRange["copyRange"][0].column}, {"row": [minh, maxh], "column": [minc, maxc]}, "restPart"); + let range = conditionformat.CFSplitRange( + source_curCdformat_cellrange[j], + {"row": [c_r1, c_r2], "column": [c_c1, c_c2]}, + {"row": [minh, maxh], "column": [minc, maxc]}, + "restPart" + ); + emptyRange = emptyRange.concat(range); - let range2 = conditionformat.CFSplitRange(source_curCdformat_cellrange[j], {"row": copyRange["copyRange"][0].row, "column": copyRange["copyRange"][0].column}, {"row": [minh, maxh], "column": [minc, maxc]}, "operatePart"); + let range2 = conditionformat.CFSplitRange( + source_curCdformat_cellrange[j], + {"row": [c_r1, c_r2], "column": [c_c1, c_c2]}, + {"row": [minh, maxh], "column": [minc, maxc]}, + "operatePart" + ); + if(range2.length > 0){ emptyRange2 = emptyRange2.concat(range2); } @@ -1091,6 +1123,13 @@ const selection = { target_curCdformat = target_curCdformat.concat(ruleArr); } + //数据验证 + for(let i = c_r1; i <= c_r2; i++){ + for(let j = c_c1; j <= c_c2; j++){ + delete c_dataVerification[i + "_" + j]; + } + } + source = { "sheetIndex": copySheetIndex, "data": sourceData, @@ -1099,9 +1138,11 @@ const selection = { "curConfig": sourceCurConfig, "cdformat": source_cdformat, "curCdformat": source_curCdformat, + "dataVerification": $.extend(true, {}, Store.luckysheetfile[getSheetIndex(copySheetIndex)]["dataVerification"]), + "curDataVerification": c_dataVerification, "range": { - "row": copyRange["copyRange"][0].row, - "column": copyRange["copyRange"][0].column + "row": [c_r1, c_r2], + "column": [c_c1, c_c2] } } target = { @@ -1112,6 +1153,8 @@ const selection = { "curConfig": cfg, "cdformat": target_cdformat, "curCdformat": target_curCdformat, + "dataVerification": $.extend(true, {}, Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dataVerification"]), + "curDataVerification": dataVerification, "range": { "row": [minh, maxh], "column": [minc, maxc] @@ -1128,7 +1171,13 @@ const selection = { let emptyRange = []; for(let j = 0; j < cellrange.length; j++){ - let range = conditionformat.CFSplitRange(cellrange[j], {"row": copyRange["copyRange"][0].row, "column": copyRange["copyRange"][0].column}, {"row": [minh, maxh], "column": [minc, maxc]}, "allPart"); + let range = conditionformat.CFSplitRange( + cellrange[j], + {"row": [c_r1, c_r2], "column": [c_c1, c_c2]}, + {"row": [minh, maxh], "column": [minc, maxc]}, + "allPart" + ); + emptyRange = emptyRange.concat(range); } @@ -1145,9 +1194,11 @@ const selection = { "curConfig": cfg, "cdformat": cdformat, "curCdformat": curCdformat, + "dataVerification": $.extend(true, {}, Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dataVerification"]), + "curDataVerification": dataVerification, "range": { - "row": copyRange["copyRange"][0].row, - "column": copyRange["copyRange"][0].column + "row": [c_r1, c_r2], + "column": [c_c1, c_c2] } } target = { @@ -1158,6 +1209,8 @@ const selection = { "curConfig": cfg, "cdformat": cdformat, "curCdformat": curCdformat, + "dataVerification": $.extend(true, {}, Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dataVerification"]), + "curDataVerification": dataVerification, "range": { "row": [minh, maxh], "column": [minc, maxc] @@ -1183,11 +1236,16 @@ const selection = { let copyRowlChange = copyRange["RowlChange"]; let copySheetIndex = copyRange["dataSheetIndex"]; + let c_r1 = copyRange["copyRange"][0].row[0], + c_r2 = copyRange["copyRange"][0].row[1], + c_c1 = copyRange["copyRange"][0].column[0], + c_c2 = copyRange["copyRange"][0].column[1]; + let arr = [], isSameRow = false; for(let i = 0; i < copyRange["copyRange"].length; i++){ let arrData = getdatabyselection({"row": copyRange["copyRange"][i].row, "column": copyRange["copyRange"][i].column}, copySheetIndex); if(copyRange["copyRange"].length > 1){ - if(copyRange["copyRange"][0].row[0] == copyRange["copyRange"][1].row[0] && copyRange["copyRange"][0].row[1] == copyRange["copyRange"][1].row[1]){ + if(c_r1 == copyRange["copyRange"][1].row[0] && c_r2 == copyRange["copyRange"][1].row[1]){ arrData = arrData[0].map(function(col, a){ return arrData.map(function(row){ return row[a]; @@ -1198,7 +1256,7 @@ const selection = { isSameRow = true; } - else if(copyRange["copyRange"][0].column[0] == copyRange["copyRange"][1].column[0] && copyRange["copyRange"][0].column[1] == copyRange["copyRange"][1].column[1]){ + else if(c_c1 == copyRange["copyRange"][1].column[0] && c_c2 == copyRange["copyRange"][1].column[1]){ arr = arr.concat(arrData); } } @@ -1274,6 +1332,8 @@ const selection = { } let borderInfoCompute = getBorderInfoCompute(copySheetIndex); + let c_dataVerification = $.extend(true, {}, Store.luckysheetfile[getSheetIndex(copySheetIndex)].dataVerification); + let dataVerification = null; let mth = 0, mtc = 0, maxcellCahe = 0, maxrowCache = 0; for(let th = 1; th <= timesH; th++){ @@ -1284,24 +1344,24 @@ const selection = { maxcellCahe = minc + tc * copyc; //行列位移值 用于单元格有函数 - let offsetRow = mth - copyRange["copyRange"][0].row[0]; - let offsetCol = mtc - copyRange["copyRange"][0].column[0]; + let offsetRow = mth - c_r1; + let offsetCol = mtc - c_c1; let offsetMC = {}; for (let h = mth; h < maxrowCache; h++) { let x = [].concat(d[h]); for (let c = mtc; c < maxcellCahe; c++) { - if(borderInfoCompute[(copyRange["copyRange"][0].row[0] + h - mth) + "_" + (copyRange["copyRange"][0].column[0] + c - mtc)]){ + if(borderInfoCompute[(c_r1 + h - mth) + "_" + (c_c1 + c - mtc)]){ let bd_obj = { "rangeType": "cell", "value": { "row_index": h, "col_index": c, - "l": borderInfoCompute[(copyRange["copyRange"][0].row[0] + h - mth) + "_" + (copyRange["copyRange"][0].column[0] + c - mtc)].l, - "r": borderInfoCompute[(copyRange["copyRange"][0].row[0] + h - mth) + "_" + (copyRange["copyRange"][0].column[0] + c - mtc)].r, - "t": borderInfoCompute[(copyRange["copyRange"][0].row[0] + h - mth) + "_" + (copyRange["copyRange"][0].column[0] + c - mtc)].t, - "b": borderInfoCompute[(copyRange["copyRange"][0].row[0] + h - mth) + "_" + (copyRange["copyRange"][0].column[0] + c - mtc)].b + "l": borderInfoCompute[(c_r1 + h - mth) + "_" + (c_c1 + c - mtc)].l, + "r": borderInfoCompute[(c_r1 + h - mth) + "_" + (c_c1 + c - mtc)].r, + "t": borderInfoCompute[(c_r1 + h - mth) + "_" + (c_c1 + c - mtc)].t, + "b": borderInfoCompute[(c_r1 + h - mth) + "_" + (c_c1 + c - mtc)].b } } @@ -1331,6 +1391,15 @@ const selection = { cfg["borderInfo"].push(bd_obj); } + //数据验证 复制 + if(c_dataVerification[(c_r1 + h - mth) + "_" + (c_c1 + c - mtc)]){ + if(dataVerification == null){ + dataVerification = $.extend(true, {}, Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].dataVerification) + } + + dataVerification[h + "_" + c] = c_dataVerification[(c_r1 + h - mth) + "_" + (c_c1 + c - mtc)]; + } + if(getObjType(x[c]) == "object" && "mc" in x[c]){ if("rs" in x[c].mc){ delete cfg["merge"][x[c]["mc"].r + "_" + x[c]["mc"].c]; @@ -1401,21 +1470,17 @@ const selection = { } } - //复制范围 是否有 条件格式 - let ruleArr_cf = [], cdformat = []; + //复制范围 是否有 条件格式和数据验证 + let cdformat = null; if(copyRange["copyRange"].length == 1){ let c_file = Store.luckysheetfile[getSheetIndex(copySheetIndex)]; let a_file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]; - - let c_r1 = copyRange["copyRange"][0].row[0], - c_r2 = copyRange["copyRange"][0].row[1], - c_c1 = copyRange["copyRange"][0].column[0], - c_c2 = copyRange["copyRange"][0].column[1]; - ruleArr_cf = $.extend(true, [], c_file["luckysheet_conditionformat_save"]); - cdformat = $.extend(true, [], a_file["luckysheet_conditionformat_save"]); + let ruleArr_cf = $.extend(true, [], c_file["luckysheet_conditionformat_save"]); if(ruleArr_cf != null && ruleArr_cf.length > 0){ + cdformat = $.extend(true, [], a_file["luckysheet_conditionformat_save"]); + for(let i = 0; i < ruleArr_cf.length; i++){ let cf_range = ruleArr_cf[i].cellrange; @@ -1429,7 +1494,13 @@ const selection = { maxcellCahe = minc + tc * copyc; for(let j = 0; j < cf_range.length; j++){ - let range = conditionformat.CFSplitRange(cf_range[j], {"row": [c_r1, c_r2], "column": [c_c1, c_c2]}, {"row": [mth, maxrowCache - 1], "column": [mtc, maxcellCahe - 1]}, "operatePart"); + let range = conditionformat.CFSplitRange( + cf_range[j], + {"row": [c_r1, c_r2], "column": [c_c1, c_c2]}, + {"row": [mth, maxrowCache - 1], "column": [mtc, maxcellCahe - 1]}, + "operatePart" + ); + if(range.length > 0){ emptyRange = emptyRange.concat(range); } @@ -1450,22 +1521,10 @@ const selection = { if(copyRowlChange || addr > 0 || addc > 0){ cfg = rowlenByRange(d, minh, maxh, cfg); - - if(copyRange["copyRange"].length == 1 && ruleArr_cf != null && ruleArr_cf.length > 0){ - jfrefreshgrid(d, Store.luckysheet_select_save, cfg, cdformat, true); - } - else{ - jfrefreshgrid(d, Store.luckysheet_select_save, cfg, null, true); - } + jfrefreshgrid(d, Store.luckysheet_select_save, cfg, cdformat, true, dataVerification); } else{ - if(copyRange["copyRange"].length == 1 && ruleArr_cf != null && ruleArr_cf.length > 0){ - jfrefreshgrid(d, Store.luckysheet_select_save, cfg, cdformat); - } - else{ - jfrefreshgrid(d, Store.luckysheet_select_save, cfg); - } - + jfrefreshgrid(d, Store.luckysheet_select_save, cfg, cdformat, null, dataVerification); selectHightlightShow(); } }, @@ -1478,9 +1537,14 @@ const selection = { //复制范围 let copyHasMC = copyRange["HasMC"]; let copyRowlChange = copyRange["RowlChange"]; - let copySheetIndex = copyRange["dataSheetIndex"]; - let copyData = $.extend(true, [], getdatabyselection({"row": copyRange["copyRange"][0].row, "column": copyRange["copyRange"][0].column}, copySheetIndex)); + + let c_r1 = copyRange["copyRange"][0].row[0], + c_r2 = copyRange["copyRange"][0].row[1], + c_c1 = copyRange["copyRange"][0].column[0], + c_c2 = copyRange["copyRange"][0].column[1]; + + let copyData = $.extend(true, [], getdatabyselection({"row": [c_r1, c_r2], "column": [c_c1, c_c2]}, copySheetIndex)); //应用范围 let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1]; @@ -1518,6 +1582,8 @@ const selection = { let rowMaxLength = d.length; let borderInfoCompute = getBorderInfoCompute(copySheetIndex); + let c_dataVerification = $.extend(true, {}, Store.luckysheetfile[getSheetIndex(copySheetIndex)].dataVerification); + let dataVerification = null; let mth = 0, mtc = 0, maxcellCahe = 0, maxrowCache = 0; for (let th = 1; th <= timesH; th++) { @@ -1540,16 +1606,16 @@ const selection = { let x = [].concat(d[h]); for (let c = mtc; c < maxcellCahe; c++) { - if(borderInfoCompute[(copyRange["copyRange"][0].row[0] + h - mth) + "_" + (copyRange["copyRange"][0].column[0] + c - mtc)]){ + if(borderInfoCompute[(c_r1 + h - mth) + "_" + (c_c1 + c - mtc)]){ let bd_obj = { "rangeType": "cell", "value": { "row_index": h, "col_index": c, - "l": borderInfoCompute[(copyRange["copyRange"][0].row[0] + h - mth) + "_" + (copyRange["copyRange"][0].column[0] + c - mtc)].l, - "r": borderInfoCompute[(copyRange["copyRange"][0].row[0] + h - mth) + "_" + (copyRange["copyRange"][0].column[0] + c - mtc)].r, - "t": borderInfoCompute[(copyRange["copyRange"][0].row[0] + h - mth) + "_" + (copyRange["copyRange"][0].column[0] + c - mtc)].t, - "b": borderInfoCompute[(copyRange["copyRange"][0].row[0] + h - mth) + "_" + (copyRange["copyRange"][0].column[0] + c - mtc)].b + "l": borderInfoCompute[(c_r1 + h - mth) + "_" + (c_c1 + c - mtc)].l, + "r": borderInfoCompute[(c_r1 + h - mth) + "_" + (c_c1 + c - mtc)].r, + "t": borderInfoCompute[(c_r1 + h - mth) + "_" + (c_c1 + c - mtc)].t, + "b": borderInfoCompute[(c_r1 + h - mth) + "_" + (c_c1 + c - mtc)].b } } @@ -1579,6 +1645,15 @@ const selection = { cfg["borderInfo"].push(bd_obj); } + //数据验证 复制 + if(c_dataVerification[(c_r1 + h - mth) + "_" + (c_c1 + c - mtc)]){ + if(dataVerification == null){ + dataVerification = $.extend(true, {}, Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].dataVerification) + } + + dataVerification[h + "_" + c] = c_dataVerification[(c_r1 + h - mth) + "_" + (c_c1 + c - mtc)]; + } + if(getObjType(x[c]) == "object" && ("mc" in x[c])){ if("rs" in x[c].mc){ delete cfg["merge"][x[c]["mc"].r + "_" + x[c]["mc"].c]; @@ -1642,16 +1717,24 @@ const selection = { } //复制范围 是否有 条件格式 + let cdformat = null; let ruleArr = $.extend(true, [], Store.luckysheetfile[getSheetIndex(copySheetIndex)]["luckysheet_conditionformat_save"]); - let cdformat = $.extend(true, [], Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["luckysheet_conditionformat_save"]); if(ruleArr != null && ruleArr.length > 0){ + cdformat = $.extend(true, [], Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["luckysheet_conditionformat_save"]); + for(let i = 0; i < ruleArr.length; i++){ let cdformat_cellrange = ruleArr[i].cellrange; let emptyRange = []; for(let j = 0; j < cdformat_cellrange.length; j++){ - let range = conditionformat.CFSplitRange(cdformat_cellrange[j], {"row": copyRange["copyRange"][0]["row"], "column": copyRange["copyRange"][0]["column"]}, {"row": [minh, maxh], "column": [minc, maxc]}, "operatePart"); + let range = conditionformat.CFSplitRange( + cdformat_cellrange[j], + {"row": [c_r1, c_r2], "column": [c_c1, c_c2]}, + {"row": [minh, maxh], "column": [minc, maxc]}, + "operatePart" + ); + if(range.length > 0){ emptyRange = emptyRange.concat(range); } @@ -1669,22 +1752,10 @@ const selection = { if(copyRowlChange){ cfg = rowlenByRange(d, minh, maxh, cfg); - - if(ruleArr != null && ruleArr.length > 0){ - jfrefreshgrid(d, Store.luckysheet_select_save, cfg, cdformat, true); - } - else{ - jfrefreshgrid(d, Store.luckysheet_select_save, cfg, null, true); - } + jfrefreshgrid(d, Store.luckysheet_select_save, cfg, cdformat, true, dataVerification); } else{ - if(ruleArr != null && ruleArr.length > 0){ - jfrefreshgrid(d, Store.luckysheet_select_save, cfg, cdformat); - } - else{ - jfrefreshgrid(d, Store.luckysheet_select_save, cfg); - } - + jfrefreshgrid(d, Store.luckysheet_select_save, cfg, cdformat, null, dataVerification); selectHightlightShow(); } }, diff --git a/src/controllers/sheetmanage.js b/src/controllers/sheetmanage.js index 07aa443..3eb5a4d 100644 --- a/src/controllers/sheetmanage.js +++ b/src/controllers/sheetmanage.js @@ -18,6 +18,7 @@ import pivotTable from './pivotTable'; import luckysheetsizeauto from './resize'; import luckysheetPostil from './postil'; import imageCtrl from './imageCtrl'; +import dataVerificationCtrl from './dataVerificationCtrl'; import luckysheetFreezen from './freezen'; import { createFilterOptions, labelFilterOptionState } from './filter'; import { selectHightlightShow, selectionCopyShow } from './select'; @@ -871,6 +872,9 @@ const sheetmanage = { imageCtrl.images = file.images; imageCtrl.allImagesShow(); + //数据验证 + dataVerificationCtrl.dataVerification = file.dataVerification; + this.sheetParamRestore(file, Store.flowdata); if(file["freezen"] == null){ diff --git a/src/controllers/updateCell.js b/src/controllers/updateCell.js index 1d18577..9df8116 100644 --- a/src/controllers/updateCell.js +++ b/src/controllers/updateCell.js @@ -3,6 +3,7 @@ import luckysheetFreezen from './freezen'; import menuButton from './menuButton'; import conditionformat from './conditionformat'; import alternateformat from './alternateformat'; +import dataVerificationCtrl from './dataVerificationCtrl'; import { chatatABC } from '../utils/util'; import { isEditMode } from '../global/validate'; import { getcellvalue } from '../global/getdata'; @@ -17,6 +18,16 @@ export function luckysheetupdateCell(row_index1, col_index1, d, cover, isnotfocu return; } + if(dataVerificationCtrl.dataVerification != null && dataVerificationCtrl.dataVerification[row_index1 + '_' + col_index1] != null){ + let dataVerificationItem = dataVerificationCtrl.dataVerification[row_index1 + '_' + col_index1]; + if(dataVerificationItem.type == 'dropdown'){ + dataVerificationCtrl.dropdownListShow(); + } + else if(dataVerificationItem.type == 'checkbox'){ + return; + } + } + let size = getColumnAndRowSize(row_index1, col_index1, d); let row = size.row, row_pre = size.row_pre, col = size.col, col_pre = size.col_pre, row_index = size.row_index, col_index = size.col_index; diff --git a/src/css/luckysheet-core.css b/src/css/luckysheet-core.css index 04e461d..3328bfe 100644 --- a/src/css/luckysheet-core.css +++ b/src/css/luckysheet-core.css @@ -7013,4 +7013,176 @@ fieldset[disabled] .btn-danger.focus { margin-left: 5px; margin-bottom: -5px; cursor: pointer; -} \ No newline at end of file +} +/* 数据验证 */ +#luckysheet-dataVerification-dialog{ + user-select: none; +} +#luckysheet-dataVerification-dialog .box{ + font-size: 12px; +} +#luckysheet-dataVerification-dialog .box select{ + width: 100%; + height: 30px; + border-color: #d4d4d4; + outline-style: none; +} +#luckysheet-dataVerification-dialog .box input::-webkit-input-placeholder { + color: #d4d4d4; +} +#luckysheet-dataVerification-dialog .box input:-moz-placeholder { + color: #d4d4d4; +} +#luckysheet-dataVerification-dialog .box input::-moz-placeholder { + color: #d4d4d4; +} +#luckysheet-dataVerification-dialog .box input:-ms-input-placeholder { + color: #d4d4d4; +} +#luckysheet-dataVerification-dialog .box-item{ + padding: 10px; + border-bottom: 1px solid #E1E4E8; +} +#luckysheet-dataVerification-dialog .box-item .box-item-title{ + font-size: 14px; + font-weight: 600; + margin-bottom: 10px; +} +#luckysheet-dataVerification-dialog .box-item .range{ + width: 100%; + height: 30px; + border: 1px solid #d4d4d4; +} +#luckysheet-dataVerification-dialog .box-item .range input{ + width: calc(100% - 30px); + height: 30px; + padding: 0 10px; + float: left; + border: none; + outline-style: none; + box-sizing: border-box; +} +#luckysheet-dataVerification-dialog .box-item .range i.fa-table{ + float: right; + margin-top: 9px; + margin-right: 5px; + cursor: pointer; + color: #6598F3; +} +#luckysheet-dataVerification-dialog .box-item .show-box{ + margin-top: 10px; +} +#luckysheet-dataVerification-dialog .box-item .check-box{ + height: 30px; + line-height: 30px; + margin-bottom: 10px; +} +#luckysheet-dataVerification-dialog .box-item .check-box:last-child{ + margin-bottom: 0; +} +#luckysheet-dataVerification-dialog .box-item .check-box input{ + height: 30px; + padding: 0 10px; + border: 1px solid #d4d4d4; + box-sizing: border-box; +} +#luckysheet-dataVerification-dialog .box-item .check{ + line-height: 30px; +} +#luckysheet-dataVerification-dialog .box-item .check input{ + vertical-align: text-top; +} +#luckysheet-dataVerification-dialog .box-item .input{ + height: 30px; + line-height: 30px; + margin-top: 10px; +} +#luckysheet-dataVerification-dialog .box-item .input input{ + height: 30px; + padding: 4px 10px 4px 10px; + border: 1px solid #d4d4d4; + box-sizing: border-box; +} +#luckysheet-dataVerification-dialog .box-item .input1 input{ + width: 150px; +} +#luckysheet-dataVerification-dialog .box-item .input2 input{ + width: 100%; +} +#luckysheet-dataVerification-dialog .box-item .input span{ + display: inline-block; + width: 30px; + text-align: center; +} +#luckysheet-dataVerification-dialog .data-verification-hint-text{ + width: 100%; + height: 30px; + border: 1px solid #d4d4d4; + margin-top: 10px; +} +#luckysheet-dataVerification-dialog .data-verification-hint-text input{ + display: block; + width: 100%; + height: 100%; + padding: 0 10px; + border: none; + outline-style: none; + box-sizing: border-box; +} +#luckysheet-dataVerification-dialog .show-box .show-box-item{ + display: none; +} +#luckysheet-dataVerificationRange-dialog input{ + height: 30px; + padding: 0 10px; + border: 1px solid #d4d4d4; + outline-style: none; +} +#luckysheet-dataVerification-dropdown-btn{ + display: none; + width: 20px; + height: 20px; + background-color: #fff; + position: absolute; + z-index: 10; + overflow: hidden; +} +#luckysheet-dataVerification-dropdown-btn::after{ + content: ''; + width: 10px; + height: 10px; + background: url(arrow-down.png) center no-repeat; + position: absolute; + left: 50%; + top: 50%; + margin-left: -5px; + margin-top: -5px; +} +#luckysheet-dataVerification-dropdown-List{ + display: none; + background-color: #fff; + border: 1px solid #ccc; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + position: absolute; + z-index: 1000; + box-sizing: border-box; +} +#luckysheet-dataVerification-dropdown-List .dropdown-List-item{ + padding: 5px 10px; + box-sizing: border-box; + cursor: pointer; +} +#luckysheet-dataVerification-dropdown-List .dropdown-List-item:hover{ + background-color: #E1E1E1; +} +#luckysheet-dataVerification-showHintBox{ + display: none; + padding: 10px; + background-color: #fff; + border: 1px solid #ccc; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + position: absolute; + z-index: 1000; + user-select: none; + cursor: default; +} diff --git a/src/global/draw.js b/src/global/draw.js index 3dc866e..85aaaef 100644 --- a/src/global/draw.js +++ b/src/global/draw.js @@ -3,6 +3,7 @@ import conditionformat from '../controllers/conditionformat'; import alternateformat from '../controllers/alternateformat'; import luckysheetSparkline from '../controllers/sparkline'; import menuButton from '../controllers/menuButton'; +import dataVerificationCtrl from '../controllers/dataVerificationCtrl'; import { luckysheetdefaultstyle, luckysheet_CFiconsImg,luckysheetdefaultFont } from '../controllers/constant'; import { luckysheet_searcharray } from '../controllers/sheetSearch'; import { dynamicArrayCompute } from './dynamicArray'; @@ -1651,8 +1652,8 @@ let cellRender = function(r, c, start_r, start_c, end_r, end_c, value, luckyshee (start_r + offsetTop + borderfix[1]), (end_c - start_c + borderfix[2]-(!!isMerge?1:0)), (end_r - start_r + borderfix[3]) - ]; - luckysheetTableContent.fillRect(cellsize[0], cellsize[1], cellsize[2], cellsize[3]); + ]; + luckysheetTableContent.fillRect(cellsize[0], cellsize[1], cellsize[2], cellsize[3]); // luckysheetTableContent.fillRect( // (start_c + offsetLeft - 1) , @@ -1661,6 +1662,31 @@ let cellRender = function(r, c, start_r, start_c, end_r, end_c, value, luckyshee // (end_r - start_r) // ) + //数据验证 + let dataVerification = dataVerificationCtrl.dataVerification; + + if(dataVerification != null && dataVerification[r + '_' + c] != null && !dataVerificationCtrl.validateCellData(value, dataVerification[r + '_' + c])){ + //单元格左上角红色小三角标示 + let dv_w = 5 * Store.zoomRatio, dv_h = 5 * Store.zoomRatio; //红色小三角宽高 + + luckysheetTableContent.beginPath(); + luckysheetTableContent.moveTo( + (start_c + offsetLeft), + (start_r + offsetTop) + ); + luckysheetTableContent.lineTo( + (start_c + offsetLeft + dv_w), + (start_r + offsetTop) + ); + luckysheetTableContent.lineTo( + (start_c + offsetLeft), + (start_r + offsetTop + dv_h) + ); + luckysheetTableContent.fillStyle = "#FC6666"; + luckysheetTableContent.fill(); + luckysheetTableContent.closePath(); + } + //若单元格有批注(单元格右上角红色小三角标示) if(cell.ps != null){ let ps_w = 8*Store.zoomRatio, ps_h = 8*Store.zoomRatio; //红色小三角宽高 @@ -1726,6 +1752,77 @@ let cellRender = function(r, c, start_r, start_c, end_r, end_c, value, luckyshee cellOverflow_bd_r_render = false; } } + //数据验证 复选框 + else if(dataVerification != null && dataVerification[r + '_' + c] != null && dataVerification[r + '_' + c].type == 'checkbox'){ + let pos_x = start_c + offsetLeft; + let pos_y = start_r + offsetTop + 1; + + luckysheetTableContent.save(); + luckysheetTableContent.beginPath(); + luckysheetTableContent.rect(pos_x, pos_y, cellWidth, cellHeight); + luckysheetTableContent.clip(); + luckysheetTableContent.scale(Store.zoomRatio,Store.zoomRatio); + + textMetrics += 14; + + let horizonAlignPos = (pos_x + space_width) ; //默认为1,左对齐 + if(horizonAlign == "0"){ //居中对齐 + horizonAlignPos = (pos_x + cellWidth / 2) - (textMetrics / 2); + } + else if(horizonAlign == "2"){ //右对齐 + horizonAlignPos = (pos_x + cellWidth - space_width) - textMetrics; + } + + let verticalCellHeight = cellHeight > oneLineTextHeight ? cellHeight : oneLineTextHeight; + + let verticalAlignPos_text = (pos_y + verticalCellHeight - space_height) ; //文本垂直方向基准线 + luckysheetTableContent.textBaseline = "bottom"; + let verticalAlignPos_checkbox = verticalAlignPos_text - 13; + + if(verticalAlign == "0"){ //居中对齐 + verticalAlignPos_text = (pos_y + verticalCellHeight / 2); + luckysheetTableContent.textBaseline = "middle"; + verticalAlignPos_checkbox = verticalAlignPos_text - 6; + } + else if(verticalAlign == "1"){ //上对齐 + verticalAlignPos_text = (pos_y + space_height); + luckysheetTableContent.textBaseline = "top"; + verticalAlignPos_checkbox = verticalAlignPos_text + 1; + } + + horizonAlignPos = horizonAlignPos / Store.zoomRatio; + verticalAlignPos_text = verticalAlignPos_text / Store.zoomRatio; + verticalAlignPos_checkbox = verticalAlignPos_checkbox / Store.zoomRatio; + + //复选框 + luckysheetTableContent.lineWidth = 1; + luckysheetTableContent.strokeStyle = "#000"; + luckysheetTableContent.strokeRect(horizonAlignPos, verticalAlignPos_checkbox, 10, 10); + + if(dataVerification[r + '_' + c].checked){ + luckysheetTableContent.beginPath(); + luckysheetTableContent.lineTo( + horizonAlignPos + 1, + verticalAlignPos_checkbox + 6 + ); + luckysheetTableContent.lineTo( + horizonAlignPos + 4, + verticalAlignPos_checkbox + 9 + ); + luckysheetTableContent.lineTo( + horizonAlignPos + 9, + verticalAlignPos_checkbox + 2 + ); + luckysheetTableContent.stroke(); + luckysheetTableContent.closePath(); + } + + //文本 + luckysheetTableContent.fillStyle = menuButton.checkstatus(Store.flowdata, r, c , "fc"); + luckysheetTableContent.fillText(value == null ? "" : value, horizonAlignPos + 14, verticalAlignPos_text); + + luckysheetTableContent.restore(); + } //非溢出单元格 else{ //若单元格有条件格式数据条 @@ -1950,7 +2047,7 @@ let cellRender = function(r, c, start_r, start_c, end_r, end_c, value, luckyshee // space_width = space_width/Store.zoomRatio; // cellHeight = cellHeight/Store.zoomRatio; // oneLineTextHeight = oneLineTextHeight/Store.zoomRatio; - + //若单元格有条件格式图标集 if(checksCF != null && checksCF["icons"] != null){ let l = checksCF["icons"]["left"]; diff --git a/src/global/extend.js b/src/global/extend.js index 2591c65..960ea37 100644 --- a/src/global/extend.js +++ b/src/global/extend.js @@ -14,7 +14,7 @@ import Store from '../store'; function luckysheetextendtable(type, index, value, direction, order) { let curOrder = order || getSheetIndex(Store.currentSheetIndex); let file = Store.luckysheetfile[curOrder]; - let d = file.data; + let d = $.extend(true, [], file.data); value = Math.floor(value); let cfg = $.extend(true, {}, file.config); @@ -457,6 +457,50 @@ function luckysheetextendtable(type, index, value, direction, order) { newFreezen.freezenverticaldata = luckysheetFreezen.freezenverticaldata; } + //数据验证配置变动 + let dataVerification = file.dataVerification; + let newDataVerification = {}; + if(dataVerification != null){ + for(let key in dataVerification){ + let r = Number(key.split('_')[0]), + c = Number(key.split('_')[1]); + let item = dataVerification[key]; + + if(type == "row"){ + if(index < r){ + newDataVerification[(r + value) + "_" + c] = item; + } + else if(index == r){ + if(direction == "lefttop"){ + newDataVerification[(r + value) + "_" + c] = item; + } + else{ + newDataVerification[r + "_" + c] = item; + } + } + else{ + newDataVerification[r + "_" + c] = item; + } + } + else if(type == "column"){ + if(index < c){ + newDataVerification[r + "_" + (c + value)] = item; + } + else if(index == c){ + if(direction == "lefttop"){ + newDataVerification[r + "_" + (c + value)] = item; + } + else{ + newDataVerification[r + "_" + c] = item; + } + } + else{ + newDataVerification[r + "_" + c] = item; + } + } + } + } + let type1; if (type == "row") { type1 = "r"; @@ -713,7 +757,7 @@ function luckysheetextendtable(type, index, value, direction, order) { } // 修改当前sheet页时刷新 - if (curOrder == Store.currentSheetIndex) { + if (file.index == Store.currentSheetIndex) { jfrefreshgrid_adRC( d, cfg, @@ -723,9 +767,20 @@ function luckysheetextendtable(type, index, value, direction, order) { newFilterObj, newCFarr, newAFarr, - newFreezen + newFreezen, + newDataVerification ); } + else{ + file.data = d; + file.config = cfg; + file.calcChain = newCalcChain; + file.filter = newFilterObj.filter; + file.filter_select = newFilterObj.filter_select; + file.luckysheet_conditionformat_save = newCFarr; + file.luckysheet_alternateformat_save = newAFarr; + file.dataVerification = newDataVerification; + } let range = null; if(type == "row"){ @@ -746,7 +801,7 @@ function luckysheetextendtable(type, index, value, direction, order) { } file.luckysheet_select_save = range; - if (curOrder == Store.currentSheetIndex) { + if (file.index == Store.currentSheetIndex) { Store.luckysheet_select_save = range; selectHightlightShow(); } @@ -816,7 +871,7 @@ function luckysheetextendData(rowlen, newData) { function luckysheetdeletetable(type, st, ed, order) { let curOrder = order || getSheetIndex(Store.currentSheetIndex); let file = Store.luckysheetfile[curOrder]; - let d = file.data; + let d = $.extend(true, [], file.data); let slen = ed - st + 1; let cfg = $.extend(true, {}, file.config); @@ -1280,6 +1335,34 @@ function luckysheetdeletetable(type, st, ed, order) { newFreezen.freezenverticaldata = luckysheetFreezen.freezenverticaldata; } + //数据验证配置变动 + let dataVerification = file.dataVerification; + let newDataVerification = {}; + if(dataVerification != null){ + for(let key in dataVerification){ + let r = Number(key.split('_')[0]), + c = Number(key.split('_')[1]); + let item = dataVerification[key]; + + if(type == "row"){ + if(r < st){ + newDataVerification[r + "_" + c] = item; + } + else if(r > ed){ + newDataVerification[(r - slen) + "_" + c] = item; + } + } + else if(type == "column"){ + if(c < st){ + newDataVerification[r + "_" + c] = item; + } + else if(c > ed){ + newDataVerification[r + "_" + (c - slen)] = item; + } + } + } + } + //主逻辑 let type1; if (type == "row") { @@ -1471,7 +1554,7 @@ function luckysheetdeletetable(type, st, ed, order) { } // 修改当前sheet页时刷新 - if (curOrder == Store.currentSheetIndex) { + if (file.index == Store.currentSheetIndex) { jfrefreshgrid_adRC( d, cfg, @@ -1481,17 +1564,29 @@ function luckysheetdeletetable(type, st, ed, order) { newFilterObj, newCFarr, newAFarr, - newFreezen + newFreezen, + newDataVerification ); } + else{ + file.data = d; + file.config = cfg; + file.calcChain = newCalcChain; + file.filter = newFilterObj.filter; + file.filter_select = newFilterObj.filter_select; + file.luckysheet_conditionformat_save = newCFarr; + file.luckysheet_alternateformat_save = newAFarr; + file.dataVerification = newDataVerification; + } } //删除单元格 function luckysheetDeleteCell(type, str, edr, stc, edc, order) { - let d = editor.deepCopyFlowData(Store.flowdata); let curOrder = order || getSheetIndex(Store.currentSheetIndex); let file = Store.luckysheetfile[curOrder]; + let d = $.extend(true, [], file.data); + let rlen = edr - str + 1; let clen = edc - stc + 1; let cfg = $.extend(true, {}, Store.config); @@ -1835,6 +1930,36 @@ function luckysheetDeleteCell(type, str, edr, stc, edc, order) { } } + //数据验证配置变动 + let dataVerification = file.dataVerification; + let newDataVerification = {}; + if(dataVerification != null){ + for(let key in dataVerification){ + let r = Number(key.split('_')[0]), + c = Number(key.split('_')[1]); + let item = dataVerification[key]; + + if(r < str || r > edr || c < stc || c > edc){ + if(type == "moveLeft"){ + if(c > edc && r >= str && r <= edr){ + newDataVerification[r + "_" + (c - clen)] = item; + } + else{ + newDataVerification[r + "_" + c] = item; + } + } + else if(type == "moveUp"){ + if(r > edr && c >= stc && c <= edc){ + newDataVerification[(r - rlen) + "_" + c] = item; + } + else{ + newDataVerification[r + "_" + c] = item; + } + } + } + } + } + //边框配置变动 if(cfg["borderInfo"] && cfg["borderInfo"].length > 0){ let borderInfo = []; @@ -1948,14 +2073,26 @@ function luckysheetDeleteCell(type, str, edr, stc, edc, order) { } } - jfrefreshgrid_deleteCell( - d, - cfg, - { type: type, 'str': str, 'edr': edr, 'stc': stc, 'edc': edc }, - newCalcChain, - newFilterObj, - newCFarr - ); + if(file.index == Store.currentSheetIndex){ + jfrefreshgrid_deleteCell( + d, + cfg, + { type: type, 'str': str, 'edr': edr, 'stc': stc, 'edc': edc }, + newCalcChain, + newFilterObj, + newCFarr, + newDataVerification + ); + } + else{ + file.data = d; + file.config = cfg; + file.calcChain = newCalcChain; + file.filter = newFilterObj.filter; + file.filter_select = newFilterObj.filter_select; + file.luckysheet_conditionformat_save = newCFarr; + file.dataVerification = newDataVerification; + } } export { diff --git a/src/global/formula.js b/src/global/formula.js index 40c5e8d..17838fa 100644 --- a/src/global/formula.js +++ b/src/global/formula.js @@ -1195,7 +1195,7 @@ const luckysheetformula = { let $input = $("#luckysheet-rich-text-editor"), value = $input.text(); - if (_this.rangetosheet != Store.currentSheetIndex) { + if (_this.rangetosheet != null && _this.rangetosheet != Store.currentSheetIndex) { sheetmanage.changeSheetExec(_this.rangetosheet); } @@ -1353,10 +1353,10 @@ const luckysheetformula = { } if(RowlChange){ - jfrefreshgrid(d, [{ "row": [r, r], "column": [c, c] }], cfg, null, RowlChange, isRunExecFunction); + jfrefreshgrid(d, [{ "row": [r, r], "column": [c, c] }], cfg, null, RowlChange, null, isRunExecFunction); } else { - jfrefreshgrid(d, [{ "row": [r, r], "column": [c, c] }], undefined, undefined, undefined, isRunExecFunction); + jfrefreshgrid(d, [{ "row": [r, r], "column": [c, c] }], undefined, undefined, undefined, undefined, isRunExecFunction); } // Store.luckysheetCellUpdate.length = 0; //clear array diff --git a/src/global/refresh.js b/src/global/refresh.js index 512448e..48c9720 100644 --- a/src/global/refresh.js +++ b/src/global/refresh.js @@ -13,12 +13,13 @@ import luckysheetFreezen from '../controllers/freezen'; import server from '../controllers/server'; import sheetmanage from '../controllers/sheetmanage'; import luckysheetPostil from '../controllers/postil'; +import dataVerificationCtrl from '../controllers/dataVerificationCtrl'; import { selectHightlightShow, selectionCopyShow } from '../controllers/select'; import { createFilterOptions } from '../controllers/filter'; import { getSheetIndex } from '../methods/get'; import Store from '../store'; -function jfrefreshgrid(data, range, cfg, cdformat, RowlChange, isRunExecFunction=true, isRefreshCanvas=true) { +function jfrefreshgrid(data, range, cfg, cdformat, RowlChange, dataVerification, isRunExecFunction=true, isRefreshCanvas=true) { if(data == null){ data = Store.flowdata; } @@ -58,6 +59,14 @@ function jfrefreshgrid(data, range, cfg, cdformat, RowlChange, isRunExecFunction else{ curCdformat = cdformat; } + + let curDataVerification; + if(dataVerification == null){ + curDataVerification = $.extend(true, {}, Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dataVerification"]) + } + else{ + curDataVerification = dataVerification; + } Store.jfredo.push({ "type": "datachange", @@ -69,7 +78,9 @@ function jfrefreshgrid(data, range, cfg, cdformat, RowlChange, isRunExecFunction "curConfig": curConfig, "cdformat": $.extend(true, [], Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["luckysheet_conditionformat_save"]), "curCdformat": curCdformat, - "RowlChange": RowlChange + "RowlChange": RowlChange, + "dataVerification": $.extend(true, [], Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dataVerification"]), + "curDataVerification": curDataVerification }); } @@ -97,6 +108,13 @@ function jfrefreshgrid(data, range, cfg, cdformat, RowlChange, isRunExecFunction server.saveParam("all", Store.currentSheetIndex, cdformat, { "k": "luckysheet_conditionformat_save" }); } + //数据验证 + if(dataVerification != null){ + dataVerificationCtrl.dataVerification = dataVerification; + Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dataVerification"] = dataVerification; + server.saveParam("all", Store.currentSheetIndex, dataVerification, { "k": "dataVerification" }); + } + //更新数据的范围 for(let s = 0; s < range.length; s++){ let r1 = range[s].row[0]; @@ -127,7 +145,6 @@ function jfrefreshgrid(data, range, cfg, cdformat, RowlChange, isRunExecFunction luckysheetrefreshgrid(); }, 1); } - window.luckysheet_getcelldata_cache = null; } @@ -331,7 +348,7 @@ function jfrefreshrange(data, range, cdformat) { } //删除、增加行列 刷新表格 -function jfrefreshgrid_adRC(data, cfg, ctrlType, ctrlValue, calc, filterObj, cf, af, freezen){ +function jfrefreshgrid_adRC(data, cfg, ctrlType, ctrlValue, calc, filterObj, cf, af, freezen, dataVerification){ let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]; //merge改变对应的单元格值改变 @@ -397,7 +414,9 @@ function jfrefreshgrid_adRC(data, cfg, ctrlType, ctrlValue, calc, filterObj, cf, "af": $.extend(true, [], file.luckysheet_alternateformat_save), "curAf": af, "freezen": { "freezenhorizontaldata": luckysheetFreezen.freezenhorizontaldata, "freezenverticaldata": luckysheetFreezen.freezenverticaldata }, - "curFreezen": freezen + "curFreezen": freezen, + "dataVerification": $.extend(true, {}, file.dataVerification), + "curDataVerification": dataVerification }); } @@ -516,12 +535,17 @@ function jfrefreshgrid_adRC(data, cfg, ctrlType, ctrlValue, calc, filterObj, cf, luckysheetFreezen.freezenverticaldata = null; } + //数据验证 + dataVerificationCtrl.dataVerification = dataVerification; + file.dataVerification = dataVerification; + server.saveParam("all", Store.currentSheetIndex, file.dataVerification, { "k": "dataVerification" }); + //行高、列宽刷新 jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length); } //删除单元格 刷新表格 -function jfrefreshgrid_deleteCell(data, cfg, ctrl, calc, filterObj, cf){ +function jfrefreshgrid_deleteCell(data, cfg, ctrl, calc, filterObj, cf, dataVerification){ let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]; //merge改变对应的单元格值改变 @@ -598,6 +622,8 @@ function jfrefreshgrid_deleteCell(data, cfg, ctrl, calc, filterObj, cf){ "curFilterObj": filterObj, "cf": $.extend(true, [], file.luckysheet_conditionformat_save), "curCf": cf, + "dataVerification": $.extend(true, {}, file.dataVerification), + "curDataVerification": dataVerification }); } @@ -671,6 +697,11 @@ function jfrefreshgrid_deleteCell(data, cfg, ctrl, calc, filterObj, cf){ file.luckysheet_conditionformat_save = cf; server.saveParam("all", Store.currentSheetIndex, file.luckysheet_conditionformat_save, { "k": "luckysheet_conditionformat_save" }); + //数据验证 + dataVerificationCtrl.dataVerification = dataVerification; + file.dataVerification = dataVerification; + server.saveParam("all", Store.currentSheetIndex, file.dataVerification, { "k": "dataVerification" }); + setTimeout(function () { luckysheetrefreshgrid(); }, 1); @@ -795,6 +826,16 @@ function jfrefreshgrid_pastcut(source, target, RowlChange){ Store.luckysheetfile[getSheetIndex(source["sheetIndex"])].luckysheet_conditionformat_save = source["curCdformat"]; Store.luckysheetfile[getSheetIndex(target["sheetIndex"])].luckysheet_conditionformat_save = target["curCdformat"]; + //数据验证 + if(Store.currentSheetIndex == source["sheetIndex"]){ + dataVerificationCtrl.dataVerification = source["curDataVerification"]; + } + else if(Store.currentSheetIndex == target["sheetIndex"]){ + dataVerificationCtrl.dataVerification = target["curDataVerification"] + } + Store.luckysheetfile[getSheetIndex(source["sheetIndex"])].dataVerification = source["curDataVerification"]; + Store.luckysheetfile[getSheetIndex(target["sheetIndex"])].dataVerification = target["curDataVerification"]; + setTimeout(function () { luckysheetrefreshgrid(); }, 1); @@ -811,6 +852,16 @@ function jfrefreshgrid_pastcut(source, target, RowlChange){ server.historyParam(source["curData"], source["sheetIndex"], {"row": source["range"]["row"], "column": source["range"]["column"]}); //目的表 server.historyParam(target["curData"], target["sheetIndex"], {"row": target["range"]["row"], "column": target["range"]["column"]}); + + //来源表 + server.saveParam("all", source["sheetIndex"], source["curCdformat"], { "k": "luckysheet_conditionformat_save" }); + //目的表 + server.saveParam("all", target["sheetIndex"], target["curCdformat"], { "k": "luckysheet_conditionformat_save" }); + + //来源表 + server.saveParam("all", source["sheetIndex"], source["curDataVerification"], { "k": "dataVerification" }); + //目的表 + server.saveParam("all", target["sheetIndex"], target["curDataVerification"], { "k": "dataVerification" }); } //行高、列宽改变 刷新表格 diff --git a/src/locale/en.js b/src/locale/en.js index fb0dd08..e364e6e 100644 --- a/src/locale/en.js +++ b/src/locale/en.js @@ -46,6 +46,7 @@ export default { screenshot: 'Screenshot', splitColumn: 'Split text', insertImage: 'Insert image', + dataVerification: 'Data verification', clearText:"Clear color", noColorSelectedText:"No color is selected", diff --git a/src/locale/zh.js b/src/locale/zh.js index fd18cb7..c695b02 100644 --- a/src/locale/zh.js +++ b/src/locale/zh.js @@ -46,6 +46,7 @@ export default { screenshot: '截图', splitColumn: '分列', insertImage: '插入图片', + dataVerification: '数据验证', clearText:"清除颜色选择", noColorSelectedText:"没有颜色被选择", From a661d303101ee6ebedf22aabb60f7a5a50722b0e Mon Sep 17 00:00:00 2001 From: wpxp123456 <2677556700@qq.com> Date: Thu, 17 Sep 2020 15:37:23 +0800 Subject: [PATCH 2/2] feat(data verification): data verification data verification --- README-zh.md | 21 +- README.md | 22 +- docs/guide/FAQ.md | 7 +- docs/guide/README.md | 28 +- docs/guide/data.md | 18 +- docs/guide/sheet.md | 1346 ++++++++++++++++++++ docs/zh/guide/FAQ.md | 7 +- docs/zh/guide/README.md | 29 +- docs/zh/guide/api.md | 178 ++- docs/zh/guide/cell.md | 11 +- docs/zh/guide/config.md | 465 ++++++- docs/zh/guide/sheet.md | 42 +- src/controllers/formulaBar.js | 4 + src/controllers/handler.js | 5 +- src/controllers/keyboard.js | 2 +- src/controllers/menuButton.js | 12 +- src/core.js | 3 +- src/function/functionImplementation.js | 2 +- src/function/functionlist.js | 1 - src/global/api.js | 1585 +++++++++++++++++++++--- src/global/draw.js | 1488 ++++++---------------- src/global/editor.js | 11 +- src/global/formula.js | 80 +- src/global/getRowlen.js | 1327 ++++++++++++++++---- src/global/getdata.js | 15 + src/index.html | 122 +- src/store/index.js | 1 + 27 files changed, 5155 insertions(+), 1677 deletions(-) create mode 100644 docs/guide/sheet.md diff --git a/README-zh.md b/README-zh.md index ebe5d23..4803cc8 100644 --- a/README-zh.md +++ b/README-zh.md @@ -10,10 +10,11 @@ 🚀Luckysheet ,一款纯前端类似excel的在线表格,功能强大、配置简单、完全开源。 ## 文档 -[在线demo](https://mengshukeji.github.io/LuckysheetDemo/) [在线文档](https://mengshukeji.github.io/LuckysheetDocs/zh/) +[在线demo](https://mengshukeji.github.io/LuckysheetDemo/) / [导入excel demo](https://mengshukeji.github.io/LuckyexcelDemo/) + ![演示](/docs/.vuepress/public/img/LuckysheetDemo.gif) ## 插件 @@ -123,23 +124,21 @@ npm run build ## 用法 #### 第一步 -`npm run build`后`dist`文件夹下的所有文件复制到项目目录 +通过CDN引入依赖 -#### 第二步 -引入依赖 ``` - - - - - + + + + + ``` -#### 第三步 +#### 第二步 指定一个表格容器 ```
``` -#### 第四步 +#### 第三步 创建一个表格 ``` - + + + + + ``` -#### Third step +#### Second step Specify a table container ```
``` -#### Fourth step +#### Third step Create a table ``` + +``` + +Note that `https://cdn.jsdelivr.net/npm/luckysheet/dist/luckysheet.umd.js` will pull the latest luckysheet code. If you want to specify the luckysheet version, please add the version number after the luckysheet , Such as: `https://cdn.jsdelivr.net/npm/luckysheet@2.0.0/dist/luckysheet.umd.js` + +If it is not convenient to access jsdelivr.net, you can also import it locally + +#### Import locally +After `npm run build`, all files in the `dist` folder are copied to the project directory ```html @@ -124,12 +138,12 @@ Introduce dependencies ``` -### Third step +### Second step Specify a table container ```html
``` -### Fourth step +### Third step Create a table ```javascript + +``` + +注意,`https://cdn.jsdelivr.net/npm/luckysheet/dist/luckysheet.umd.js`这个路径会拉取到最新的luckysheet代码,想要指定luckysheet版本,请在luckysheet后面加上版本号,如:`https://cdn.jsdelivr.net/npm/luckysheet@2.0.0/dist/luckysheet.umd.js` + +如果不方便访问 jsdelivr.net,还可以采用本地方式引入 + +#### 本地引入 + +`npm run build`后`dist`文件夹下的所有文件复制到项目目录,然后通过相对路径引入 -### 第二步 -引入依赖 ```html @@ -124,12 +139,12 @@ npm run build ``` -### 第三步 +### 第二步 指定一个表格容器 ```html
``` -### 第四步 +### 第三步 创建一个表格 ```javascript