PageSourceSearch

https://www.framar.it/assets/common/js/dev.js?v=20261009005325

js framar.it collected 2026-10-08 22:54:30 UTC 32,912 bytes, 1,147 lines download raw bytes

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.