1/** DEVELOPER METHODS */ 2 3//#region Ajax 4 5function get_call(url, params, successfulCallback, failureCallback) { 6 7 make_ajax_call({ 8 type: 'GET', 9 async: true, 10 url: formatUrl(url), 11 data: params, 12 }, successfulCallback, failureCallback); 13 14} 15 16function post_call(url, params, successfulCallback, failureCallback) { 17 18 make_ajax_call({ 19 type: 'POST', 20 async: true, 21 url: formatUrl(url), 22 data: params ? JSON.stringify(params) : null, 23 }, successfulCallback, failureCallback); 24 25} 26 27function put_call(url, params, successfulCallback, failureCallback) { 28 29 make_ajax_call({ 30 type: 'PUT', 31 async: true, 32 url: formatUrl(url), 33 data: params ? JSON.stringify(params) : null, 34 }, successfulCallback, failureCallback); 35 36} 37 38function delete_call(url, params, successfulCallback, failureCallback) { 39 40 make_ajax_call({ 41 type: 'DELETE', 42 async: true, 43 url: formatUrl(url), 44 data: params ? JSON.stringify(params) : null, 45 }, successfulCallback, failureCallback); 46 47} 48 49function file_call(url, params, input, successfulCallback, failureCallback) { 50 51 getInputFileCustomRenderQueue(input, 52 function (files, finished) { 53 54 var formData = new FormData(); 55 56 // Insert files 57 for (let index = 0; index < files.length; index++) { 58 const file = files[index]; 59 formData.append("Files[]", file); 60 } 61 62 // Merge with params 63 for (var key in params) { 64 65 var value = params[key]; 66 67 // Check if is an array 68 if (Array.isArray(params[key])) 69 value = `FILE_CALL_ARRAY${value.join("FILE_CALL_SEPARATOR_ARRAY")}`; 70 71 formData.append(key, value); 72 } 73 74 var succCall = null; 75 var failCall = null; 76 77 // Check if finished and set the right callbacks 78 if (finished) { 79 succCall = successfulCallback; 80 failCall = failureCallback; 81 } 82 83 make_ajax_call({ 84 type: "POST", 85 dataType: 'json', 86 async: false, 87 contentType: false, 88 processData: false, 89 url: formatUrl(url), 90 data: formData, 91 }, succCall, failCall, true); 92 93 }, 94 function () { 95 hideLoader(); 96 }); 97 98} 99
100function make_ajax_call(options, successfulCallback, failureCallback, file_upload = false) { 101 102 // Add headers 103 options.headers = { 104 "Payload-Validation-Header": create_request_validation_header(options.data), 105 "Validation-Header-Origin": "EXTERNAL" 106 }; 107 108 if (file_upload === false) 109 options.headers['Content-Type'] = 'application/json'; 110 111 $.ajax(options) 112 .done(function (data, status) { 113 ajax_call_callback(data, successfulCallback, failureCallback); 114 }) 115 .fail(function (data, status) { 116 ajax_call_callback(data?.responseJSON, failureCallback, failureCallback); 117 }); 118} 119 120function ajax_call_callback(response, callback, failureCallback, err = null) { 121 122 // Check response length and keys 123 if (isEmpty(response) || Object.keys(response).length == 0 || JSON.stringify(Object.keys(response)) !== JSON.stringify(["Response", "Message", "IsGeneric", "Code"])) { 124 125 // Set error message 126 err = err ?? "Error!"; 127 128 // Check if failure function exists 129 if (typeof failureCallback !== 'function') { 130 hideLoader(); 131 132 notificationError(err); 133 134 return; 135 } 136 137 // Call failure callback 138 failureCallback(null, err); 139 return; 140 } 141 else { 142 143 // Check if is generic 144 if (response.IsGeneric === true) { 145 146 // Check if exists the generic error translation of the code 147 if ($("#generic_error_translation_" + response.Code).length > 0) 148 response.Message = $("#generic_error_translation_" + response.Code).val(); 149 } 150 151 // Everything is fine, call callback 152 if (typeof callback === 'function') 153 callback(response.Response, response.Message); 154 else if (response.Code != 200) 155 notificationError(response.Message); 156 } 157 158} 159 160function create_request_validation_header(payload) { 161 var response = ""; 162 163 // Check if not empty 164 if (!isEmpty(payload)) { 165 166 // Check if is a formData 167 if (payload instanceof FormData) { 168 var tmp = {}; 169 170 // Cycle all keys 171 for (var key of payload.keys()) { 172 if (key != "Files[]") { 173 var value = payload.get(key); 174 175 // Check if is an array from file call 176 if (value.lastIndexOf("FILE_CALL_ARRAY") != -1) 177 value = value.replace("FILE_CALL_ARRAY", "").split("FILE_CALL_SEPARATOR_ARRAY"); 178 179 // Set 180 tmp[key] = value 181 } 182 } 183 184 payload = tmp; 185 } 186 187 if (payload != null && typeof payload !== "undefined") 188 payload = JSON.stringify(format_request_for_validation_header(payload)); 189 190 // Cast to SHA256 191 payload = CryptoJS.SHA256(payload).toString(CryptoJS.enc.Hex); 192 193 // Get current unix timestamp + 3 seconds 194 const unix = Math.floor(new Date().getTime() / 1000) + 3; 195 196 // Create header value 197 response = encrypt(payload, unix); 198 199 } 200 201 return response; 202 203} 204 205function format_request_for_validation_header(payload) { 206 207 // Check if JSON 208 try { 209 payload = typeof payload === "string" ? JSON.parse(payload) : payload; 210 } catch (e) { } 211 212 for (const key in payload) { 213 const value = payload[key]; 214 215 // Check if is an object or an array 216 if (typeof value === "object" || Array.isArray(value)) 217 payload[key] = format_request_for_validation_header(value); 218 219 // Check if is a number and not a boolean 220 else if (!isNaN(value) && typeof value !== "boolean") 221 payload[key] = Number(value) === value && value % 1 === 0 ? parseInt(value) : parseFloat(value); 222 223 // Check if an empty string 224 else if (typeof value === "string" && isNullOrEmpty(value)) 225 payload[key] = null; 226 227 // Check if undefined 228 else if (typeof value === "undefined") 229 payload[key] = null; 230 } 231 232 return payload 233} 234 235function formatUrl(url) { 236 // Check if has the / at the end 237 if (url[url.length - 1] != "/") 238 url += "/"; 239 240 return url; 241} 242 243//#endregion 244 245//#region Errors Check 246function checkMandatory(selector = null) { 247 var ret = true; 248 var mandatory = $((selector == null) ? '[mandatory]' : `${selector} [mandatory]`); 249 250 for (let index = 0; index < mandatory.length; index++) { 251 const element = mandatory[index]; 252 var err = false; 253 254 var selectpicker = false; 255 256 // SELECT 257 if (element.type == "select-one" || element.type == "select-multiple") { 258 err = $(element).length == 0 || $(element).val() == null || $(element).val() == "" || typeof $(element).val() == 'undefined'; 259 selectpicker = $(element).parent(".dropdown.bootstrap-select").length > 0;
260 } 261 // checkbox 262 else if (element.type == "checkbox") { 263 err = $(element).prop("checked") ? false : true; 264 } 265 // DATEPICKER (if date add attribute is_date) 266 else if (typeof $(element).attr('is_date') !== typeof undefined && $(element).attr('is_date') !== false) { 267 err = ($(element).val() == "1970-01-01" || $(element).val() == "01/01/1970"); 268 } 269 // Normal INPUT 270 else { 271 err = ($(element).val().trim().replace(/(<([^>]+)>)/ig, '').length == 0); 272 } 273 274 if (err) { 275 ret = false; 276 277 if (selectpicker) 278 $(element).closest(".dropdown.bootstrap-select").addClass("is-invalid"); 279 else 280 if (element.type == "checkbox") $(element).closest(".control").addClass("is-invalid"); 281 else $(element).addClass("is-invalid"); 282 283 } else { 284 if (element.type == "checkbox") $(element).closest(".control").removeClass("is-invalid"); 285 else $(element).removeClass("is-invalid"); 286 } 287 288 } 289 290 return ret; 291} 292function checkMandatoryTabs() { 293 294 var validity = true; 295 296 // Cycle all mandatory tabs of the page 297 $("[mandatory_tab_content]").each(function (index, element) { 298 299 // Get the id of the element 300 var id = $(element).attr("id"); 301 302 var tab_id = $(element).closest(".tab-pane").attr("aria-labelledby"); 303 304 // Check the mandatory fields of the rows 305 var tab_valid = checkMandatory(`#${id}`); 306 307 // Check if the tab_valid is not valid 308 if (tab_valid == false) { 309 310 // Set the validity to false 311 validity = false; 312 313 $(`#${tab_id}`).addClass("bg-danger"); 314 } 315 else 316 $(`#${tab_id}`).removeClass("bg-danger"); 317 318 }); 319 320 return validity; 321} 322 323function addErrorClass(element) { 324 $(element).addClass("is-invalid"); 325} 326function removeErrorClass(element) { 327 $(element).removeClass("is-invalid"); 328} 329function addErrorLabel(element, message) { 330 $(element).closest(".form-group").append("<label class='text-danger custom-validators-label'>" + message + "</label>"); 331} 332function removeErrorLabel(element) { 333 $(element).closest(".form-group").find(".custom-validators-label").remove(); 334} 335 336$(document).ready(renderMandatoryAsterisks); 337function renderMandatoryAsterisks() { 338 339 setTimeout(() => { 340 341 var mandatory = $('[mandatory]'); 342 343 for (let index = 0; index < mandatory.length; index++) { 344 const element = mandatory[index]; 345 346 $(element).closest(".form-group").find('label').html($(element).closest(".form-group").find('label').html() + " *"); 347 348 // Get the placeholder 349 var placeholder = $(element).attr("placeholder"); 350 351 // Check if exists 352 if (!isEmpty(placeholder)) 353 $(element).attr("placeholder", placeholder + " *"); 354 } 355 356 }, 500); 357 358} 359//#endregion 360 361//#region Date format 362function fDate(format, date) { 363 // If there's no date, get current 364 if (date === undefined) date = new Date(); 365 else date = rightDateFormat(date); 366 367 // Split to get Dates and Hours 368 var formats = format.split(" "); 369 370 // Remove black char 371 formats = formats.filter(function (el) { 372 return (!isEmpty(el) && el !== undefined); 373 }); 374 375 var res = []; 376 for (let index = 0; index < formats.length; index++) { 377 const f = formats[index]; 378 379 var sep = ""; 380 var arr = []; 381 382 // Get each letter 383 for (var i = 0; i < f.length; i++) { 384 var letter = f.charAt(i); 385 386 var type = getDateTypeValue(letter, date); 387 388 // If is boolean, is not a type but is a special char (the separator) 389 if (typeof type === "boolean") sep = letter; 390 else arr.push(type); 391 } 392 393 res.push(arr.join(sep)); 394 } 395 396 ret = res.join(' '); 397 return ret; 398} 399function getDateTypeValue(type, date) { 400 var d = new Date(date); 401 var ret = null; 402 403 switch (type.toUpperCase()) { 404 case "Y": 405 ret = d.getFullYear(); 406 break; 407 case "M": 408 ret = (d.getMonth() + 1).toString(); 409 if (ret.length < 2) ret = '0' + ret; 410 break; 411 case "D": 412 ret = d.getDate().toString(); 413 if (ret.length < 2) ret = '0' + ret; 414 break; 415 case "H": 416 ret = d.getHours().toString(); 417 if (ret.length < 2) ret = '0' + ret;; 418 break; 419 case "I": 420 ret = d.getMinutes().toString(); 421 if (ret.length < 2) ret = '0' + ret;; 422 break; 423 case "S": 424 ret = d.getSeconds().toString(); 425 if (ret.length < 2) ret = '0' + ret;; 426 break; 427 428 default: 429 ret = true; 430 break; 431 } 432 433 return ret; 434} 435// Convert every type of date/date and time in Y-m-d 436function rightDateFormat(date) { 437 if (typeof date === 'string') { 438 var exp = date.split(" "); 439 440 var d = exp[0].replace(/\//g, "-").split("-"); 441 442 // Check if date has all values 443 if (d.length == 1) 444 d.push("01"); 445 446 if (d.length == 2) 447 d.push("01"); 448 449 // Check and get lengths 450 var lengths = []; 451 for (let index = 0; index < d.length; index++) { 452 const element = d[index]; 453 454 if (element.length < 2) 455 d[index] = `0${d[index]}`; 456 457 // Push 458 lengths.push(d[index].length); 459 } 460 461 // Get if there is the year 462 if (lengths.indexOf(4) == -1) 463 d[0] = `20${d[0]}`; 464 465 // Merge together 466 date = `${d.join("-")} ${exp.length > 1 ? exp[1] : ''}`.trim(); 467 } 468 469 return date; 470} 471//#endregion 472 473//#region Notifications 474 475$(document).ready(function () { 476 477 setTimeout(() => { 478 479 // Get querystring params
480 const urlParams = new URLSearchParams(window.location.search); 481 482 // Check if exists at least one 483 if (urlParams.has('st') == false && urlParams.has('m') == false) 484 return; 485 486 // Set default 487 var status = "OK"; 488 var message = null; 489 490 // Check if exists st param 491 if (urlParams.get('st')) { 492 status = urlParams.get('st'); 493 urlParams.delete("st"); 494 } 495 496 // Check if exists m param 497 if (urlParams.get('m')) { 498 message = urlParams.get('m'); 499 urlParams.delete("m"); 500 } 501 502 // Check if success 503 if (status.toUpperCase() == "OK") 504 notificationSuccess(message); 505 506 // Check if error 507 else if (status.toUpperCase() == "KO") 508 notificationError(message); 509 510 var new_url_params = []; 511 512 // Rebuild url params 513 for (const [key, value] of urlParams.entries()) 514 new_url_params.push(`${key}=${value}`) 515 516 // Overwrite with the pathname (the url without query) 517 window.history.replaceState({}, document.title, window.location.pathname + `?${new_url_params.join("&")}`); 518 519 }, 500); 520 521}); 522 523function notificationSuccess(text = null) { 524 text = isEmpty(text) ? "Modifiche salvate" : text; 525 526 toastr.options = { 527 closeButton: false, 528 debug: false, 529 newestOnTop: false, 530 progressBar: false, 531 positionClass: "toast-bottom-right", 532 preventDuplicates: false, 533 onclick: null, 534 showDuration: "300", 535 hideDuration: "1000", 536 timeOut: "5000", 537 extendedTimeOut: "1000", 538 showEasing: "swing", 539 hideEasing: "linear", 540 showMethod: "fadeIn", 541 hideMethod: "fadeOut", 542 }; 543 toastr.success(text); 544} 545 546function notificationWarning(text = null, fixed = false) { 547 text = isEmpty(text) ? "Warning" : text; 548 549 toastr.options = { 550 closeButton: false, 551 debug: false, 552 newestOnTop: false, 553 progressBar: false, 554 positionClass: "toast-bottom-right", 555 preventDuplicates: false, 556 onclick: null, 557 showDuration: "300", 558 hideDuration: "1000", 559 timeOut: (!fixed) ? "5000" : 0, 560 extendedTimeOut: (!fixed) ? "1000" : 0, 561 showEasing: "swing", 562 hideEasing: "linear", 563 showMethod: "fadeIn", 564 hideMethod: "fadeOut", 565 tapToDismiss: fixed, 566 }; 567 568 toastr.warning(text); 569} 570 571function notificationInfo(text = null) { 572 text = isEmpty(text) ? "Info" : text; 573 574 toastr.options = { 575 closeButton: false, 576 debug: false, 577 newestOnTop: false, 578 progressBar: false, 579 positionClass: "toast-bottom-right", 580 preventDuplicates: false, 581 onclick: null, 582 showDuration: "300", 583 hideDuration: "1000", 584 timeOut: "5000", 585 extendedTimeOut: "1000", 586 showEasing: "swing", 587 hideEasing: "linear", 588 showMethod: "fadeIn", 589 hideMethod: "fadeOut", 590 }; 591 toastr.info(text); 592} 593 594function notificationError(text = null) { 595 text = isEmpty(text) ? "Error" : text; 596 597 toastr.options = { 598 closeButton: false, 599 debug: false, 600 newestOnTop: false, 601 progressBar: false, 602 positionClass: "toast-bottom-right", 603 preventDuplicates: true, 604 onclick: null, 605 showDuration: "300", 606 hideDuration: "1000", 607 timeOut: "5000", 608 extendedTimeOut: "1000", 609 showEasing: "swing", 610 hideEasing: "linear", 611 showMethod: "fadeIn", 612 hideMethod: "fadeOut", 613 }; 614 toastr.error(text); 615} 616//#endregion 617 618//#region Forms 619 620function getContentData(selector, useBinary = false) { 621 622 var ret = {}; 623 624 // :not(.note-input) = excluding summernote element 625 $(`${selector} [name]:not(.note-input)`).each(function () { 626 var exclude = false; 627 628 element = this; 629 630 // Check if property with this "name" exists 631 if (element != null) { 632 633 nameAttr = $(element).attr("name"); 634 value = null; 635 636 // CHECKBOX 637 if ($(element).is(":checkbox")) { 638 var val = $(element).prop("checked"); 639 640 value = (useBinary === true) ? (val ? 1 : 0) : val; 641 } 642 // RADIO 643 else if ($(element).is(":radio")) { 644 value = $(`${selector} [name="${nameAttr}"]:checked`).val(); 645 } 646 // TEXTAREA WITH SUMMERNOTE 647 else if ( 648 $(element).is("textarea") && 649 $(element).next().hasClass("note-editor") 650 ) { 651 value = $(element).summernote("code"); 652 } 653 // Normal INPUT/SELECT 654 else { 655 656 // Check if not an element inside a summernote 657 if ($(element).parents(".note-editor").length == 0) 658 value = $(element).val(); 659 else 660 exclude = true; 661 662 } 663 664 if (exclude === false) 665 ret[nameAttr] = value; 666 } 667 });
668 669 return ret; 670} 671function getContentDataByTabs() { 672 673 var response = []; 674 675 // Cycle all mandatory tabs of the page 676 $("[mandatory_tab_content]").each(function (index, element) { 677 678 // Get the id of the element 679 var id = $(element).attr("id"); 680 681 // Get all data from id 682 var data = getContentData(`#${id}`); 683 684 // Add the data in the response array 685 response[id] = data; 686 }); 687 688 return response; 689} 690 691function fillContentByNames(selector, data, inputs = true) { 692 for (var key in data) { 693 var value = data[key]; 694 var element = null; 695 696 if (value == null || value == "null") 697 value = ""; 698 699 // Get element by name 700 if ($(`${selector} [name="${key}"]`).length > 0) 701 element = $(`${selector} [name="${key}"]`); 702 703 // By id 704 else if ($(`${selector} #${key}`).length > 0) 705 element = $(`${selector} #${key}`); 706 707 // Check if property with this "name" exists 708 if (element != null) { 709 710 if (inputs == true) { 711 712 // CHECKBOX 713 if ($(element).is(":checkbox")) { 714 $(element).prop("checked", value != 0); 715 } 716 // RADIO 717 else if ($(element).is(":radio")) { 718 for (let index = 0; index < element.length; index++) { 719 const radio = element[index]; 720 721 if ($(radio).val() == value) 722 $(radio).prop("checked", true); 723 } 724 } 725 // TEXTAREA WITH SUMMERNOTE 726 else if ( 727 $(element).is("textarea") && 728 $(element).next().hasClass("note-editor") 729 ) { 730 $(element).summernote("code", value); 731 } 732 // Normal INPUT/SELECT 733 else { 734 $(element).val(value); 735 } 736 } else { 737 // Set the html in the element 738 $(element).html(value); 739 } 740 } 741 } 742} 743function clearInputsByContainer(container_id) { 744 745 // Clear the inputs by the error class 746 $(`${container_id} .is-invalid`).removeClass("is-invalid") 747 748 // Get the data in the container 749 var data = getContentData(container_id); 750 751 // Cycle the data 752 for (var key in data) { 753 data[key] = ""; 754 } 755 756 // Clear the container 757 fillContentByNames(container_id, data); 758} 759 760//#endregion 761 762//#region Loader 763function showLoader() { 764 $('body').addClass("is-loading"); 765} 766function hideLoader() { 767 $('body').removeClass("is-loading-full"); 768 $('body').removeClass("is-loading"); 769} 770function hideFullLoader() { 771 $('body').removeClass("is-loading-full"); 772} 773//#endregion 774 775//#region Tooltip 776 777$(document).ready(initTooltip); 778 779function initTooltip() { 780 781 // Wait because some elements are not initialized yet 782 setTimeout(() => { 783 784 // Check if there are custom tooltip 785 if ($("[tooltip]").length > 0) { 786 787 var elements = $("[tooltip]"); 788 789 for (let index = 0; index < elements.length; index++) { 790 const element = elements[index]; 791 792 // Get tooltip text 793 var text = $(element).attr("tooltip"); 794 795 // Remove custom 796 $(element).removeAttr("tooltip"); 797 798 // Add default 799 $(element).attr("data-toggle", "tooltip"); 800 $(element).attr("data-placement", "top"); 801 $(element).attr("data-html", "true"); 802 $(element).attr("title", text); 803 } 804 805 } 806 807 if ($("[data-toggle='tooltip']").length > 0) 808 $('[data-toggle="tooltip"]').tooltip(); 809 }, 1000); 810} 811 812//#endregion 813 814//#region Summernote 815 816function initSummernote(selector) { 817 818 if ($(selector).length == 0) 819 return; 820 821 // Init summernote 822 $(selector).summernote({ 823 lang: "it-IT", 824 placeholder: "Testo", 825 disableDragAndDrop: true, 826 height: 300, 827 toolbar: [ 828 ["style", ["", "bold", "italic", "underline", "clear"]], 829 ["para", ["ul", "ol", "paragraph"]], 830 ["height", ["height"]], 831 ['style', ['style']], 832 ["insert", ["picture"]], 833 ["link"], 834 ["codeview", ["codeview"]], 835 ], 836 styleTags: ['h2', 'h3', 'h4'], 837 callbacks: { 838 onPaste: function (e) { 839 e.preventDefault(); 840 841 var bufferText = ((e.originalEvent || e).clipboardData || window.clipboardData).getData("text/html"); 842 843 if (bufferText != "") 844 document.execCommand("insertHtml", false, summernoteCleanPastedHTML(bufferText)); 845 846 else { 847 bufferText = ( 848 (e.originalEvent || e).clipboardData || window.clipboardData 849 ).getData("text/plain"); 850 851 document.execCommand("insertHtml", false, summernoteCleanPastedHTML(bufferText)); 852 } 853 854 } 855 }, 856 857 });
858 859 window.onclick = function (e) { 860 // Check if the element clicked IS NOT a child of a Summernote 861 if ($(e.target).parents('.note-editor').length == 0) { 862 863 // Clear the code 864 $('.js-editor').each(function (index) { 865 $(this).summernote('code', summernoteCleanPastedHTML($(this).summernote('code'))); 866 }); 867 868 } 869 } 870 871 872} 873 874function summernoteCleanPastedHTML(input) { 875 876 // 1. remove line breaks / Mso classes 877 var stringStripper = /(\n|\r| class=(")?Mso[a-zA-Z]+(")?)/g; 878 var output_no_breaks = input.replace(stringStripper, ' '); 879 880 // 2. strip Word generated HTML comments 881 var commentSripper = new RegExp('<!--(.*?)-->', 'g'); 882 output = output_no_breaks.replace(commentSripper, ''); 883 884 // Check if Word text 885 if (output_no_breaks != output) { 886 887 // 3. remove tags leave content if any 888 var tagStripper = new RegExp('<(/)*(meta|link|span|xmlns:|\\?xml:|st1:|o:|html|head|body|lang|font)(.*?)>', 'gi'); 889 output = output.replace(tagStripper, ''); 890 891 // 4. Remove everything in between and including tags '<style(.)style(.)>' 892 var badTags = ['style', 'script', 'applet', 'embed', 'noframes', 'n
892oscript', 'xmlns']; 893 894 for (var i = 0; i < badTags.length; i++) { 895 tagStripper = new RegExp('<' + badTags[i] + '.*?' + badTags[i] + '(.*?)>', 'gi'); 896 output = output.replace(tagStripper, ''); 897 } 898 899 // 5. remove attributes ' style="..."' 900 var badAttributes = ['style', 'start', 'class', 'xmlns', 'data-(.*?)', 'dir']; 901 for (var i = 0; i < badAttributes.length; i++) { 902 var attributeStripper = new RegExp(' ' + badAttributes[i] + '="(.*?)"', 'gi'); 903 output = output.replace(attributeStripper, ''); 904 } 905 906 } 907 908 return output.trim(); 909} 910 911//#endregion 912 913//#region Selectpicker 914 915function initSelectpicker(selector) { 916 917 if ($(selector).length > 0) 918 $(selector).selectpicker("refresh"); 919 920} 921 922//#endregion 923 924//#region Encrypt 925 926function encrypt(obj, key) { 927 928 var CryptoJSAesJson = { 929 stringify: function (cipherParams) { 930 var j = { ct: cipherParams.ciphertext.toString(CryptoJS.enc.Base64) }; 931 if (cipherParams.iv) j.iv = cipherParams.iv.toString(); 932 if (cipherParams.salt) j.s = cipherParams.salt.toString(); 933 return JSON.stringify(j); 934 }, 935 parse: function (jsonStr) { 936 var j = JSON.parse(jsonStr); 937 var cipherParams = CryptoJS.lib.CipherParams.create({ ciphertext: CryptoJS.enc.Base64.parse(j.ct) }); 938 if (j.iv) cipherParams.iv = CryptoJS.enc.Hex.parse(j.iv) 939 if (j.s) cipherParams.salt = CryptoJS.enc.Hex.parse(j.s) 940 return cipherParams; 941 } 942 } 943 944 // Check if is not a string 945 if (typeof obj !== "string") 946 obj = JSON.stringify(obj); 947 948 // Check if is not a string 949 if (typeof key !== "string") 950 key = JSON.stringify(key); 951 952 return btoa(CryptoJS.AES.encrypt(obj, key, { format: CryptoJSAesJson }).toString()); 953} 954 955//#endregion 956 957//#region Others 958 959function confirmDeleteModal(confCallback, cancelCallback = null, text = null) { 960 if (!isEmpty(text)) 961 $('#modalConfirmDeleteText').text(text); 962 963 $("#modalConfirmDelete").modal("show"); 964 965 $("#confirmDeleteBtn") 966 .off("click") 967 .on("click", function () { 968 $("#modalConfirmDelete").modal("hide"); 969 confCallback(); 970 }); 971 $("#cancelDeleteBtn") 972 .off("click") 973 .on("click", function () { 974 $("#modalConfirmDelete").modal("hide"); 975 if (cancelCallback != null) cancelCallback(); 976 }); 977} 978function confirmGenericModal(confCallback, cancelCallback = null, text = null, text_is_html = false) { 979 if (!isEmpty(text)) { 980 981 if (text_is_html) 982 $('#modalConfirmGenericText').html(text); 983 else 984 $('#modalConfirmGenericText').text(text); 985 } 986 987 $('#modalConfirmGeneric').modal("show"); 988 989 $('#confirmGenericBtn').off("click").on("click", function () { 990 $('#modalConfirmGeneric').modal("hide"); 991 confCallback(); 992 }); 993 $('#cancelGenericBtn').off("click").on("click", function () { 994 $('#modalConfirmGeneric').modal("hide"); 995 if (cancelCallback != null) cancelCallback(); 996 }); 997} 998 999function hasSubstring(string, substring) { 1000 return (string.includes(substring)); 1001} 1002function addElementToSerialized(serialized, key, value) { 1003 var toPush = { name: key, value: value }; 1004 serialized.push(toPush); 1005 1006 return serialized; 1007} 1008function isEmptyId(id) { 1009 return $("#" + id).val() == "" || $("#" + id).val() == null; 1010} 1011function isEmpty(string) { 1012 return string == "" || string == null || string == undefined; 1013} 1014 1015function copyToClipboard(text) { 1016 1017 navigator.clipboard.writeText(text).then(function () { 1018 notificationSuccess("Copiato"); 1019 }); 1020 1021} 1022 1023function isNullOrEmpty() { 1024 1025 const isNullOrEmpty = []; 1026 1027 // Get args 1028 const toCheck = Array.from(arguments); 1029 1030 // Check if array 1031 if (!Array.isArray(toCheck)) toCheck = [toCheck]; 1032 1033 // Check fields 1034 toCheck.forEach((field) => { 1035 if (field === null) 1036 isNullOrEmpty.push(true); 1037 1038 else if (typeof field === 'number' && !isNaN(field)) 1039 isNullOrEmpty.push(false); 1040 1041 else if (typeof field === 'string') { 1042 const check = field.replace(/(<([^>]+)>)/gi, '').replace(/\s/g, ''); 1043 isNullOrEmpty.push(check === null || check === ''); 1044 } 1045 1046 else if (Array.isArray(field)) 1047 isNullOrEmpty.push(field.length === 0); 1048 1049 else if (typeof field === 'object') 1050 isNullOrEmpty.push(Object.keys(field).length === 0); 1051 1052 else if (typeof field === 'boolean') 1053 isNullOrEmpty.push(false); 1054 1055 else 1056 isNullOrEmpty.push(false); 1057 1058 });
1059 1060 // If even just one element is empty 1061 return isNullOrEmpty.includes(true); 1062 1063} 1064 1065function scrollToAnchor(element, minus_value = 0) { 1066 1067 $('html,body').animate({ scrollTop: $(element).offset().top - minus_value }, 'slow'); 1068} 1069 1070$(document).ready(function () { 1071 1072 // Get querystring params 1073 const urlParams = new URLSearchParams(window.location.search); 1074 1075 // No params but url has the ? at the end 1076 if (urlParams.size == 0 && window.location.href[window.location.href.length - 1] == "?") 1077 window.history.replaceState({}, document.title, window.location.pathname); 1078 1079}); 1080 1081$(document).on("keyup", "[maxlength].counting_missing_characters", function () { 1082 1083 // Get the max length of the input 1084 var max_length = $(this).attr("maxlength"); 1085 1086 // Get the text length of the input 1087 var text_length = $(this).val().length; 1088 1089 // Calculate the missing characters 1090 var missing_characters = max_length - text_length; 1091 1092 // Check if the input has a label 1093 if ($(this).parents(".form-group").find("label").length > 0) { 1094 1095 $(this).parents(".form-group").find("label span[missing_characters]").remove(); 1096 1097 // Get the text 1098 var text = $(this).parents(".form-group").find("label").html(); 1099 1100 // Add the remaining 1101 text = `${text} <span missing_characters><small> - Caratteri Mancanti: ${missing_characters}</small></span>`; 1102 1103 $(this).parents(".form-group").find("label").html(text); 1104 } 1105 1106}); 1107 1108//#endregion 1109 1110//#region Fix max/min values 1111 1112$(document).on("focusout", "[type='number']", function () { 1113 1114 var max = $(this).attr('max'); 1115 // check if the element has a max 1116 if (typeof max !== 'undefined' && max !== false) { 1117 1118 max = parseInt(max); 1119 1120 // get value 1121 value = parseInt($(this).val()); 1122 // check if value is greater than max 1123 if (value > max) 1124 $(this).val(max); // set max as value 1125 } 1126 1127}); 1128 1129// check min of an element type number 1130$(document).on("focusout", "[type='number']", function () { 1131 1132 var min = $(this).attr('min'); 1133 // check if the element has a min 1134 if (typeof min !== 'undefined' && min !== false) { 1135 1136 min = parseInt(min); 1137 1138 // get value 1139 value = parseInt($(this).val()); 1140 // check if value is greater than min 1141 if (value < min) 1142 $(this).val(min); // set min as value 1143 } 1144 1145}); 1146 1147//#endregion
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.