1(function (root, factory) { 2 3 "use strict"; 4 5 // CommonJS module is defined 6 if (typeof module !== 'undefined' && module.exports) { 7 module.exports = factory(require('jquery')); 8 } 9 // AMD module is defined 10 else if (typeof define === "function" && define.amd) { 11 define("UTK", ["jquery"], function ($) { 12 return factory($); 13 }); 14 } else { 15 // planted over the root! 16 root.UTK = factory(root.jQuery); 17 } 18}(this, function ($) { 19 20 "use strict"; 21 22 /* ================================================ 23 * Definition of UTKModal. 24 * ================================================ */ 25 //var Modal = $.fn.modal.constructor; 26 //var UTKModal = function (element, options) { 27 // Modal.call(this, element, options); 28 //}; 29 30 //UTKModal.prototype = { 31 // constructor: UTKModal 32 //}; 33 //UTKModal.prototype = $.extend(UTKModal.prototype, $.fn.modal.Constructor.prototype); 34 35 /* ================================================ 36 * Definition 37 * ================================================ */ 38 var UTK = function (options) { 39 this.defaultOptions = $.extend(true, { 40 id: UTK.newGuid(), 41 // 'jquery.serializejson': '2.9.0', 42 // 'Keen': "v2.0.9" 43 }, UTK.defaultOptions); 44 }; 45 46 UTK.newGuid = function () { 47 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 48 var r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8); 49 return v.toString(16); 50 }); 51 }; 52 53 //UTK.UTKModal = UTKModal; 54 55 /* ================================================ 56 * default options 57 * ================================================ */ 58 UTK.defaultOptions = function () { 59 return { 60 blockOptions: function (options) { 61 return $.extend(true, { 62 overlayColor: '#000', 63 opacity: 0.5, 64 baseZ: 99999, 65 }, options); 66 }, 67 68 ajaxOptions: function (options) { 69 return $.extend(true, { 70 block: true, 71 blockElement: '', 72 type: 'POST', 73 dataType: 'json', 74 contentType: 'application/json; charset=utf-8', 75 timeout: 120000, 76 showError: true 77 }, options); 78 }, 79 80 KTDataTableOptions: function (options) { 81 return $.extend(true, { 82 data: { 83 type: "remote", 84 source: { 85 read: { 86 method: 'POST', 87 timeout: 60000, 88 map: function (raw) { 89 var dataSet = raw; 90 if (typeof raw.data !== 'undefined') { 91 dataSet = raw.data; 92 } 93 return dataSet; 94 } 95 } 96 }, 97 saveState: { 98 cookie: false, 99 webstorage: false 100 }, 101 //saveState: false, 102 pageSize: 10, 103 serverPaging: true, 104 serverFiltering: true, 105 serverSorting: true 106 }, 107 layout: { 108 theme: 'default', 109 class: 'datatable datatable-umall datatable-bordered', 110 scroll: true, 111 footer: false 112 }, 113 rows: { 114 authHide: true 115 }, 116 sortable: false, 117 pagination: true, 118 tooltip: true, 119 toolbar: { 120 items: { 121 pagination: { 122 pageSizeSelect: [5, 10, 20, 30, 50, 100] 123 }, 124 info: true 125 } 126 }, 127 error: function (ev, jqXHR, msg) { 128 swal.fire('Error', msg, 'error'); 129 }, 130 scrollto: true 131 }, options); 132 }, 133 134 dateRangePickerOptions: function (options) { 135 return $.extend(true, {
136 buttonClasses: 'btn btn-sm', 137 applyClass: 'btn-primary', 138 cancelClass: 'btn-default', 139 alwaysShowCalendars: true, 140 autoApply: false, 141 autoUpdateInput: false, 142 showDropdowns: true, 143 opens: "right", 144 maxYear: new Date().getFullYear() + 30, 145 ranges: { 146 "æ¨å¤©": [moment().add(-1, 'days'), moment().add(-1, 'days')], 147 "ä»å¤©": [moment(), moment()], 148 "éå»3天": [moment().subtract(2, "days"), moment()], 149 "éå»7天": [moment().subtract(6, "days"), moment()], 150 "æ¬æ": [moment().startOf("month"), moment().endOf("month")], 151 "ä¸åæ": [moment().subtract(1, "month").startOf("month"), moment().subtract(1, "month").endOf("month")] 152 }, 153 locale: { 154 separator: " - ", 155 format: "YYYY/MM/DD", 156 firstDay: 1, 157 applyLabel: GetSystemLanguageText("確å®"), 158 cancelLabel: GetSystemLanguageText("åæ¶"), 159 fromLabel: GetSystemLanguageText("éå§æ¥æ"), 160 toLabel: GetSystemLanguageText("çµææ¥æ"), 161 customRangeLabel: "èªè¨èµ·è¨", 162 daysOfWeek: ["æ¥", "ä¸", "äº", "ä¸", "å", "äº", "å "], 163 monthNames: ["1æ", "2æ", "3æ", "4æ", "5æ", "6æ", "7æ", "8æ", "9æ", "10æ", "11æ", "12æ"] 164 } 165 }, options); 166 }, 167 168 datepickerOptions: function (options) { 169 return $.extend(true, { 170 singleDatePicker: true, 171 showDropdowns: true, 172 minYear: 1901, 173 maxYear: new Date().getFullYear() + 10, 174 autoApply: true, 175 locale: { 176 separator: " - ", 177 format: "YYYY/MM/DD", 178 firstDay: 1, 179 applyLabel: GetSystemLanguageText("確å®"), 180 cancelLabel: GetSystemLanguageText("åæ¶"), 181 fromLabel: GetSystemLanguageText("éå§æ¥æ"), 182 toLabel: GetSystemLanguageText("çµææ¥æ"), 183 daysOfWeek: ["æ¥", "ä¸", "äº", "ä¸", "å", "äº", "å "], 184 monthNames: ["1æ", "2æ", "3æ", "4æ", "5æ", "6æ", "7æ", "8æ", "9æ", "10æ", "11æ", "12æ"] 185 } 186 }, options); 187 }, 188 datetimepickerOptions: function (options) { 189 return $.extend(true, { 190 singleDatePicker: true, 191 showDropdowns: true, 192 minYear: 1901, 193 maxYear: new Date().getFullYear() + 10, 194 autoApply: true, 195 timePicker: true, 196 timePicker24Hour: true, 197 locale: { 198 separator: " - ", 199 format: "YYYY/MM/DD HH:mm", 200 firstDay: 1, 201 applyLabel: GetSystemLanguageText("確å®"), 202 cancelLabel: GetSystemLanguageText("æ¸ é¤"), 203 fromLabel: GetSystemLanguageText("éå§æ¥æ"), 204 toLabel: GetSystemLanguageText("çµææ¥æ"), 205 daysOfWeek: ["æ¥", "ä¸", "äº", "ä¸", "å", "äº", "å "], 206 monthNames: ["1æ", "2æ", "3æ", "4æ", "5æ", "6æ", "7æ", "8æ", "9æ", "10æ", "11æ", "12æ"] 207 } 208 }, options); 209 }, 210 211 selectPickerOptions: function (options) { 212 return $.extend(true, { 213 }, options); 214 }, 215 216 select2Options: function (options) { 217 return $.extend(true, { 218 allowClear: true, 219 minimumResultsForSearch: 'Infinity', 220 width: 'resolve' 221 }, options); 222 }, 223 224 DataTableOptions: function (options) { 225 return $.extend(true, { 226 //ajax: { 227 // type: 'POST' 228 //}, 229 blockElement: "body", 230 processing: true, 231 serverSide: false, 232 searching: false, 233 //ordering: true, 234 //autoWidth :true, 235 orderMulti: false, 236 scrollX: true, 237 autoFill: false, 238 lengthMenu: [[20, 50, 100, -1], [20, 50, 100, "All"]], 239 language: { 240 sProcessing: GetSystemLanguageText("è®åä¸") + "...", 241 sLengthMenu: GetSystemLanguageText("sLengthMenu"), 242 sZeroRecords: GetSystemLanguageText("æ¥ç¡è³æ"), 243 sEmptyTable: GetSystemLanguageText("æ¥ç¡è³æ"), 244 sInfo: GetSystemLanguageText("sInfo"), 245 sInfoEmpty: GetSystemLanguageText("æ¥ç¡è³æ"), 246 sLoadingRecords: GetSystemLanguageText("è®åä¸") + "...", 247 } 248 }, options); 249 }, 250 toastOptions: function (options) { 251 return $.extend(true, { 252 "closeButton": false, 253 "debug": false, 254 "newestOnTop": false, 255 "progressBar": false, 256 "positionClass": "toastr-top-right", 257 "preventDuplicates": false, 258 "onclick": null, 259 "showDuration": "300", 260 "hideDuration": "1000", 261 "timeOut": "5000", 262 "extendedTimeOut": "1000", 263 "showEasing": "swing", 264 "hideEasing": "linear", 265 "showMethod": "fadeIn", 266 "hideMethod": "fadeOut" 267 }, options); 268 }, 269 quillOptions: function (options) { 270 return $.extend(true, { 271 modules: { 272 toolbar: { 273 container: [ 274 ['bold', 'italic'], 275 //['link', 'blockquote', 'code-block', 'image'], 276 ['link', 'image', 'file'], // é裡æ file çéµ 277 [{ 'list': 'ordered' }, { 'list': 'bullet' }], 278 [{ 'size': ['small', false, 'large', 'huge'] }], 279 [{ 'header': [1, 2, 3, 4, 5, 6, false] }], 280 [{ 'color': [] }, { 'background': [] }], 281 [{ 'align': [] }], 282 ], 283 handlers: { 284 file: function () { 285 console.log("èªè¨æªæ¡æéè¢«é»æ"); 286 } 287 } 288 } 289 }, 290 theme: 'snow' 291 }, options); 292 }, 293 } 294 }(); 295 296 /* ================================================ 297 * block ui 298 * ================================================ */ 299 UTK.blockPage = function (options) { 300 UTK.block("body", UTK.defaultOptions.blockOptions(options)); 301 }; 302 303 UTK.unblockPage = function () { 304 UTK.unblock("body"); 305 }; 306 307 UTK.block = function (element, options) { 308 if (element == '') { element = "body"; } 309 let target = document.querySelector(element); 310 if (typeof target == 'undefined') return; 311 var blockUI = KTBlockUI.getInstance(target); 312 if (blockUI == null) { 313 blockUI = new KTBlockUI(target); 314 blockUI.block(); 315 } 316 else if (!blockUI.isBlocked()) { 317 blockUI.block(); 318 } 319 320 //let opt = UTK.defaultOptions.blockOptions(options); 321 //var blockUI = new KTBlockUI(target);//, opt); 322 //blockUI.block(); 323 324 return blockUI; 325 }; 326 327 UTK.unblock = function (element, options) { 328 if (element == '') { element = "body"; } 329 let target = document.querySelector(element); 330 if (typeof target == 'undefined') return; 331 var blockUI = KTBlockUI.getInstance(target); 332 if (blockUI != null && blockUI.isBlocked()) { 333 blockUI.release(); 334 } 335 }; 336 337 /* ================================================ 338 * ajax 339 * ================================================ */ 340 UTK.ajax = function (url, options) { 341 var headers = { 'RequestVerificationToken': $("input[name='__RequestVerificationToken']").val() }; 342 if (typeof options.headers != 'undefined') { 343 $.each(options.headers, function (name, value) { 344 headers[name] = value; 345 }); 346 } 347 348 var opt = $.extend({}, options, UTK.defaultOptions.ajaxOptions(options)); 349 350 var ajaxParams = { 351 headers: headers, 352 data: {}, 353 beforeSend: function (jqXHR) { 354 if (opt.block) { 355 UTK.block(opt.blockElement); 356 } 357 }, 358 complete: function (XMLHttpRequest, textStatus) { 359 if (opt.block) { 360 UTK.unblock(opt.blockElement); 361 } 362 }, 363 error: function (jqXHR, textStatus, errorThrown) { 364 try { 365 let result = JSON.parse(jqXHR.responseText); 366 console.log(result); 367 if (options.showError) { 368 if (jqXHR.status === 401) { 369 // 401 身份é©è失æï¼éå®åå°ç»å ¥é é¢ 370 UTK.Notice(GetSystemLanguageText("身åè¶ æï¼è«éæ°ç»å ¥"), function () { window.location.href = '/account/login'; }); 371 372 return false; 373 } 374 Swal.fire(result._returnMessage, "Code=" + result._returnCode, "error"); 375 } 376 377 } catch { 378 console.log(jqXHR); 379 if (options.showError) { 380 if (jqXHR.status === 401) { 381 // 401 身份é©è失æï¼éå®åå°ç»å ¥é é¢ 382 UTK.Notice(GetSystemLanguageText("身åè¶ æï¼è«éæ°ç»å ¥"), function () { window.location.href = '/account/login'; }); 383 return false; 384 } 385 Swal.fire(jqXHR.status + " - " + jqXHR.statusText, "", "error"); 386 } 387 } 388 } 389 }; 390 391 ajaxParams = $.extend({}, ajaxParams, opt); 392
393 return $.ajax(url, ajaxParams); 394 }; 395 396 UTK.loadHtml = function (url, options) { 397 var headers = { 'RequestVerificationToken': $("input[name='__RequestVerificationToken']").val() }; 398 if (typeof options.headers != 'undefined') { 399 $.each(options.headers, function (name, value) { 400 headers[name] = value; 401 }); 402 } 403 404 var opt = $.extend({}, options, UTK.defaultOptions.ajaxOptions(options)); 405 opt.dataType = 'html'; 406 407 var ajaxParams = { 408 headers: headers, 409 data: {}, 410 beforeSend: function (jqXHR) { 411 if (opt.block) { 412 UTK.block(opt.blockElement); 413 } 414 }, 415 complete: function (XMLHttpRequest, textStatus) { 416 if (opt.block) { 417 UTK.unblock(opt.blockElement); 418 } 419 }, 420 success: function (html) { 421 if (typeof opt.bindElement === 'string' && opt.bindElement != '') { 422 $(opt.bindElement).html(html); 423 if (typeof opt.scrollto !== "undefined" && opt.scrollto == true) { 424 var x = $(opt.bindElement).offset().top - 100; 425 $('html,body').animate({ scrollTop: x }, 400); 426 } 427 } 428 }, 429 error: function (jqXHR, textStatus, errorThrown) { 430 try { 431 let result = JSON.parse(jqXHR.responseText); 432 console.log(result); 433 if (options.showError) { 434 Swal.fire(result._returnMessage, "Code=" + result._returnCode, "error"); 435 } 436 437 } catch { 438 console.log(jqXHR); 439 if (options.showError) { 440 Swal.fire(jqXHR.status + " - " + jqXHR.statusText, "", "error"); 441 } 442 } 443 } 444 }; 445 446 ajaxParams = $.extend({}, ajaxParams, opt); 447 448 return $.ajax(url, ajaxParams); 449 }; 450 451 /* ================================================ 452 * form 453 * ================================================ */ 454 UTK.setUIControl = function (container, options) { 455 //datepicker 456 $(container).find('[data-control="datepicker"]').each(function (index) { 457 let option = UTK.defaultOptions.datepickerOptions({}); 458 let f = $(this).data('format'); 459 let d = $(this).data('drops'); 460 let s = $(this).data('mindate'); 461 462 if (f != 'undefined') { 463 option = $.extend(true, { 464 locale: { 465 format: f 466 } 467 }, option); 468 } 469 if (d != 'undefined') { 470 option = $.extend(true, { 471 drops: d 472 }, option); 473 } 474 if (s != 'undefined') { 475 option = $.extend(true, { 476 minDate: s 477 }, option); 478 } 479 480 $(this).daterangepicker(option); 481 $(this).attr('autocomplete', 'off'); 482 }); 483 //daterangepicker 484 $(container).find('[data-control="daterangepicker"]').each(function (index) { 485 let option = UTK.defaultOptions.dateRangePickerOptions({}); 486 let days = $(this).data('days'); 487 if (typeof days != 'undefined') { 488 option = $.extend(true, { 489 "maxSpan": { 490 "days": days 491 } 492 }, option); 493 } 494 let defaultRanges = $(this).data('defaultranges'); 495 if (typeof defaultRanges != 'undefined') { 496 if (defaultRanges == 'all') { 497 option = $.extend(true, { 498 "ranges": { 499 'Today': [moment(), moment()], 500 'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')], 501 'Last 3 Days': [moment().subtract(2, 'days'), moment()], 502 'Last 7 Days': [moment().subtract(6, 'days'), moment()], 503 'Last 30 Days': [moment().subtract(29, 'days'), moment()], 504 'This Month': [moment().startOf('month'), moment().endOf('month')], 505 'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')] 506 } 507 }, option); 508 } 509 } 510 511 let setOptions = $(this).data('setoptions'); 512 if (typeof setOptions != 'undefined' && setOptions != '') { 513 var fn = window[setOptions]; 514 if (typeof fn === "function") { 515 option = fn(option); 516 } 517 } 518 519 let container1 = $(this).data('container'); 520 if (typeof container1 != 'undefined' && container1 != '') { 521 option = $.extend(true, { 522 "parentEl": container1 523 }, option); 524 } 525 let maxYearOffset = $(this).data('max-year-offset'); 526 if (typeof maxYearOffset != 'undefined') { 527 option = $.extend(true, { 528 maxYear: new Date().getFullYear() + maxYearOffset, 529 }, option); 530 } 531 let startDate = $($(this).data('startdate-for')).val(); 532 if (typeof startDate != 'undefined' && startDate != '') { 533 option = $.extend(true, { 534 "startDate": new Date(startDate) 535 }, option); 536 } 537 let endDate = $($(this).data('enddate-for')).val(); 538 if (typeof endDate != 'undefined' && endDate != '') { 539 option = $.extend(true, { 540 "endDate": new Date(endDate) 541 }, option); 542 } 543 544 let drp = $(this).daterangepicker(option); 545 $(this).on("apply.daterangepicker", function (ev, picker) { 546 debugger; 547 UTK.daterangepickerSetDate(container, this, picker.startDate, picker.endDate); 548 }); 549 $(this).on("cancel.daterangepicker", function (ev, picker) { 550 //UTK.daterangepickerSetDate(container, this, '', ''); 551 }); 552 $(this).on("hide.daterangepicker", function (ev, picker) { 553 $(this).data('daterangepicker').element.trigger('change'); 554 }); 555 $(this).on("change", function (ev) { 556 if ($(this).val() == "") { 557 UTK.daterangepickerSetDate(container, this, '', ''); 558 } 559 else { 560 UTK.daterangepickerSetDate(container, this, $(this).data('daterangepicker').startDate, $(this).data('daterangepicker').endDate); 561 } 562 }); 563 $(this).trigger('change'); 564 }); 565 //selectpicker
566 $(container).find('[data-control="selectpicker"]').each(function (index) { 567 let option = UTK.defaultOptions.select2Options({}); 568 let s = $(this).data('allowclear'); 569 if (typeof s != 'undefined') { 570 option.allowClear = false; 571 } 572 let a = $(this).data('search'); 573 if (typeof a != 'undefined') { 574 option.minimumResultsForSearch = 1; 575 option.dropdownParent = $(this).parent(); 576 } 577 let w = $(this).data('width'); 578 if (typeof w != 'undefined') { option.width = w; } 579 let p = $(this).data('placeholder'); 580 if (typeof p != 'undefined') { option.placeholder = p; } 581 582 $(this).select2(option); 583 }); 584 //datepicker 585 $(container).find('[data-control="datetimepicker"]').each(function (index) { 586 let option = UTK.defaultOptions.datetimepickerOptions({}); 587 let f = $(this).data('format'); 588 let d = $(this).data('drops'); 589 let s = $(this).data('mindate'); 590 let a = $(this).data('auto') 591 592 if (typeof f != 'undefined') { 593 option = $.extend(true, { 594 locale: { 595 format: f 596 } 597 }, option); 598 } 599 if (typeof d != 'undefined') { 600 option = $.extend(true, { 601 drops: d 602 }, option); 603 } 604 if (typeof s != 'undefined') { 605 option = $.extend(true, { 606 minDate: s 607 }, option); 608 } 609 if (typeof a != 'undefined') { 610 option = $.extend(true, { 611 autoApply: false 612 }, option); 613 } 614 615 $(this).daterangepicker(option); 616 $(this).on('cancel.daterangepicker', function (ev, picker) { 617 $(this).val(''); 618 }); 619 $(this).attr('autocomplete', 'off'); 620 }); 621 622 //TODO: timepicker 623 $(container).find('[data-control="timepicker"]').each(function (index) { }); 624 625 $(container).find('[data-control="countup"]').each(function (item, index) { 626 var ele = new CountUp(index, $(this).data('countup-value')); 627 ele.start(); 628 }); 629 630 $(container).find('[data-control="htmleditor"]').each(function (index) { 631 var icons = Quill.import('ui/icons'); 632 // è¨å® file éµçå示ï¼éè£¡ä½¿ç¨ Font Awesome ç file iconï¼ 633 icons['file'] = '<i class="fa-solid fa-upload"></i>'; 634 var editor = new Quill(this, 635 UTK.defaultOptions.quillOptions({ 636 placeholder: $(this).prop('placeholder') 637 })); 638 $(this).find('[class=ql-editor]').attr('id', this.id + '_ql_editor'); 639 640 //æ´æHtml編輯å¨çä¸å³æªæ¡åè½ 641 //æå¼å« homecontrollerä¸çimageuploadæ¹æ³ 642 editor.getModule('toolbar').addHandler('image', function () { 643 const input = document.createElement('input'); 644 input.setAttribute('type', 'file'); 645 input.setAttribute('accept', 'image/png, image/jpeg') 646 input.click(); 647 648 // Listen upload local image and save to server 649 input.onchange = function () { 650 const file = input.files[0]; 651 const fd = new FormData(); 652 fd.append('files', file); 653 //éå¶æªæ¡å¤§å° 654 655 const xhr = new XMLHttpRequest(); 656 xhr.open('POST', '/quillimageupload', true); 657 xhr.setRequestHeader('RequestVerificationToken', $("input[name='__RequestVerificationToken']").val()); 658 xhr.onload = function () { 659 if (xhr.status === 200) { 660 // this is callback data: url 661 const url = JSON.parse(xhr.responseText).Data; 662 const range = editor.getSelection(); 663 editor.insertEmbed(range.index, 'image', `/getshareimage/quillhtmledit/${url.toString()}`); 664 } 665 }; 666 xhr.send(fd); 667 }; 668 }); 669 //æªæ¡ä¸å³ å¯ä¸å³PDF,Word,Excelçæªæ¡ï¼ä¸å³å¾æå¾å°è½æå¾çç¶²å 670 editor.getModule('toolbar').addHandler('file', function () { 671 const input = document.createElement('input');
672 input.setAttribute('type', 'file'); 673 input.setAttribute('accept', 'application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.oasis.opendocument.text'); 674 input.click(); 675 676 // Listen upload local image and save to server 677 input.onchange = function () { 678 debugger; 679 const file = input.files[0]; 680 const fd = new FormData(); 681 fd.append('files', file); 682 //éå¶æªæ¡å¤§å° 683 684 const xhr = new XMLHttpRequest(); 685 xhr.open('POST', '/quillfileupload', true); 686 xhr.setRequestHeader('RequestVerificationToken', $("input[name='__RequestVerificationToken']").val()); 687 xhr.onload = function () { 688 if (xhr.status === 200) { 689 /// åå¾åå³è³æä¸ç URL 690 const url = JSON.parse(xhr.responseText).Data; 691 // è¥æ²æé¸æç¯åï¼é è¨æå ¥å°ç·¨è¼¯å¨æå¾ 692 const range = editor.getSelection() || { index: editor.getLength() }; 693 const filename = file.name; 694 const newUrl = `/getsharefile/quillhtmledit/${url.toString()}`; 695 696 // ä½¿ç¨ insertTextï¼ä¸¦è¨å®æ ¼å¼çºé£çµ 697 editor.insertText(range.index, filename, { link: newUrl }); 698 // æ´æ°æ¸¸æ¨ä½ç½® 699 editor.setSelection(range.index + filename.length); 700 } 701 }; 702 xhr.send(fd); 703 }; 704 }); 705 }); 706 707 //ç§»é¤ç覽å¨èªåå¡«å ¥ 708 $(container).find('input[type="text"]').attr('autocomplete', 'off'); 709 $(container).find('input[type="email"], input[type="password"]').attr('autocomplete', 'nope'); 710 $(container).on('keyup keypress', function (e) { 711 var keyCode = e.keyCode || e.which; 712 if (keyCode === 13 && e.target.tagName !== 'TEXTAREA') { 713 e.preventDefault(); 714 return false; 715 } 716 }); 717 //給äºç«é¢å ç´ maxlengthææ 718 $(container).find('input[type="text"],input[type="number"],textarea').each(function () { 719 if ($(this).attr('maxlength') !== undefined) { 720 $(this).maxlength({ 721 warningClass: "badge badge-primary", 722 limitReachedClass: "badge badge-success" 723 }); 724 } 725 }); 726 727 //å çºæè½åé¡ Tooltipå¿ é èªè¡åå§å 728 $(container).find('[data-bs-toggle="tooltip"]').each(function () { 729 new bootstrap.Tooltip($(this)); 730 }); 731 732 //æå²åæéå ä¸Loadingææï¼ä¸ç§å¾æ¢å¾©æ£å¸¸æé 733 $(container).find('[data-control="savebutton"]').each(function () { 734 $(this).on('click', function () { 735 var thisButton = $(this); 736 thisButton.attr('disabled', true); 737 setTimeout(function () { thisButton.removeAttr('disabled'); }, 1000); 738 }); 739 }); 740 741 moment.locale('zh-tw'); 742 $(container).find('[data-moment]').each(function () { 743 var dtime = $(this).data('moment'); 744 if (dtime) { 745 $(this).text(moment(dtime).fromNow()); 746 $(this).val(moment(dtime).fromNow()); 747 } 748 }) 749 750 }; 751 752 UTK.setQueryUIControl = function (container, defaultOrderBy, query) { 753 if (defaultOrderBy) { 754 var x = 0; 755 $(container).find('.tableOrderBy').each(function () { 756 var obj = $(this); 757 var foundItem = defaultOrderBy.find(x => x.Column == obj.data('orderby')); 758 759 if (foundItem && foundItem.Dir == 'ASC') { 760 $(this).append('<i class="icon asc fa-solid fa-caret-up ms-2 text-white"></i>'); 761 obj.data('sort', x++); 762 } else if (foundItem && foundItem.Dir == 'DESC') { 763 $(this).append('<i class="icon desc fa-solid fa-caret-down ms-2 text-white"></i>'); 764 obj.data('sort', x++); 765 } 766 }); 767 } 768 $(container).find('.tableOrderBy').click(function () { 769 //è¥æ²æ.icon å°±å ä¸<i class="icon asc fa-solid fa-caret-up"></i> åå ä¸ sort 770 //è¥æ.icon asc å°±å ä¸ <i class="icon desc fa-solid fa-caret-down"></i> 771 //è¥æ.icon desc å°±ç§»é¤ .icon & sort 772 var obj = $(this); 773 if (obj.find('.icon').length == 0) { 774 var maxSort = 0; //æ¾icon䏿大çsort 775 $('.tableOrderBy .icon').each(function () { 776 var sort = parseInt($(this).parent().data('sort')); 777 if (!isNaN(sort) && sort > maxSort) { 778 maxSort = sort; 779 } 780 }); 781 obj.append('<i class="icon asc fa-solid fa-caret-up ms-2 text-white"></i>'); 782 obj.data('sort', maxSort + 1); 783 } 784 else if (obj.find('.icon.asc').length > 0) { 785 obj.find('.icon').remove(); 786 obj.append('<i class="icon desc fa-solid fa-caret-down ms-2 text-white"></i>'); 787 } 788 else { 789 obj.find('.icon').remove(); 790 obj.removeData('sort'); 791 } 792 793 query(); 794 }); 795 } 796 797 UTK.daterangepickerSetDate = function (container, element, startDate, endDate) { 798 let startDateElement = $(element).data('startdate-for'); 799 let endDateElement = $(element).data('enddate-for'); 800 if ((typeof startDate === 'string' && startDate == '') || 801 (typeof endDate === 'string' && endDate == '')) { 802 $(element).val(""); 803 if (typeof startDateElement !== 'undefined') { 804 $(container).find(startDateElement).val(''); 805 } 806 if (typeof endDateElement !== 'undefined') { 807 $(container).find(endDateElement).val(''); 808 } 809 } 810 else { 811 let drp = $(element).data('daterangepicker'); 812 drp.setStartDate(startDate); 813 drp.setEndDate(endDate); 814 var startValue = drp.startDate.format(drp.locale.format); 815 var endValue = drp.endDate.format(drp.locale.format); 816 $(element).val(startValue + drp.locale.separator + endValue); 817 $(container).find(startDateElement).val(startValue); 818 $(container).find(endDateElement).val(endValue); 819 } 820 }; 821 822 UTK.formReset = function (container) { 823 let forms = $(container).find('form'); 824 forms.each(function (index) { 825 forms[index].reset(); 826 }); 827 $(container).find('[data-control-selectpicker]').each(function (index) { 828 $(this).selectpicker('refresh'); 829 });
830 $(container).find('[data-control="selectpicker"]').each(function (index) { 831 //$(this).selectpicker('refresh'); //bootstrap-selectpickerç¨ç 832 $(this).val('').trigger('change'); 833 }); 834 835 $(container).find('[data-control-daterangepicker]').each(function (index) { 836 $(this).trigger('change'); 837 }); 838 $(container).find('[data-control="daterangepicker"]').each(function (index) { 839 $(this).trigger('change'); 840 }); 841 $(container).find('.tableOrderBy').each(function () { 842 $(this).find('.icon').remove(); 843 $(this).removeData('sort'); 844 }); 845 }; 846 847 UTK.formValidation = function (container, options) { 848 var el = $(container).get(0); 849 var opt = $.extend(true, 850 { 851 noMessage: false, 852 plugins: { 853 trigger: new FormValidation.plugins.Trigger(), 854 submitButton: new FormValidation.plugins.SubmitButton(), 855 bootstrap: new FormValidation.plugins.Bootstrap5(), 856 //icon: new FormValidation.plugins.Icon({ 857 // valid: 'fa fa-check', 858 // invalid: 'fa fa-times', 859 // validating: 'fa fa-refresh', 860 //}), 861 } 862 }, options); 863 864 var validation = FormValidation.formValidation(el, opt) 865 .on('core.field.invalid', function (e) { 866 $('#' + e).focus(); 867 }) 868 .on('plugins.message.displayed', function (e) { 869 if (!opt.noMessage) { 870 e.messageElement.style.display = 'none'; 871 } 872 }); 873 874 return validation; 875 } 876 877 UTK.formJSON = function (element) { 878 var myform = $(element); 879 var disabled = myform.find(':input:disabled').removeAttr('disabled'); 880 var json = myform.serializeJSON(); 881 disabled.attr('disabled', 'disabled'); 882 883 return json; 884 }; 885 UTK.formQueryJSON = function (queryform,element) { 886 var myform = $(queryform); 887 var disabled = myform.find(':input:disabled').removeAttr('disabled'); 888 var json = myform.serializeJSON(); 889 disabled.attr('disabled', 'disabled'); 890 891 json.Order = []; 892 $(element).find('.tableOrderBy > .icon').each(function () { 893 var obj = $(this).parent(); 894 var dir = obj.find('.icon.asc').length > 0 ? 'ASC' : 'DESC'; 895 var sort = obj.data('sort'); 896 897 if (json.Order.find(x => x.Column == obj.data('orderby'))) return; 898 json.Order.push({ Column: obj.data('orderby'), ColumnAllPage: obj.data('allorderby'), Dir: dir, Sort: sort }); 899 }); 900 json.Order = json.Order.sort((a, b) => a.Sort - b.Sort).map(x => { delete x.Sort; return x; }); 901 902 return json; 903 }; 904 UTK.formSetQueryJSON = function (element,sessionName) { 905 var myform = $(element); 906 var searchParams = sessionStorage.getItem(sessionName); 907 if (searchParams) { 908 searchParams = JSON.parse(searchParams); 909 myform.find('input').each(function () { 910 var name = $(this).attr('name'); 911 var type = $(this).attr('type'); 912 if (searchParams[name]) { 913 if (type == 'checkbox') { 914 $(this).prop('checked', searchParams[name]); 915 } 916 else if (type == 'radio') { 917 if ($(this).val() == searchParams[name]) { 918 $(this).prop('checked', true); 919 } 920 } 921 else $(this).val(searchParams[name]); 922 } 923 }); 924 myform.find('select').each(function () { 925 var name = $(this).attr('name'); 926 if (searchParams[name]) { 927 $(this).val(searchParams[name]).trigger('change');; 928 } 929 }); 930 } 931 } 932 933 UTK.getFormData = function (form) { 934 var data = new FormData($(form).get(0)); 935 return data; 936 }; 937 938 UTK.Notice = function (text, success) { 939 Swal.fire({ 940 title: GetSystemLanguageText("è¦å"), 941 text: text, 942 icon: "warning", 943 buttonsStyling: false, 944 confirmButtonText: GetSystemLanguageText("éé"), 945 customClass: { 946 confirmButton: "btn btn-primary" 947 } 948 }).then((result) => { 949 if (typeof success === 'function') success(result); 950 }); 951 } 952 UTK.NoticeHtml = function (text, success) { 953 Swal.fire({ 954 html: text, 955 title: GetSystemLanguageText("è¦å"), 956 icon: "warning", 957 buttonsStyling: false, 958 confirmButtonText: GetSystemLanguageText("éé"), 959 customClass: { 960 confirmButton: "btn btn-primary" 961 } 962 }).then((result) => { 963 if (typeof success === 'function') success(result); 964 }); 965 } 966 967 UTK.Success = function (text, success) { 968 Swal.fire({ 969 title: GetSystemLanguageText("æå"), 970 text: text, 971 icon: "success", 972 buttonsStyling: false, 973 confirmButtonText: GetSystemLanguageText("éé"), 974 customClass: { 975 confirmButton: "btn btn-primary" 976 } 977 }).then((result) => { 978 if (typeof success === 'function') success(result); 979 }); 980 } 981 982 UTK.SuccessHtml = function (text, success) { 983 Swal.fire({ 984 html: text, 985 title: GetSystemLanguageText("æå"), 986 icon: "success", 987 buttonsStyling: false, 988 confirmButtonText: GetSystemLanguageText("éé"), 989 customClass: { 990 confirmButton: "btn btn-primary" 991 } 992 }).then((result) => { 993 if (typeof success === 'function') success(result); 994 }); 995 } 996 997 UTK.AutoCloseNotice = function (text, success, title, time) { 998 //è¥time æ²çµ¦å¼ é è¨5 999 time = time || 5; 1000 // è¥ title æ²çµ¦å¼ï¼é è¨çº "è¦å" 1001 title = title || GetSystemLanguageText("è¦å"); 1002 1003 Swal.fire({ 1004 title: title, 1005 html: `${text}<br><br><span style="font-size:0.8rem;">å½è·³è¦çªå°å¨ <b id="timer">${time}</b> ç§å¾éé</span>`, 1006 timer: time * 1000, // è¨ç½®èªåééæéçº5ç§ 1007 timerProgressBar: true, // 顯示é²åº¦æ¢
1008 showConfirmButton: false, // é±èç¢ºèªæé 1009 didOpen: () => { 1010 // éå§åæ¸è¨æ 1011 const timerElement = document.getElementById('timer'); 1012 let timerInterval = setInterval(() => { 1013 let timeLeft = parseInt(timerElement.textContent, 10); 1014 if (timeLeft > 1) { 1015 timerElement.textContent = timeLeft - 1; 1016 } else { 1017 clearInterval(timerInterval); 1018 } 1019 }, 1000); // æ¯ç§æ´æ°ä¸æ¬¡åæ¸è¨æ 1020 } 1021 }).then((result) => { 1022 if (result.dismiss === Swal.DismissReason.timer) { 1023 if (typeof success === 'function') { 1024 success(result); 1025 } 1026 } 1027 });; 1028 } 1029 1030 UTK.SaveButton = function (success, msg) { 1031 Swal.fire({ 1032 title: msg, 1033 text: GetSystemLanguageText('確å®è¦') + msg + '?', 1034 icon: "warning", 1035 iconColor: "#009EF7", 1036 buttonsStyling: false, 1037 showCancelButton: true, 1038 confirmButtonText: GetSystemLanguageText("確å®"), 1039 cancelButtonText: GetSystemLanguageText("åæ¶"), 1040 customClass: { 1041 confirmButton: "btn btn-primary", 1042 cancelButton: "btn btn-light" 1043 } 1044 }).then((result) => { 1045 if (result.isConfirmed) { 1046 if (typeof success === 'function') { 1047 success(); 1048 } 1049 } 1050 }); 1051 } 1052 1053 UTK.ServerError = function (html, success) { 1054 Swal.fire({ 1055 title: '<b>' + GetSystemLanguageText("é¯èª¤") + '</b>', 1056 html: html, 1057 icon: "error", 1058 buttonsStyling: false, 1059 confirmButtonText: GetSystemLanguageText("éé"), 1060 customClass: { 1061 confirmButton: "btn btn-primary" 1062 } 1063 }).then((result) => { 1064 if (typeof success === 'function') success(result); 1065 }); 1066 } 1067 1068 UTK.Error = function (text, success) { 1069 Swal.fire({ 1070 title: GetSystemLanguageText("é¯èª¤"), 1071 text: text, 1072 icon: "error", 1073 buttonsStyling: false, 1074 confirmButtonText: GetSystemLanguageText("éé"), 1075 customClass: { 1076 confirmButton: "btn btn-primary" 1077 } 1078 }).then((result) => { 1079 if (typeof success === 'function') success(result); 1080 }); 1081 } 1082 1083 UTK.ErrorHtml = function (text, success) { 1084 Swal.fire({ 1085 html: text, 1086 title: GetSystemLanguageTex("é¯èª¤"), 1087 icon: "error", 1088 buttonsStyling: false, 1089 confirmButtonText: GetSystemLanguageText("éé"), 1090 customClass: { 1091 confirmButton: "btn btn-primary" 1092 } 1093 }).then((result) => { 1094 if (typeof success === 'function') success(result); 1095 }); 1096 } 1097 1098 UTK.ReturnPage = function (success) { 1099 Swal.fire({ 1100 title: GetSystemLanguageText("è¿å"), 1101 text: GetSystemLanguageText("確å®é¢éæ¤é å?"), 1102 icon: "warning", 1103 buttonsStyling: false, 1104 showCancelButton: true, 1105 confirmButtonText: GetSystemLanguageText("確å®"), 1106 cancelButtonText: GetSystemLanguageText("åæ¶"), 1107 customClass: { 1108 confirmButton: "btn btn-primary", 1109 cancelButton: "btn btn-secondary" 1110 } 1111 }).then((result) => { 1112 if (result.isConfirmed) { 1113 if (typeof success === 'function') { 1114 success(); 1115 } 1116 } 1117 }); 1118 } 1119 1120 UTK.Comfirm = function (title, text, success) { 1121 Swal.fire({ 1122 title: title, 1123 text: text, 1124 icon: "info", 1125 iconColor: "#E31C3B", 1126 buttonsStyling: false, 1127 showCancelButton: true, 1128 confirmButtonText: GetSystemLanguageText("確å®"), 1129 cancelButtonText: GetSystemLanguageText("åæ¶"), 1130 customClass: { 1131 confirmButton: "btn btn-primary", 1132 cancelButton: "btn btn-light" 1133 } 1134 }).then((result) => { 1135 if (result.isConfirmed) { 1136 if (typeof success === 'function') { 1137 success(); 1138 } 1139 } 1140 }); 1141 } 1142 1143 UTK.Delete = function (success) { 1144 Swal.fire({ 1145 title: GetSystemLanguageText("åªé¤"), 1146 text: GetSystemLanguageText('確å®åªé¤æ¤çè³æå?'), 1147 icon: "error", 1148 buttonsStyling: false, 1149 showCancelButton: true, 1150 confirmButtonText: GetSystemLanguageText("確å®"), 1151 cancelButtonText: GetSystemLanguageText("åæ¶"), 1152 customClass: { 1153 confirmButton: "btn btn-primary", 1154 cancelButton: "btn btn-secondary" 1155 } 1156 }).then((result) => { 1157 if (result.isConfirmed) { 1158 if (typeof success === 'function') { 1159 success(); 1160 } 1161 } 1162 }); 1163 } 1164 1165 UTK.Confirm = function (title, text, confirmFunction) { 1166 Swal.fire({ 1167 title: title, 1168 text: text, 1169 icon: "question", 1170 buttonsStyling: false, 1171 showCancelButton: true, 1172 confirmButtonText: GetSystemLanguageText("確å®"), 1173 cancelButtonText: GetSystemLanguageText("åæ¶"), 1174 customClass: { 1175 confirmButton: "btn btn-primary", 1176 cancelButton: "btn btn-secondary" 1177 } 1178 }).then((result) => { 1179 if (result.isConfirmed) { 1180 if (confirmFunction) { 1181 confirmFunction(); 1182 } 1183 } 1184 }); 1185 } 1186 1187 UTK.ConfirmHtml = function (title, html, success) { 1188 Swal.fire({ 1189 title: title, 1190 html: html, 1191 icon: "question", 1192 buttonsStyling: false, 1193 showCancelButton: true, 1194 confirmButtonText: GetSystemLanguageText("確å®"), 1195 cancelButtonText: GetSystemLanguageText("åæ¶"), 1196 customClass: { 1197 confirmButton: "btn btn-primary", 1198 cancelButton: "btn btn-secondary" 1199 } 1200 }).then((result) => { 1201 if (result.isConfirmed) { 1202 if (typeof success === 'function') { 1203 success(); 1204 } 1205 } 1206 }); 1207 } 1208 1209 UTK.Swal = function (option, success) { 1210 let options = $.extend(true, { 1211 icon: "question", 1212 buttonsStyling: false, 1213 showCancelButton: true, 1214 confirmButtonText: GetSystemLanguageText("確å®"), 1215 cancelButtonText: GetSystemLanguageText("åæ¶"), 1216 customClass: { 1217 confirmButton: "btn btn-primary", 1218 cancelButton: "btn btn-secondary" 1219 } 1220 }, option); 1221 1222 return Swal.fire(options) 1223 } 1224 1225 UTK.toastr_success = function (msg, options) {
1226 var defaultOptions = UTK.defaultOptions.toastOptions(options); 1227 toastr.options = defaultOptions; 1228 toastr.success(msg, '', { 1229 "timeOut": "2000" 1230 }); 1231 }; 1232 1233 UTK.toastr_warning = function (msg, options) { 1234 var defaultOptions = UTK.defaultOptions.toastOptions(options); 1235 toastr.options = defaultOptions; 1236 toastr.warning(msg, '', { 1237 "timeOut": "2000" 1238 }); 1239 }; 1240 1241 UTK.toastr_error = function (msg, options) { 1242 var defaultOptions = UTK.defaultOptions.toastOptions(options); 1243 toastr.options = defaultOptions; 1244 toastr.error(msg, '', { 1245 "timeOut": "3000" 1246 }); 1247 }; 1248 1249 /* ================================================ 1250 * KTDataTable 1251 * ================================================ */ 1252 UTK.KTDatatable = function (element, options) { 1253 let opt = UTK.defaultOptions.KTDataTableOptions(options); 1254 var dataTable = $(element).KTDatatable(opt); 1255 1256 $(element).on('datatable-on-ajax-done', function (ev, data) { 1257 if (typeof opt.scrollto !== "undefined" && opt.scrollto == true) { 1258 $("html, body").animate({ scrollTop: $(element).offset().top }, 0); 1259 } 1260 1261 if (typeof (data._returnCode) !== 'undefined' && typeof (data._returnMessage) !== 'undefined') { 1262 try { 1263 if (data.Code != "0000") { 1264 swal.fire('Error', '[' + data._returnCode + '] ' + data._returnMessage, 'error'); 1265 return; 1266 } 1267 } 1268 catch (e) { } 1269 } 1270 1271 if ($.isFunction(opt.done)) { 1272 opt.done(ev, data); 1273 } 1274 }); 1275 1276 $(element).on('datatable-on-ajax-fail', function (ev, jqXHR) { 1277 console.log(jqXHR); 1278 1279 if (typeof (jqXHR.responseJSON) !== 'undefined' && 1280 typeof (jqXHR.responseJSON._returnCode) !== 'undefined' && 1281 typeof (jqXHR.responseJSON._returnMessage) !== 'undefined') { 1282 try { 1283 if (jqXHR.responseJSON.Code != "0000") { 1284 swal.fire('Error', '[' + jqXHR.responseJSON._returnCode + '] ' + jqXHR.responseJSON._returnMessage, 'error'); 1285 return; 1286 } 1287 } 1288 catch (e) { } 1289 } 1290 1291 if ($.isFunction(opt.error)) { 1292 var msg = jqXHR.responseJSON ? jqXHR.responseJSON._returnMessage : jqXHR.status + " (" + jqXHR.statusText + ")"; 1293 opt.error(ev, jqXHR, msg); 1294 } 1295 else { 1296 1297 } 1298 }); 1299 1300 $(element).on('datatable-on-reloaded', function (ev, jqXHR) { 1301 }); 1302 1303 return dataTable; 1304 }; 1305 1306 /* ================================================ 1307 * DataTables 1308 * ================================================ */ 1309 1310 /** 1311 * å®å ¨ç DataTables Render å½å¼éå 1312 * ç¨æ¼é²æ¢ XSS æ»æ 1313 */ 1314 UTK.safeRender = { 1315 /** 1316 * å®å ¨çæå Render - å°ææ HTML åå è½ç¾© 1317 * @param {string} data - è³æ 1318 * @param {string} type - é¡å (display, filter, sort, type) 1319 * @param {object} row - æ´åè³æ 1320 * @returns {string} - è½ç¾©å¾çå®å ¨å串 1321 * @example columns: [{ data: 'name', render: UTK.safeRender.text }] 1322 */ 1323 text: function (data, type, row) { 1324 if (type === 'display' || type === 'filter') { 1325 return UTK.escapeHtml(data == null ? '' : String(data)); 1326 } 1327 return data; 1328 }, 1329 1330 /** 1331 * å®å ¨çé£çµ Render 1332 * @param {string} urlField - URL æ¬ä½å稱 1333 * @param {string} textField - 顯示æåæ¬ä½å稱 (å¯é¸ï¼é è¨ä½¿ç¨ data) 1334 * @param {string} target - éåæ¹å¼ (å¯é¸ï¼é è¨ _self) 1335 * @returns {function} - Render å½å¼ 1336 * @example columns: [{ data: 'name', render: UTK.safeRender.link('url', 'name', '_blank') }] 1337 */ 1338 link: function (urlField, textField, target) { 1339 target = target || '_self'; 1340 return function (data, type, row) { 1341 if (type === 'display') { 1342 var url = UTK.escapeHtml(row[urlField] || '#'); 1343 var text = UTK.escapeHtml(textField ? (row[textField] || data) : data); 1344 text = text == null ? '' : String(text); 1345 return '<a href="' + url + '" target="' + target + '">
1345' + text + '</a>'; 1346 } 1347 return data; 1348 }; 1349 }, 1350 1351 /** 1352 * å®å ¨ç HTML Render - åªå 許ç¹å®æ¨ç±¤ 1353 * @param {Array} allowedTags - å 許ç HTML æ¨ç±¤é£å 1354 * @returns {function} - Render å½å¼ 1355 * @example columns: [{ data: 'content', render: UTK.safeRender.html(['b', 'i', 'br']) }] 1356 */ 1357 html: function (allowedTags) { 1358 allowedTags = allowedTags || ['b', 'i', 'u', 'strong', 'em', 'br', 'span']; 1359 return function (data, type, row) { 1360 if (type === 'display') { 1361 if (data == null) return ''; 1362 // å è½ç¾©ææå §å®¹ 1363 var escaped = UTK.escapeHtml(String(data)); 1364 // åéåå è¨±çæ¨ç±¤ 1365 allowedTags.forEach(function (tag) { 1366 var openTagRegex = new RegExp('<' + tag + '(\\s[^&]*)?>', 'gi'); 1367 var closeTagRegex = new RegExp('</' + tag + '>', 'gi'); 1368 escaped = escaped.replace(openTagRegex, '<' + tag + '$1>'); 1369 escaped = escaped.replace(closeTagRegex, '</' + tag + '>'); 1370 }); 1371 return escaped; 1372 } 1373 return data; 1374 }; 1375 }, 1376 1377 /** 1378 * å®å ¨çåç Render 1379 * @param {string} srcField - åç URL æ¬ä½å稱 1380 * @param {string} altField - Alt æåæ¬ä½å稱 (å¯é¸) 1381 * @param {string} cssClass - CSS é¡å¥ (å¯é¸) 1382 * @returns {function} - Render å½å¼ 1383 * @example columns: [{ data: 'imageUrl', render: UTK.safeRender.image('imageUrl', 'name', 'img-thumbnail') }] 1384 */ 1385 image: function (srcField, altField, cssClass) { 1386 cssClass = cssClass || ''; 1387 return function (data, type, row) { 1388 if (type === 'display') { 1389 var src = UTK.escapeHtml(row[srcField] || ''); 1390 var alt = UTK.escapeHtml(altField ? (row[altField] || '') : ''); 1391 if (!src) return ''; 1392 return '<img src="' + src + '" alt="' + alt + '" class="' + cssClass + '">'; 1393 } 1394 return data; 1395 }; 1396 }, 1397 1398 /** 1399 * å®å ¨çæ¥æ Render 1400 * @param {string} format - æ¥ææ ¼å¼ (ä½¿ç¨ moment.js) 1401 * @returns {function} - Render å½å¼ 1402 * @example columns: [{ data: 'createAt', render: UTK.safeRender.date('YYYY/MM/DD HH:mm') }] 1403 */ 1404 date: function (format) { 1405 format = format || 'YYYY/MM/DD'; 1406 return function (data, type, row) { 1407 if (type === 'display' || type === 'filter') { 1408 if (!data) return ''; 1409 return moment(data).format(format); 1410 } 1411 return data; 1412 }; 1413 }, 1414 1415 /** 1416 * å®å ¨çæ¸å Render (å ä¸ååä½) 1417 * @param {number} decimals - å°æ¸ä½æ¸ (å¯é¸ï¼é è¨ 0) 1418 * @returns {function} - Render å½å¼ 1419 * @example columns: [{ data: 'amount', render: UTK.safeRender.number(2) }] 1420 */ 1421 number: function (decimals) { 1422 decimals = decimals || 0; 1423 return function (data, type, row) { 1424 if (type === 'display') { 1425 if (data == null || data === '') return ''; 1426 var num = parseFloat(data); 1427 if (isNaN(num)) return UTK.escapeHtml(String(data)); 1428 return num.toLocaleString('zh-TW', { 1429 minimumFractionDigits: decimals, 1430 maximumFractionDigits: decimals 1431 }); 1432 } 1433 return data; 1434 }; 1435 }, 1436 1437 /** 1438 * ä¸é²è¡è½ç¾©ç Render (å éæ¼å¯ä¿¡ä»»ç HTML å §å®¹ï¼å¦å¾ç«¯ç¢ççæé) 1439 * â ï¸ è¦åï¼ä½¿ç¨æ¤å½å¼åè«ç¢ºä¿è³æä¾æºå®å ¨ 1440 * @param {string} data - è³æ 1441 * @param {string} type - é¡å 1442 * @param {object} row - æ´åè³æ 1443 * @returns {string} - åå§ HTML 1444 * @example columns: [{ data: 'actions', render: UTK.safeRender.trusted }] 1445 */ 1446 trusted: function (data, type, row) { 1447 // ç´æ¥è¿åï¼ä¸åè½ç¾© (å ç¨æ¼å¾ç«¯ç¢ççå¯ä¿¡ä»» HTML) 1448 return data; 1449 } 1450 }; 1451 1452 /** 1453 * 使ç¨DataTable.jså¥ä»¶ 1454 * @param {å表æ¬èº«å ç´ } element 1455 * @param {å表以å¤é顯示çå ç´ } element2 1456 * @param {å¥ä»¶çoption} options 1457 * @returns 1458 */ 1459 UTK.DataTable = function (element, element2, options) { 1460 let opt = UTK.defaultOptions.DataTableOptions(options); 1461 1462 //opt.scrollY = '500px'; 1463 opt.ordering = (opt.utkorder) ? true : false; 1464 1465 opt.drawCallback = function (settings) { 1466 options.drawCallback(settings); 1467 $(element).find('td.tooltip').each(function () { 1468 $(this).attr('title', $(this).text()).attr('data-bs-toggle', 'tooltip').attr('data-bs-custom-class', 'tooltip-primary').attr('data-bs-placement', 'top'); 1469 }); 1470 var tooltipTriggerList = $(element).find('[data-bs-toggle="tooltip"]'); 1471 const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl)); 1472 1473 $(element).find('.addcomma').each(function () { 1474 var comma = /\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g; 1475 var num = $(this).text(); 1476 num = num.toString().replace(comma, ','); 1477 $(this).text(num); 1478 }); 1479 } 1480 1481 if (typeof options.ajax != 'undefined') { 1482 opt.ajax.type = "POST"; 1483 opt.serverSide = true; 1484
1485 //夿·å¾ç«¯åæé¯èª¤ 1486 opt.ajax.dataSrc = function (json) { 1487 if (json._returnCode) { 1488 if (json._returnCode != "0000") { 1489 UTK.Notice(json._returnMessage); 1490 return false; 1491 } 1492 } 1493 $(element2).show(); 1494 //éæ¿¾XSSæ»æ 1495 var XSSData = UTK.sanitizeResponse(json.data); 1496 return XSSData; 1497 } 1498 } 1499 1500 1501 1502 $(element).on('preInit.dt', function (e, settings) { 1503 if (!(typeof opt.blockElement == 'undefined' || opt.blockElement == null || opt.blockElement == '')) { 1504 UTK.block(opt.blockElement); 1505 } 1506 }) 1507 1508 $(element).on('init.dt', function (e, settings) { 1509 }); 1510 1511 $(element).on('draw.dt', function (e, settings) { 1512 if (!(typeof opt.blockElement == 'undefined' || opt.blockElement == null || opt.blockElement == '')) { 1513 UTK.unblock(opt.blockElement); 1514 } 1515 }); 1516 1517 $(element).on('error.dt', function (e, settings, techNote, message) { 1518 if (!(typeof opt.blockElement == 'undefined' || opt.blockElement == null || opt.blockElement == '')) { 1519 UTK.unblock(opt.blockElement); 1520 } 1521 try { 1522 let result = JSON.parse(settings.jqXHR.responseText); 1523 if (result._returnCode != undefined) { 1524 Swal.fire(result._returnMessage, "Code=" + result._returnCode, "error"); 1525 } 1526 } 1527 catch { 1528 } 1529 }) 1530 1531 var dataTable = $(element).DataTable(opt); 1532 if (opt.ShowScroll) { 1533 $(element2).find('.dataTables_scroll').append('<div class="utktable-scroll-button utktable-left-button"></div>') 1534 .append('<div class="utktable-scroll-button utktable-right-button"></div>') 1535 .append('<div class="utktable-scroll-button utktable-top-button"></div>') 1536 .append('<div class="utktable-scroll-button utktable-bottom-button"></div>'); 1537 1538 const scrollContainer = $(element2).find('.dataTables_scrollBody'); 1539 const leftButton = $(element2).find('.utktable-left-button'); 1540 const rightButton = $(element2).find('.utktable-right-button'); 1541 const topButton = $(element2).find('.utktable-top-button'); 1542 const bottomButton = $(element2).find('.utktable-bottom-button'); 1543 1544 leftButton.on('mouseover', () => UTK.startScrolling($(element2), -1, 'horizontal')); 1545 leftButton.on('mouseout', UTK.stopScrolling); 1546 1547 rightButton.on('mouseover', () => UTK.startScrolling($(element2), 1, 'horizontal')); 1548 rightButton.on('mouseout', UTK.stopScrolling); 1549 1550 topButton.on('mouseover', () => UTK.startScrolling($(element2), -1, 'vertical')); 1551 topButton.on('mouseout', UTK.stopScrolling); 1552 1553 bottomButton.on('mouseover', () => UTK.startScrolling($(element2), 1, 'vertical')); 1554 bottomButton.on('mouseout', UTK.stopScrolling); 1555 1556 // åå§æéé¡¯ç¤ºçæ 1557 if (scrollContainer.scrollLeft() === 0) { leftButton.hide(); } 1558 if (scrollContainer.scrollLeft() + scrollContainer.width() >= scrollContainer[0].scrollWidth) { rightButton.hide(); } 1559 if (scrollContainer.scrollTop() === 0) { topButton.hide(); } 1560 if (scrollContainer.scrollTop() + scrollContainer.height() >= scrollContainer[0].scrollHeight) { bottomButton.hide(); } 1561 scrollContainer.scroll(function () { 1562 if (scrollContainer.scrollLeft() > 0) { leftButton.show(); } 1563 else { leftButton.hide(); } 1564 1565 if (scrollContainer.scrollLeft() < (scrollContainer[0].scrollWidth - scrollContainer.width() - 0.5)) { rightButton.show(); } 1566 else { rightButton.hide(); } 1567 1568 if (scrollContainer.scrollTop() > 0) { topButton.show(); } 1569 else { topButton.hide(); } 1570 1571 if (scrollContainer.scrollTop() < (scrollContainer[0].scrollHeight - scrollC
1571ontainer.height())) { bottomButton.show(); } 1572 else { bottomButton.hide(); } 1573 }); 1574 } 1575 return dataTable; 1576 }; 1577 /** 1578 * 鿏å°å°åæä¸çæ¯åå串é²è¡è½ç¾©èç 1579 * @param {Object|string} response - ä¾èªä¼ºæå¨çåææ¸æï¼å¯ä»¥æ¯å串æç©ä»¶ 1580 * @returns {Object|string} - å·²ç¶è½ç¾©èçéçå®å ¨æ¸æ 1581 */ 1582 UTK.sanitizeResponse = function (response) { 1583 if (typeof response === 'string') { 1584 // 妿忿¯ä¸åå串ï¼é²è¡ HTML è½ç¾© 1585 return UTK.escapeHtml(response); 1586 } else if (typeof response === 'object') { 1587 // 妿忿¯ä¸åç©ä»¶ï¼éæ¸å°èçæ¯åå±¬æ§ 1588 for (let key in response) { 1589 if (response.hasOwnProperty(key)) { 1590 response[key] = UTK.sanitizeResponse(response[key]); 1591 } 1592 } 1593 } 1594 return response; 1595 } 1596 /** 1597 * å°ä¸å®å ¨ç HTML å符è½ç¾©æå®å ¨çå符 1598 * @param {string} unsafe - å¯è½å å«ä¸å®å ¨å符çå串 1599 * @returns {string} - è½ç¾©å¾çå®å ¨å串 1600 */ 1601 UTK.escapeHtml = function (unsafe) { 1602 return unsafe 1603 .replace(/&/g, "&") // å° & æ¿æçº & 1604 .replace(/</g, "<") // å° < æ¿æçº < 1605 .replace(/>/g, ">") // å° > æ¿æçº > 1606 .replace(/"/g, """) // å° " æ¿æçº " 1607 .replace(/'/g, "'"); // å° ' æ¿æçº ' 1608 } 1609 1610 let scrollInterval; 1611 1612 UTK.startScrolling = function (table, direction, axis) { 1613 scrollInterval = setInterval(() => { 1614 const scrollContainer = table.find('.dataTables_scrollBody'); 1615 const leftButton = table.find('.utktable-left-button'); 1616 const rightButton = table.find('.utktable-right-button'); 1617 const topButton = table.find('.utktable-top-button'); 1618 const bottomButton = table.find('.utktable-bottom-button'); 1619 if (axis === 'horizontal') { 1620 scrollContainer.scrollLeft(scrollContainer.scrollLeft() + direction * 20); // èª¿æ´æ»¾åé度 1621 } else if (axis === 'vertical') { 1622 scrollContainer.scrollTop(scrollContainer.scrollTop() + direction * 20); // èª¿æ´æ»¾åé度 1623 } 1624 1625 // 檢æ¥å·¦å³æéé¡¯ç¤ºçæ 1626 if (scrollContainer.scrollLeft() === 0) { 1627 leftButton.hide(); 1628 } else { 1629 leftButton.show(); 1630 } 1631 1632 if (scrollContainer.scrollLeft() + scrollContainer.width() >= scrollContainer[0].scrollWidth) { 1633 rightButton.hide(); 1634 } else { 1635 rightButton.show(); 1636 } 1637 1638 // 檢æ¥ä¸ä¸æéé¡¯ç¤ºçæ 1639 if (scrollContainer.scrollTop() === 0) { 1640 topButton.hide(); 1641 } else { 1642 topButton.show(); 1643 } 1644 1645 if (scrollContainer.scrollTop() + scrollContainer.height() >= scrollContainer[0].scrollHeight) { 1646 bottomButton.hide(); 1647 } else { 1648 bottomButton.show(); 1649 } 1650 }, 50); 1651 } 1652 1653 UTK.stopScrolling = function () { 1654 clearInterval(scrollInterval); 1655 } 1656 1657 /* ================================================ 1658 * KeyUp 1659 * ================================================ */ 1660 UTK.KeyupEngNum = function (element) { 1661 $(element).keyup(function () { 1662 var x = $(this).val(); 1663 x = x.replace(/[\W]/g, ''); 1664 $(this).val(x); 1665 }) 1666 $(element).on('keyup input', function () { 1667 var x = $(this).val(); 1668 x = x.replace(/[\W]/g, ''); 1669 $(this).val(x); 1670 }) 1671 } 1672 UTK.KeyupNum = function (element) { 1673 $(element).keyup(function () { 1674 var x = $(this).val(); 1675 x = x.replace(/[\D]/g, ''); 1676 $(this).val(x); 1677 }) 1678 $(element).on('keyup input', function () { 1679 var x = $(this).val(); 1680 x = x.replace(/[\D]/g, ''); 1681 $(this).val(x); 1682 }) 1683 } 1684 UTK.ValidateEmail = function (email) { 1685 return email.match( 1686 /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ 1687 ); 1688 }; 1689 1690 /** 1691 * åæ¸è¨æ 1692 * @param {any} duration 1693 * @param {any} element 1694 * @param {any} zerofunction 1695 */ 1696 UTK.StartCountDown = function (duration, element, zerofunction) { 1697 1698 let secondsRemaining = duration; 1699 let min = 0; 1700 let sec = 0; 1701 1702 let countInterval = setInterval(function () { 1703 1704 min = parseInt(secondsRemaining / 60); 1705 sec = parseInt(secondsRemaining % 60);
1706 1707 element.text(`${paddedFormat(min)}:${paddedFormat(sec)}`); 1708 1709 secondsRemaining = secondsRemaining - 1; 1710 if (secondsRemaining < 0) { zerofunction(); clearInterval(countInterval) }; 1711 1712 }, 1000); 1713 1714 return countInterval; 1715 } 1716 var paddedFormat = function (num) { 1717 return num < 10 ? "0" + num : num; 1718 } 1719 1720 1721 UTK.ShowPassword = function () { 1722 $('.ShowPassword').click(function () { 1723 if ($(this).find('i').hasClass('fa-eye')) { 1724 $(this).find('i').remove(); 1725 $(this).append('<i class="fa-solid fa-eye-slash"></i>'); 1726 $(this).parent().find('input').attr('type', 'text'); 1727 } 1728 else { 1729 $(this).find('i').remove(); 1730 $(this).append('<i class="fa-solid fa-eye"></i>'); 1731 $(this).parent().find('input').attr('type', 'password'); 1732 } 1733 }); 1734 } 1735 1736 UTK.OpenScanner = function (ModalPanel, ElementId, FuncitonName) { 1737 var data = new Object(); 1738 data.ElementId = ElementId; 1739 data.FuncitonName = FuncitonName; 1740 1741 var options = { 1742 data: JSON.stringify(data), 1743 showError: true, 1744 success: function (html) { 1745 $(ModalPanel).html(html); 1746 } 1747 }; 1748 UTK.loadHtml("/scanner", options); 1749 } 1750 1751 /** 1752 * JsonPareseæéå°ç¹æ®åå èç 1753 * @param {any} input 1754 * @returns 1755 */ 1756 UTK.CorrectJsonParese = function (input) { 1757 return input.replace(/[\u0000-\u001F\u007F-\u009F]/g, function (char) { 1758 switch (char) { 1759 case '\b': return '\\b'; 1760 case '\t': return '\\t'; 1761 case '\n': return '\\n'; 1762 case '\f': return '\\f'; 1763 case '\r': return '\\r'; 1764 default: return '\\u' + char.charCodeAt(0).toString(16).padStart(4, '0'); 1765 } 1766 }); 1767 } 1768 /** 1769 * è¤è£½æåå°åªè²¼ç°¿ 1770 */ 1771 UTK.CopyText = function (text) { 1772 if (navigator.clipboard && window.isSecureContext) { 1773 // ä½¿ç¨ Clipboard API è¤è£½æå 1774 return navigator.clipboard.writeText(text) 1775 .then(() => { 1776 console.log("æåå·²æåè¤è£½ï¼"); 1777 }) 1778 .catch(err => { 1779 console.error("ä½¿ç¨ Clipboard API è¤è£½å¤±æ:", err); 1780 }); 1781 } else { 1782 // å³çµ± fallback æ©å¶ï¼å»ºç«é±èç textarea å ç´ ä¸¦ä½¿ç¨ execCommand 1783 let textArea = document.createElement("textarea"); 1784 textArea.value = text; 1785 // è¨å® textarea çæ¨£å¼ï¼ç¢ºä¿å ç´ ä¸æå½±é¿é é¢ä½å± 1786 textArea.style.position = "fixed"; 1787 textArea.style.top = "0"; 1788 textArea.style.left = "0"; 1789 textArea.style.width = "1px"; 1790 textArea.style.height = "1px"; 1791 textArea.style.padding = "0"; 1792 textArea.style.border = "none"; 1793 textArea.style.outline = "none"; 1794 textArea.style.boxShadow = "none"; 1795 textArea.style.background = "transparent"; 1796 document.body.appendChild(textArea); 1797 textArea.focus(); 1798 textArea.select(); 1799 1800 try { 1801 const successful = document.execCommand("copy"); 1802 if (successful) { 1803 console.log("ä½¿ç¨ execCommand è¤è£½æåï¼"); 1804 } else { 1805 console.error("execCommand è¤è£½å¤±æï¼"); 1806 } 1807 } catch (err) { 1808 console.error("execCommand ç¼çé¯èª¤:", err); 1809 } 1810 document.body.removeChild(textArea); 1811 return Promise.resolve(); 1812 } 1813 } 1814 1815 /* ================================================ 1816 * return 1817 * ================================================ */ 1818 1819 //$.fn.dataTable.ext.errMode = 'none'; 1820 1821 return UTK; 1822}))
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.