From cfc8c5512bec401638ab0015b906b81b89439308 Mon Sep 17 00:00:00 2001 From: Dasc3er Date: Tue, 6 Oct 2020 09:21:06 +0200 Subject: [PATCH] Miglioramento della gestione JS dei campi di input Correzioni per inizializzazione dei campi dalla funzione input --- assets/src/js/functions/dates.js | 113 ++++++++------- assets/src/js/functions/functions.js | 8 +- assets/src/js/functions/input.js | 124 ++++++++++++++-- assets/src/js/functions/inputmask.js | 114 ++++++--------- assets/src/js/functions/numbers.js | 66 +++++---- assets/src/js/functions/select.js | 181 +++++++++++++----------- modules/primanota/movimenti.php | 53 ++++--- modules/scadenzario/add.php | 2 - modules/scadenzario/edit.php | 14 +- src/HTMLBuilder/Handler/DateHandler.php | 2 - 10 files changed, 392 insertions(+), 285 deletions(-) diff --git a/assets/src/js/functions/dates.js b/assets/src/js/functions/dates.js index d980515c7..3e5ec500d 100755 --- a/assets/src/js/functions/dates.js +++ b/assets/src/js/functions/dates.js @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -function start_datepickers() { - var icons = { +function getCalendarIcons(){ + return { time: 'fa fa-clock-o', date: 'fa fa-calendar', up: 'fa fa-chevron-up', @@ -28,64 +28,79 @@ function start_datepickers() { clear: 'fa fa-trash', close: 'fa fa-times' }; +} - var date_format = dateFormatMoment(globals.date_format); - var timestamp_format = dateFormatMoment(globals.timestamp_format); - var time_format = dateFormatMoment(globals.time_format); +function initDateInput(input) { + let date_format = dateFormatMoment(globals.date_format); + let calendar_icons = getCalendarIcons(); - $('.timestamp-picker').each(function () { - $this = $(this); - $this.datetimepicker({ - format: timestamp_format, - locale: globals.locale, - icons: icons, - collapse: false, - sideBySide: true, - useCurrent: false, - stepping: 5, - widgetPositioning: { - horizontal: 'left', - vertical: 'auto' - }, - minDate: moment($this.attr('min-date')).isValid() ? $this.attr('min-date') : false, - maxDate: moment($this.attr('max-date')).isValid() ? $this.attr('max-date') : false, - }); + $(input).datetimepicker({ + format: date_format, + locale: globals.locale, + icons: calendar_icons, + useCurrent: false, + minDate: moment($this.attr('min-date')).isValid() ? $this.attr('min-date') : false, + maxDate: moment($this.attr('max-date')).isValid() ? $this.attr('max-date') : false, + }); +} + +function initTimestampInput(input) { + let $this = $(input); + let timestamp_format = dateFormatMoment(globals.timestamp_format); + let calendar_icons = getCalendarIcons(); + + $this.datetimepicker({ + format: timestamp_format, + locale: globals.locale, + icons: calendar_icons, + collapse: false, + sideBySide: true, + useCurrent: false, + stepping: 5, + widgetPositioning: { + horizontal: 'left', + vertical: 'auto' + }, + minDate: moment($this.attr('min-date')).isValid() ? $this.attr('min-date') : false, + maxDate: moment($this.attr('max-date')).isValid() ? $this.attr('max-date') : false, }); - //fix per timestamp-picker non visibile con la classe table-responsive + // fix per timestamp-picker non visibile con la classe table-responsive + $this.on("dp.show", function (e) { + $('#tecnici > div').removeClass('table-responsive'); + }); + + $this.on("dp.hide", function (e) { + $('#tecnici > div').addClass('table-responsive'); + }) +} + +function initTimeInput(input) { + let time_format = dateFormatMoment(globals.time_format); + let calendar_icons = getCalendarIcons(); + + $(input).datetimepicker({ + format: time_format, + locale: globals.locale, + icons: calendar_icons, + useCurrent: false, + stepping: 5, + minDate: moment($this.attr('min-date')).isValid() ? $this.attr('min-date') : false, + maxDate: moment($this.attr('max-date')).isValid() ? $this.attr('max-date') : false, + }); +} + +function start_datepickers() { $('.timestamp-picker').each(function () { - $this = $(this); - $this.on("dp.show", function (e) { - $('#tecnici > div').removeClass('table-responsive'); - }); - $this.on("dp.hide", function (e) { - $('#tecnici > div').addClass('table-responsive'); - }) + initTimestampInput(this); }); $('.datepicker').each(function () { - $this = $(this); - $this.datetimepicker({ - format: date_format, - locale: globals.locale, - icons: icons, - useCurrent: false, - minDate: moment($this.attr('min-date')).isValid() ? $this.attr('min-date') : false, - maxDate: moment($this.attr('max-date')).isValid() ? $this.attr('max-date') : false, - }); + initDateInput(this); }); $('.timepicker').each(function () { - $this = $(this); - $this.datetimepicker({ - format: time_format, - locale: globals.locale, - icons: icons, - useCurrent: false, - stepping: 5, - minDate: moment($this.attr('min-date')).isValid() ? $this.attr('min-date') : false, - maxDate: moment($this.attr('max-date')).isValid() ? $this.attr('max-date') : false, - }); + initTimeInput(this); }); } diff --git a/assets/src/js/functions/functions.js b/assets/src/js/functions/functions.js index 69178d27d..6886869be 100755 --- a/assets/src/js/functions/functions.js +++ b/assets/src/js/functions/functions.js @@ -515,7 +515,7 @@ function restart_inputs() { start_superselect(); // Autosize per le textarea - autosize($('.autosize')); + initTextareaInput($('.autosize')); } /** @@ -552,7 +552,7 @@ function alertPush() { } /** - * + * * @param button * @param form * @param data @@ -648,3 +648,7 @@ function hideTableColumn(table, column) { } } } + +function initTextareaInput(input){ + autosize($(input)); +} diff --git a/assets/src/js/functions/input.js b/assets/src/js/functions/input.js index 2149deff9..1d3719add 100644 --- a/assets/src/js/functions/input.js +++ b/assets/src/js/functions/input.js @@ -17,29 +17,79 @@ */ function input(name) { - return new Input(name); -} + let element; -function Input(name) { // Selezione tramite jQuery if (name instanceof jQuery) { - this.element = name.last(); + element = name.last(); + } + + // Selezione tramite JS diretto + else if (isElement(name)) { + element = $(name); } // Selezione per nome else { - this.element = $("[name='" + name + "']").last(); + element = $("[name='" + name + "']").last(); // Fix per select multipli - if (this.element.length === 0) { - this.element = $("[name='" + name + "[]']").last(); + if (element.length === 0) { + element = $("[name='" + name + "[]']").last(); } } + if (!element.data("input-controller")) { + return new Input(element); + } else { + return element.data("input-controller"); + } +} + +/** + * + * @constructor + * @param {jQuery} element + */ +function Input(element) { + this.element = element; + // Controllo sulla gestione precedente if (!this.element.data("input-set")) { - this.element.data("input-set", 1); - this.element.data("required", this.element.attr("required")); + return; + } + + this.element.data("input-set", 1); + this.element.data("required", this.element.attr("required")); + + // Operazioni di inizializzazione per input specifici + // Inizializzazione per date + if (this.element.hasClass('timestamp-picker')) { + initTimestampInput(this.element); + } else if (this.element.hasClass('datepicker')) { + initDateInput(this.element); + } else if (this.element.hasClass('timepicker')) { + initTimeInput(this.element); + } + + // Inizializzazione per campi numerici + else if (this.element.hasClass('decimal-number')) { + initNumberInput(this.element); + } + + // Inizializzazione per textarea + else if (this.element.hasClass('autosize')) { + initTextareaInput(this.element); + } + + // Inizializzazione per select + else if (this.element.hasClass('superselect') || this.element.hasClass('superselectajax')) { + initSelectInput(this.element); + } + + // Inizializzazione alternativa per maschere + else { + initMaskInput(this.element); } } @@ -111,24 +161,42 @@ Input.prototype.getData = function () { }; } +/** + * Restituisce il valore corrente dell'input. + * + * @returns {string|number} + */ Input.prototype.get = function () { let value = this.element.val(); // Conversione del valore per le checkbox let group = this.element.closest(".form-group"); if (group.find("input[type=checkbox]").length) { - value = parseInt(value) ? 1 : 0; + return parseInt(value) ? 1 : 0; } // Gestione dei valori numerici - const autonumeric = this.element.data("autonumeric"); - if (autonumeric) { - value = parseFloat(autonumeric.rawValue); + if (this.element.hasClass("decimal-number")) { + const autonumeric = this.element.data("autonumeric"); + + if (autonumeric) { + return parseFloat(autonumeric.rawValue); + } + // In attesa dell'inizializzazione per autonumeric, il valore registrato รจ interpretabile + else { + return parseFloat(value); + } } return value; } +/** + * Imposta il valore per l'input. + * + * @param value + * @returns {Input} + */ Input.prototype.set = function (value) { this.element.val(value).trigger("change"); @@ -154,3 +222,33 @@ Input.prototype.on = function (event, action) { Input.prototype.off = function (event) { return this.element.off(event); } + +/** + * Returns true if it is a DOM node. + * + * @param o + * @returns boolean + * + * @source https://stackoverflow.com/a/384380 + */ +function isNode(o) { + return ( + typeof Node === "object" ? o instanceof Node : + o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName === "string" + ); +} + +/** + * Returns true if it is a DOM element. + * + * @param o + * @returns boolean + * + * @source https://stackoverflow.com/a/384380 + */ +function isElement(o) { + return ( + typeof HTMLElement === "object" ? o instanceof HTMLElement : // DOM2 + o && typeof o === "object" && o.nodeType === 1 && typeof o.nodeName === "string" + ); +} diff --git a/assets/src/js/functions/inputmask.js b/assets/src/js/functions/inputmask.js index cb4272c4f..5cac17867 100644 --- a/assets/src/js/functions/inputmask.js +++ b/assets/src/js/functions/inputmask.js @@ -16,82 +16,54 @@ * along with this program. If not, see . */ -// Inputmask +function initMaskInput(input) { + let $input = $(input); + if ($input.hasClass('bound')){ + return; + } + + $input.addClass('bound'); + + if ($input.hasClass('email-mask')){ + $input.inputmask('Regex', { + regex: "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+(?:\\.[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+)*@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$", + }); + } else if ($input.hasClass('rea-mask')){ + $input.inputmask({ + mask: "AA-999999{1,15}", + casing: "upper", + }); + } else if ($input.hasClass('provincia-mask')){ + $input.inputmask({ + mask: "AA", + casing: "upper", + }); + } else if ($input.hasClass('alphanumeric-mask')){ + $input.inputmask('Regex', { + regex: "[A-Za-z0-9#_|\/\\-.]*", + }); + } else if ($input.hasClass('math-mask')){ + $input.inputmask('Regex', { + regex: "[0-9,.+\-]*", + }); + } +} + +/** + * Inputmask + * @param element + */ function start_inputmask(element) { - if (element == undefined) { + if (element === undefined) { element = ''; } else { element = element + ' '; } - var date = dateFormatMoment(globals.date_format).toLowerCase(); + let masks = ['math-mask','alphanumeric-mask', 'provincia-mask','rea-mask', 'email-mask']; - $(element + ".date-mask").not('.bound').inputmask(date, { - placeholder: date - }).addClass('bound'); - - $(element + '.email-mask').not('.bound').inputmask('Regex', { - regex: "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+(?:\\.[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+)*@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$", - }).addClass('bound'); - - $(element + '.rea-mask').not('.bound').inputmask( { - mask: "AA-999999{1,15}", - casing: "upper", - }).addClass('bound'); - - $(element + '.provincia-mask').not('.bound').inputmask( { - mask: "AA", - casing: "upper", - }).addClass('bound'); - - $(element + '.alphanumeric-mask').not('.bound').inputmask('Regex', { - regex: "[A-Za-z0-9#_|\/\\-.]*", - }).addClass('bound'); - - $(element + '.math-mask').not('.bound').inputmask('Regex', { - regex: "[0-9,.+\-]*", - }).addClass('bound'); - - if (globals.is_mobile) { - $(element + '.inputmask-decimal, ' + element + '.date-mask, ' + element + '.timestamp-mask').each(function () { - $(this).attr('type', 'tel'); - }).addClass('bound'); - } else { - $(element + '.inputmask-decimal').not('.bound').each(function () { - var $this = $(this); - - var min = $this.attr('min-value'); - if (min == 'undefined') { - min = false; - } - - var max = $this.attr('max-value'); - if (max == 'undefined') { - max = false; - } - - $this.inputmask("decimal", { - min: min ? min : undefined, - allowMinus: !min || min < 0 ? true : false, - max: max ? max : undefined, - allowPlus: !max || max < 0 ? true : false, - digits: $this.attr('decimals') ? $this.attr('decimals') : globals.cifre_decimali, - digitsOptional: true, // Necessario per un problema di inputmask con i numeri negativi durante l'init - enforceDigitsOnBlur: true, - rightAlign: true, - autoGroup: true, - radixPoint: globals.decimals, - groupSeparator: globals.thousands, - onUnMask: function (maskedValue, unmaskedValue) { - return maskedValue.toEnglish(); - }, - }); - - $this.on('keyup', function () { - if (min && $(this).val().toEnglish() < min) { - $(this).val(min); - } - }); - }).addClass('bound'); - } + let selector = element + '.' + masks.join(', ' + element + '.') + $(selector).each(function () { + initMaskInput(this); + }); } diff --git a/assets/src/js/functions/numbers.js b/assets/src/js/functions/numbers.js index 2b0d3371b..392c48a21 100644 --- a/assets/src/js/functions/numbers.js +++ b/assets/src/js/functions/numbers.js @@ -23,37 +23,41 @@ function initNumbers() { let inputs = $('.decimal-number').not('.bound'); for (const input of inputs) { - let $input = $(input); + initNumberInput(input); - if (AutoNumeric.isManagedByAutoNumeric(input)) { - continue; - } - - let min = $input.attr('min-value') && $input.attr('min-value') !== "undefined" ? $input.attr('min-value') : null; - let max = $input.attr('max-value') && $input.attr('max-value') !== "undefined" ? $input.attr('max-value') : null; - - let decimals = $input.attr('decimals') ? $input.attr('decimals') : globals.cifre_decimali; - - let autonumeric = new AutoNumeric(input, { - caretPositionOnFocus: "decimalLeft", - allowDecimalPadding: true, - currencySymbolPlacement: "s", - negativePositiveSignPlacement: "p", - decimalCharacter: globals.decimals, - decimalCharacterAlternative: ".", - digitGroupSeparator: globals.thousands, - emptyInputBehavior: min ? min : "zero", - overrideMinMaxLimits: "ignore", - modifyValueOnWheel: false, - outputFormat: "string", - unformatOnSubmit: true, - watchExternalChanges: true, - minimumValue: min ? min : "-10000000000000", - maximumValue: max ? max : "10000000000000", - decimalPlaces: decimals, - }); - - $input.data("autonumeric", autonumeric) - .addClass('bound'); + $(input).addClass('bound'); } } + +function initNumberInput(input){ + let $input = $(input); + if (AutoNumeric.isManagedByAutoNumeric(input)) { + return; + } + + let min = $input.attr('min-value') && $input.attr('min-value') !== "undefined" ? $input.attr('min-value') : null; + let max = $input.attr('max-value') && $input.attr('max-value') !== "undefined" ? $input.attr('max-value') : null; + + let decimals = $input.attr('decimals') ? $input.attr('decimals') : globals.cifre_decimali; + + let autonumeric = new AutoNumeric(input, { + caretPositionOnFocus: "decimalLeft", + allowDecimalPadding: true, + currencySymbolPlacement: "s", + negativePositiveSignPlacement: "p", + decimalCharacter: globals.decimals, + decimalCharacterAlternative: ".", + digitGroupSeparator: globals.thousands, + emptyInputBehavior: min ? min : "zero", + overrideMinMaxLimits: "ignore", + modifyValueOnWheel: false, + outputFormat: "string", + unformatOnSubmit: true, + watchExternalChanges: true, + minimumValue: min ? min : "-10000000000000", + maximumValue: max ? max : "10000000000000", + decimalPlaces: decimals, + }); + + $input.data("autonumeric", autonumeric); +} diff --git a/assets/src/js/functions/select.js b/assets/src/js/functions/select.js index fde237def..aec8c220e 100755 --- a/assets/src/js/functions/select.js +++ b/assets/src/js/functions/select.js @@ -16,87 +16,12 @@ * along with this program. If not, see . */ -// Select +/** + * Select. + */ function start_superselect() { - // Statico - $('.superselect').each(function () { - let $this = $(this); - - $(this).select2({ - theme: "bootstrap", - language: "it", - width: '100%', - maximumSelectionLength: $this.data('maximum') ? $this.data('maximum') : -1, - minimumResultsForSearch: $this.hasClass('no-search') ? -1 : 0, - allowClear: !$this.hasClass('no-search'), - escapeMarkup: function (text) { - return text; - }, - templateResult: selectBackground, - }); - }); - - // Dinamico (AJAX, per tabelle con molti record) - $('.superselectajax').each(function () { - let $this = $(this); - - $(this).select2({ - theme: "bootstrap", - language: "it", - maximumSelectionLength: $this.data('maximum') ? $this.data('maximum') : -1, - minimumInputLength: $this.data('heavy') ? 3 : 0, - allowClear: true, - escapeMarkup: function (text) { - return text; - }, - templateResult: selectBackground, - ajax: { - url: globals.rootdir + "/ajax_select.php?op=" + $this.data('source'), - dataType: 'json', - delay: 250, - data: function (params) { - return { - search: params.term, - page: params.page || 0, - length: params.length || 100, - options: this.data('select-options'), // Dati aggiuntivi - }; - }, - processResults: function (data, params) { - params.page = params.page || 0; - params.length = params.length || 100; - - let results = data.results; - - // Interpretazione forzata per campi optgroup - if (results && results[0] && [0]['optgroup']) { - let groups = results.reduce(function (r, a) { - r[a.optgroup] = r[a.optgroup] || []; - r[a.optgroup].push(a); - return r; - }, {}); - - let results_groups = []; - for (const key in groups) { - results_groups.push({ - text: key, - children: groups[key], - }); - } - results = results_groups; - } - - return { - results: results, - pagination: { - more: (params.page + 1) * params.length < data.recordsFiltered, - } - }; - }, - cache: false - }, - width: '100%' - }); + $('.superselect, .superselectajax').each(function () { + initSelectInput(this); }); } @@ -242,3 +167,99 @@ function updateSelectOption(name, value) { $(this).setSelectOption(name, value); }) } + +function initSelectInput(input){ + if ($(input).hasClass('superselect')){ + initStaticSelectInput(input); + } else { + initDynamicSelectInput(input); + } +} + +/** + * Statico. + * @param input + */ +function initStaticSelectInput(input){ + let $input = $(input); + + $input.select2({ + theme: "bootstrap", + language: "it", + width: '100%', + maximumSelectionLength: $input.data('maximum') ? $input.data('maximum') : -1, + minimumResultsForSearch: $input.hasClass('no-search') ? -1 : 0, + allowClear: !$input.hasClass('no-search'), + escapeMarkup: function (text) { + return text; + }, + templateResult: selectBackground, + }); +} + +/** + * Dinamico. + * @param input + */ +function initDynamicSelectInput(input){ + let $input = $(input); + + $input.select2({ + theme: "bootstrap", + language: "it", + maximumSelectionLength: $input.data('maximum') ? $input.data('maximum') : -1, + minimumInputLength: $input.data('heavy') ? 3 : 0, + allowClear: true, + escapeMarkup: function (text) { + return text; + }, + templateResult: selectBackground, + ajax: { + url: globals.rootdir + "/ajax_select.php?op=" + $input.data('source'), + dataType: 'json', + delay: 250, + data: function (params) { + return { + search: params.term, + page: params.page || 0, + length: params.length || 100, + options: this.data('select-options'), // Dati aggiuntivi + }; + }, + processResults: function (data, params) { + params.page = params.page || 0; + params.length = params.length || 100; + + let results = data.results; + + // Interpretazione forzata per campi optgroup + if (results && results[0] && [0]['optgroup']) { + let groups = results.reduce(function (r, a) { + r[a.optgroup] = r[a.optgroup] || []; + r[a.optgroup].push(a); + return r; + }, {}); + + let results_groups = []; + for (const key in groups) { + results_groups.push({ + text: key, + children: groups[key], + }); + } + results = results_groups; + } + + return { + results: results, + pagination: { + more: (params.page + 1) * params.length < data.recordsFiltered, + } + }; + }, + cache: false + }, + width: '100%' + }); +} + diff --git a/modules/primanota/movimenti.php b/modules/primanota/movimenti.php index 64313e41f..878fd5be1 100755 --- a/modules/primanota/movimenti.php +++ b/modules/primanota/movimenti.php @@ -171,7 +171,7 @@ echo ' echo '