hyperlinkCtrl.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. import { replaceHtml } from '../utils/util';
  2. import { getcellvalue } from '../global/getdata';
  3. import { luckysheetrefreshgrid } from '../global/refresh';
  4. import { rowLocation, colLocation, mouseposition } from '../global/location';
  5. import formula from '../global/formula';
  6. import tooltip from '../global/tooltip';
  7. import editor from '../global/editor';
  8. import { modelHTML } from './constant';
  9. import { selectHightlightShow } from './select';
  10. import server from './server';
  11. import sheetmanage from './sheetmanage';
  12. import luckysheetFreezen from './freezen';
  13. import menuButton from './menuButton';
  14. import { getSheetIndex } from '../methods/get';
  15. import locale from '../locale/locale';
  16. import Store from '../store';
  17. const hyperlinkCtrl = {
  18. item: {
  19. linkType: 'external', //链接类型 external外部链接,internal内部链接
  20. linkAddress: '', //链接地址 网页地址或工作表单元格引用
  21. linkTooltip: '', //提示
  22. },
  23. hyperlink: null,
  24. createDialog: function(){
  25. let _this = this;
  26. const _locale = locale();
  27. const hyperlinkText = _locale.insertLink;
  28. const toolbarText = _locale.toolbar;
  29. const buttonText = _locale.button;
  30. $("#luckysheet-modal-dialog-mask").show();
  31. $("#luckysheet-insertLink-dialog").remove();
  32. let sheetListOption = '';
  33. Store.luckysheetfile.forEach(item => {
  34. sheetListOption += `<option value="${item.name}">${item.name}</option>`;
  35. })
  36. let content = `<div class="box">
  37. <div class="box-item">
  38. <label for="luckysheet-insertLink-dialog-linkText">${hyperlinkText.linkText}:</label>
  39. <input type="text" id="luckysheet-insertLink-dialog-linkText"/>
  40. </div>
  41. <div class="box-item">
  42. <label for="luckysheet-insertLink-dialog-linkType">${hyperlinkText.linkType}:</label>
  43. <select id="luckysheet-insertLink-dialog-linkType">
  44. <option value="external">${hyperlinkText.external}</option>
  45. <option value="internal">${hyperlinkText.internal}</option>
  46. </select>
  47. </div>
  48. <div class="show-box show-box-external">
  49. <div class="box-item">
  50. <label for="luckysheet-insertLink-dialog-linkAddress">${hyperlinkText.linkAddress}:</label>
  51. <input type="text" id="luckysheet-insertLink-dialog-linkAddress" placeholder="${hyperlinkText.placeholder1}" />
  52. </div>
  53. </div>
  54. <div class="show-box show-box-internal">
  55. <div class="box-item">
  56. <label for="luckysheet-insertLink-dialog-linkSheet">${hyperlinkText.linkSheet}:</label>
  57. <select id="luckysheet-insertLink-dialog-linkSheet">
  58. ${sheetListOption}
  59. </select>
  60. </div>
  61. <div class="box-item">
  62. <label for="luckysheet-insertLink-dialog-linkCell">${hyperlinkText.linkCell}:</label>
  63. <input type="text" id="luckysheet-insertLink-dialog-linkCell" value="A1" placeholder="${hyperlinkText.placeholder2}" />
  64. </div>
  65. </div>
  66. <div class="box-item">
  67. <label for="luckysheet-insertLink-dialog-linkTooltip">${hyperlinkText.linkTooltip}:</label>
  68. <input type="text" id="luckysheet-insertLink-dialog-linkTooltip" placeholder="${hyperlinkText.placeholder3}" />
  69. </div>
  70. </div>`;
  71. $("body").first().append(replaceHtml(modelHTML, {
  72. "id": "luckysheet-insertLink-dialog",
  73. "addclass": "luckysheet-insertLink-dialog",
  74. "title": toolbarText.insertLink,
  75. "content": content,
  76. "botton": `<button id="luckysheet-insertLink-dialog-confirm" class="btn btn-primary">${buttonText.confirm}</button>
  77. <button class="btn btn-default luckysheet-model-close-btn">${buttonText.cancel}</button>`,
  78. "style": "z-index:100003"
  79. }));
  80. let $t = $("#luckysheet-insertLink-dialog").find(".luckysheet-modal-dialog-content").css("min-width", 350).end(),
  81. myh = $t.outerHeight(),
  82. myw = $t.outerWidth();
  83. let winw = $(window).width(),
  84. winh = $(window).height();
  85. let scrollLeft = $(document).scrollLeft(),
  86. scrollTop = $(document).scrollTop();
  87. $("#luckysheet-insertLink-dialog").css({
  88. "left": (winw + scrollLeft - myw) / 2,
  89. "top": (winh + scrollTop - myh) / 3
  90. }).show();
  91. _this.dataAllocation();
  92. },
  93. init: function (){
  94. let _this = this;
  95. const _locale = locale();
  96. const hyperlinkText = _locale.insertLink;
  97. //链接类型
  98. $(document).off("change.linkType").on("change.linkType", "#luckysheet-insertLink-dialog-linkType", function(e){
  99. let value = this.value;
  100. $("#luckysheet-insertLink-dialog .show-box").hide();
  101. $("#luckysheet-insertLink-dialog .show-box-" + value).show();
  102. })
  103. //确认按钮
  104. $(document).off("click.confirm").on("click.confirm", "#luckysheet-insertLink-dialog-confirm", function(e){
  105. let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];
  106. let rowIndex = last.row_focus || last.row[0];
  107. let colIndex = last.column_focus || last.column[0];
  108. //文本
  109. let linkText = $("#luckysheet-insertLink-dialog-linkText").val();
  110. let linkType = $("#luckysheet-insertLink-dialog-linkType").val();
  111. let linkAddress = $("#luckysheet-insertLink-dialog-linkAddress").val();
  112. let linkSheet = $("#luckysheet-insertLink-dialog-linkSheet").val();
  113. let linkCell = $("#luckysheet-insertLink-dialog-linkCell").val();
  114. let linkTooltip = $("#luckysheet-insertLink-dialog-linkTooltip").val();
  115. if(linkType == 'external'){
  116. if(!/^http[s]?:\/\//.test(linkAddress)){
  117. linkAddress = 'https://' + linkAddress;
  118. }
  119. if(!/^http[s]?:\/\/([\w\-\.]+)+[\w-]*([\w\-\.\/\?%&=]+)?$/ig.test(linkAddress)){
  120. tooltip.info('<i class="fa fa-exclamation-triangle"></i>', hyperlinkText.tooltipInfo1);
  121. return;
  122. }
  123. }
  124. else{
  125. if(!formula.iscelldata(linkCell)){
  126. tooltip.info('<i class="fa fa-exclamation-triangle"></i>', hyperlinkText.tooltipInfo2);
  127. return;
  128. }
  129. linkAddress = linkSheet + "!" + linkCell;
  130. }
  131. if(linkText == null || linkText.replace(/\s/g, '') == ''){
  132. linkText = linkAddress;
  133. }
  134. let item = {
  135. linkType: linkType,
  136. linkAddress: linkAddress,
  137. linkTooltip: linkTooltip,
  138. }
  139. let historyHyperlink = $.extend(true, {}, _this.hyperlink);
  140. let currentHyperlink = $.extend(true, {}, _this.hyperlink);
  141. currentHyperlink[rowIndex + "_" + colIndex] = item;
  142. let d = editor.deepCopyFlowData(Store.flowdata);
  143. let cell = d[rowIndex][colIndex];
  144. if(cell == null){
  145. cell = {};
  146. }
  147. cell.fc = 'rgb(0, 0, 255)';
  148. cell.un = 1;
  149. cell.v = cell.m = linkText;
  150. d[rowIndex][colIndex] = cell;
  151. _this.ref(
  152. historyHyperlink,
  153. currentHyperlink,
  154. Store.currentSheetIndex,
  155. d,
  156. [{ row: [rowIndex, rowIndex], column: [colIndex, colIndex] }]
  157. );
  158. $("#luckysheet-modal-dialog-mask").hide();
  159. $("#luckysheet-insertLink-dialog").hide();
  160. })
  161. },
  162. dataAllocation: function(){
  163. let _this = this;
  164. let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];
  165. let rowIndex = last.row_focus || last.row[0];
  166. let colIndex = last.column_focus || last.column[0];
  167. let hyperlink = _this.hyperlink || {};
  168. let item = hyperlink[rowIndex + "_" + colIndex] || {};
  169. //文本
  170. let text = getcellvalue(rowIndex, colIndex, null, 'm');
  171. $("#luckysheet-insertLink-dialog-linkText").val(text);
  172. //链接类型
  173. let linkType = item.linkType || 'external';
  174. $("#luckysheet-insertLink-dialog-linkType").val(linkType);
  175. $("#luckysheet-insertLink-dialog .show-box").hide();
  176. $("#luckysheet-insertLink-dialog .show-box-" + linkType).show();
  177. //链接地址
  178. let linkAddress = item.linkAddress || '';
  179. if(linkType == 'external'){
  180. $("#luckysheet-insertLink-dialog-linkAddress").val(linkAddress);
  181. }
  182. else{
  183. if(formula.iscelldata(linkAddress)){
  184. let sheettxt = linkAddress.split("!")[0];
  185. let rangetxt = linkAddress.split("!")[1];
  186. $("#luckysheet-insertLink-dialog-linkSheet").val(sheettxt);
  187. $("#luckysheet-insertLink-dialog-linkCell").val(rangetxt);
  188. }
  189. }
  190. //提示
  191. let linkTooltip = item.linkTooltip || '';
  192. $("#luckysheet-insertLink-dialog-linkTooltip").val(linkTooltip);
  193. },
  194. cellFocus: function(r, c){
  195. let _this = this;
  196. if(_this.hyperlink == null || _this.hyperlink[r + '_' + c] == null){
  197. return;
  198. }
  199. let item = _this.hyperlink[r + '_' + c];
  200. if(item.linkType == 'external'){
  201. window.open(item.linkAddress);
  202. }
  203. else{
  204. let cellrange = formula.getcellrange(item.linkAddress);
  205. let sheetIndex = cellrange.sheetIndex;
  206. let range = [{
  207. row: cellrange.row,
  208. column: cellrange.column
  209. }];
  210. if(sheetIndex != Store.currentSheetIndex){
  211. $("#luckysheet-sheet-area div.luckysheet-sheets-item").removeClass("luckysheet-sheets-item-active");
  212. $("#luckysheet-sheets-item" + sheetIndex).addClass("luckysheet-sheets-item-active");
  213. sheetmanage.changeSheet(sheetIndex);
  214. }
  215. Store.luckysheet_select_save = range;
  216. selectHightlightShow(true);
  217. let row_pre = cellrange.row[0] - 1 == -1 ? 0 : Store.visibledatarow[cellrange.row[0] - 1];
  218. let col_pre = cellrange.column[0] - 1 == -1 ? 0 : Store.visibledatacolumn[cellrange.column[0] - 1];
  219. $("#luckysheet-scrollbar-x").scrollLeft(col_pre);
  220. $("#luckysheet-scrollbar-y").scrollTop(row_pre);
  221. }
  222. },
  223. overshow: function(event){
  224. let _this = this;
  225. $("#luckysheet-hyperlink-overshow").remove();
  226. if($(event.target).closest("#luckysheet-cell-main").length == 0){
  227. return;
  228. }
  229. let mouse = mouseposition(event.pageX, event.pageY);
  230. let scrollLeft = $("#luckysheet-cell-main").scrollLeft();
  231. let scrollTop = $("#luckysheet-cell-main").scrollTop();
  232. let x = mouse[0] + scrollLeft;
  233. let y = mouse[1] + scrollTop;
  234. if(luckysheetFreezen.freezenverticaldata != null && mouse[0] < (luckysheetFreezen.freezenverticaldata[0] - luckysheetFreezen.freezenverticaldata[2])){
  235. return;
  236. }
  237. if(luckysheetFreezen.freezenhorizontaldata != null && mouse[1] < (luckysheetFreezen.freezenhorizontaldata[0] - luckysheetFreezen.freezenhorizontaldata[2])){
  238. return;
  239. }
  240. let row_index = rowLocation(y)[2];
  241. let col_index = colLocation(x)[2];
  242. let margeset = menuButton.mergeborer(Store.flowdata, row_index, col_index);
  243. if(!!margeset){
  244. row_index = margeset.row[2];
  245. col_index = margeset.column[2];
  246. }
  247. if(_this.hyperlink == null || _this.hyperlink[row_index + "_" + col_index] == null){
  248. return;
  249. }
  250. let item = _this.hyperlink[row_index + "_" + col_index];
  251. let linkTooltip = item.linkTooltip;
  252. if(linkTooltip == null || linkTooltip.replace(/\s/g, '') == ''){
  253. linkTooltip = item.linkAddress;
  254. }
  255. let row = Store.visibledatarow[row_index],
  256. row_pre = row_index - 1 == -1 ? 0 : Store.visibledatarow[row_index - 1];
  257. let col = Store.visibledatacolumn[col_index],
  258. col_pre = col_index - 1 == -1 ? 0 : Store.visibledatacolumn[col_index - 1];
  259. if(!!margeset){
  260. row = margeset.row[1];
  261. row_pre = margeset.row[0];
  262. col = margeset.column[1];
  263. col_pre = margeset.column[0];
  264. }
  265. let html = `<div id="luckysheet-hyperlink-overshow" style="background:#fff;padding:5px 10px;border:1px solid #000;box-shadow:2px 2px #999;position:absolute;left:${col_pre}px;top:${row + 5}px;z-index:100;">
  266. <div>${linkTooltip}</div>
  267. <div>单击鼠标可以追踪</div>
  268. </div>`;
  269. $(html).appendTo($("#luckysheet-cell-main"));
  270. },
  271. ref: function(historyHyperlink, currentHyperlink, sheetIndex, d, range){
  272. let _this = this;
  273. if (Store.clearjfundo) {
  274. Store.jfundo.length = 0;
  275. let redo = {};
  276. redo["type"] = "updateHyperlink";
  277. redo["sheetIndex"] = sheetIndex;
  278. redo["historyHyperlink"] = historyHyperlink;
  279. redo["currentHyperlink"] = currentHyperlink;
  280. redo["data"] = Store.flowdata;
  281. redo["curData"] = d;
  282. redo["range"] = range;
  283. Store.jfredo.push(redo);
  284. }
  285. _this.hyperlink = currentHyperlink;
  286. Store.luckysheetfile[getSheetIndex(sheetIndex)].hyperlink = currentHyperlink;
  287. Store.flowdata = d;
  288. editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据
  289. Store.luckysheetfile[getSheetIndex(sheetIndex)].data = Store.flowdata;
  290. //共享编辑模式
  291. if(server.allowUpdate){
  292. server.saveParam("all", sheetIndex, currentHyperlink, { "k": "hyperlink" });
  293. server.historyParam(Store.flowdata, sheetIndex, range[0]);
  294. }
  295. setTimeout(function () {
  296. luckysheetrefreshgrid();
  297. }, 1);
  298. }
  299. }
  300. export default hyperlinkCtrl;