From 82e1b15251d5a4ba32e496d6a397f9596b80b070 Mon Sep 17 00:00:00 2001 From: Dasc3er Date: Sun, 11 Oct 2020 09:46:38 +0200 Subject: [PATCH] Miglioramento gestione JS degli input Correzione sul salvataggio dei dati per il modulo Pagamenti (#896). Introduzione del supporto all'editor di testi per la gestione centralizzata JS degli input. --- assets/src/js/functions/dates.js | 9 +- assets/src/js/functions/functions.js | 86 +++++++++- assets/src/js/functions/input.js | 70 ++++++-- assets/src/js/functions/inputmask.js | 7 +- assets/src/js/functions/numbers.js | 14 +- assets/src/js/functions/select.js | 4 +- assets/src/js/functions/textarea.js | 48 ++++++ mail.php | 6 +- modules/dashboard/edit.php | 2 +- modules/pagamenti/edit.php | 180 ++++++++++++-------- plugins/notes.php | 20 +-- src/HTMLBuilder/Handler/CKEditorHandler.php | 8 +- src/HTMLBuilder/Handler/ChoicesHandler.php | 2 +- src/HTMLBuilder/Handler/DateHandler.php | 2 + src/HTMLBuilder/Handler/DefaultHandler.php | 2 + src/HTMLBuilder/Handler/MediaHandler.php | 2 + src/HTMLBuilder/Handler/SelectHandler.php | 2 + 17 files changed, 339 insertions(+), 125 deletions(-) create mode 100644 assets/src/js/functions/textarea.js diff --git a/assets/src/js/functions/dates.js b/assets/src/js/functions/dates.js index 3e5ec500d..5768056eb 100755 --- a/assets/src/js/functions/dates.js +++ b/assets/src/js/functions/dates.js @@ -90,17 +90,20 @@ function initTimeInput(input) { }); } +/** + * @deprecated + */ function start_datepickers() { $('.timestamp-picker').each(function () { - initTimestampInput(this); + input(this); }); $('.datepicker').each(function () { - initDateInput(this); + input(this); }); $('.timepicker').each(function () { - initTimeInput(this); + input(this); }); } diff --git a/assets/src/js/functions/functions.js b/assets/src/js/functions/functions.js index 6886869be..21ff049b4 100755 --- a/assets/src/js/functions/functions.js +++ b/assets/src/js/functions/functions.js @@ -495,6 +495,9 @@ function replaceAll(str, find, replace) { return str.replace(new RegExp(find, "g"), replace); } +/** + * @deprecated + */ function cleanup_inputs() { $('.bound').removeClass("bound"); @@ -507,7 +510,15 @@ function cleanup_inputs() { }); } +/** + * @deprecated + */ function restart_inputs() { + // Generazione degli input + $('.openstamanager-input').each(function () { + input(this); + }); + /* start_datepickers(); start_inputmask(); @@ -516,6 +527,7 @@ function restart_inputs() { // Autosize per le textarea initTextareaInput($('.autosize')); + */ } /** @@ -649,6 +661,76 @@ function hideTableColumn(table, column) { } } -function initTextareaInput(input){ - autosize($(input)); +/** + * Loads a JavaScript file and returns a Promise for when it is loaded + */ +function loadScript(src, async = true, defer = true) { + if (!globals.dynamicScripts) { + globals.dynamicScripts = {}; + } + + return new Promise((resolve, reject) => { + // Caricamento già completato + if (globals.dynamicScripts[src] && globals.dynamicScripts[src] === "done") { + resolve(); + return; + } + + // Aggiunta del resolve all'elenco per lo script + if (!globals.dynamicScripts[src]) { + globals.dynamicScripts[src] = []; + } + globals.dynamicScripts[src].push(resolve); + + // Ricerca dello script esistente + let found = Array.prototype.slice.call(document.scripts).find(el => el.getAttribute("src") === src); + if (found) { + return; + } + + // Caricamento dinamico dello script + const script = document.createElement('script'); + script.type = 'text/javascript'; + script.async = async; + script.defer = defer; + + script.onload = function () { + for (resolve of globals.dynamicScripts[src]) { + resolve(); + } + + globals.dynamicScripts[src] = "done"; + } + + script.onerror = reject; + script.src = src; + document.head.append(script); + }) +} + +function aggiungiContenuto(endpoint_selector, template_selector, replaces = {}) { + let template = $(template_selector); + let endpoint = $(endpoint_selector); + + // Distruzione degli input interni + template.find('.openstamanager-input').each(function () { + input(this).destroy(); + }); + + // Contenuto da sostituire + let content = template.html(); + for ([key, value] of Object.entries(replaces)) { + content = replaceAll(content, key, value); + } + + // Aggiunta del contenuto + let element = $(content); + endpoint.append(element); + + // Rigenerazione degli input interni + element.find('.openstamanager-input').each(function () { + input(this).trigger("change"); + }); + + return element; } diff --git a/assets/src/js/functions/input.js b/assets/src/js/functions/input.js index 1d3719add..025c976a5 100644 --- a/assets/src/js/functions/input.js +++ b/assets/src/js/functions/input.js @@ -55,41 +55,47 @@ function Input(element) { this.element = element; // Controllo sulla gestione precedente - if (!this.element.data("input-set")) { - return; + if (this.element.data("input-controller")) { + return this.element.data("input-controller"); } - this.element.data("input-set", 1); + this.element.data("input-controller", this); this.element.data("required", this.element.attr("required")); + let htmlElement = element[0]; // Operazioni di inizializzazione per input specifici // Inizializzazione per date if (this.element.hasClass('timestamp-picker')) { - initTimestampInput(this.element); + initTimestampInput(htmlElement); } else if (this.element.hasClass('datepicker')) { - initDateInput(this.element); + initDateInput(htmlElement); } else if (this.element.hasClass('timepicker')) { - initTimeInput(this.element); + initTimeInput(htmlElement); } // Inizializzazione per campi numerici else if (this.element.hasClass('decimal-number')) { - initNumberInput(this.element); + initNumberInput(htmlElement); + } + + // Inizializzazione per textarea + else if (this.element.hasClass('editor-input')) { + initEditorInput(htmlElement); } // Inizializzazione per textarea else if (this.element.hasClass('autosize')) { - initTextareaInput(this.element); + initTextareaInput(htmlElement); } // Inizializzazione per select else if (this.element.hasClass('superselect') || this.element.hasClass('superselectajax')) { - initSelectInput(this.element); + initSelectInput(htmlElement); } // Inizializzazione alternativa per maschere else { - initMaskInput(this.element); + initMaskInput(htmlElement); } } @@ -125,6 +131,12 @@ Input.prototype.disable = function () { .attr("readonly", false) .addClass("disabled"); + // Gestione dell'editor + if (this.element.hasClass("editor-input")) { + const name = this.element.attr("id"); + CKEDITOR.instances[name].setReadOnly(true); + } + return this; } @@ -148,6 +160,12 @@ Input.prototype.enable = function () { .attr("readonly", false) .removeClass("disabled"); + // Gestione dell'editor + if (this.element.hasClass("editor-input")) { + const name = this.element.attr("id"); + CKEDITOR.instances[name].setReadOnly(false); + } + return this; } @@ -169,6 +187,12 @@ Input.prototype.getData = function () { Input.prototype.get = function () { let value = this.element.val(); + // Gestione dei valori per l'editor + if (this.element.hasClass("editor-input")) { + const name = this.element.attr("id"); + value = typeof CKEDITOR !== 'undefined' ? CKEDITOR.instances[name].getData() : value; + } + // Conversione del valore per le checkbox let group = this.element.closest(".form-group"); if (group.find("input[type=checkbox]").length) { @@ -211,18 +235,36 @@ Input.prototype.setRequired = function (value) { } // Eventi permessi -Input.prototype.change = function (event) { - return this.element.change(event); +Input.prototype.change = function (callable) { + return this.on("change", callable); } -Input.prototype.on = function (event, action) { - return this.element.on(event, action(event)); +Input.prototype.on = function (event, callable) { + return this.element.on(event, callable); } Input.prototype.off = function (event) { return this.element.off(event); } +Input.prototype.trigger = function (event, callable) { + return this.element.trigger(event, callable); +} + +Input.prototype.destroy = function () { + if (this.element.data('select2')) { + this.element.select2().select2("destroy") + } + + // Gestione della distruzione per l'editor + if (this.element.hasClass("editor-input")) { + const name = this.element.attr("id"); + CKEDITOR.instances[name].destroy(); + } + + this.element.data("input-controller", null); +} + /** * Returns true if it is a DOM node. * diff --git a/assets/src/js/functions/inputmask.js b/assets/src/js/functions/inputmask.js index 5cac17867..97842bec2 100644 --- a/assets/src/js/functions/inputmask.js +++ b/assets/src/js/functions/inputmask.js @@ -18,11 +18,6 @@ function initMaskInput(input) { let $input = $(input); - if ($input.hasClass('bound')){ - return; - } - - $input.addClass('bound'); if ($input.hasClass('email-mask')){ $input.inputmask('Regex', { @@ -64,6 +59,6 @@ function start_inputmask(element) { let selector = element + '.' + masks.join(', ' + element + '.') $(selector).each(function () { - initMaskInput(this); + input(this); }); } diff --git a/assets/src/js/functions/numbers.js b/assets/src/js/functions/numbers.js index 392c48a21..c69c46a0b 100644 --- a/assets/src/js/functions/numbers.js +++ b/assets/src/js/functions/numbers.js @@ -18,18 +18,16 @@ /** * Funzione per inizializzare i campi di input numerici per la gestione integrata del formato impostato per il gestionale. + * + * @deprecated */ function initNumbers() { - let inputs = $('.decimal-number').not('.bound'); - - for (const input of inputs) { - initNumberInput(input); - - $(input).addClass('bound'); - } + $('.decimal-number').each(function () { + input(this); + }); } -function initNumberInput(input){ +function initNumberInput(input) { let $input = $(input); if (AutoNumeric.isManagedByAutoNumeric(input)) { return; diff --git a/assets/src/js/functions/select.js b/assets/src/js/functions/select.js index aec8c220e..0bc89b807 100755 --- a/assets/src/js/functions/select.js +++ b/assets/src/js/functions/select.js @@ -18,10 +18,12 @@ /** * Select. + * + * @deprecated */ function start_superselect() { $('.superselect, .superselectajax').each(function () { - initSelectInput(this); + input(this); }); } diff --git a/assets/src/js/functions/textarea.js b/assets/src/js/functions/textarea.js new file mode 100644 index 000000000..7c392b8ad --- /dev/null +++ b/assets/src/js/functions/textarea.js @@ -0,0 +1,48 @@ +/* + * OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione + * Copyright (C) DevCode s.n.c. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +function initTextareaInput(input) { + autosize($(input)); +} + +function initEditorInput(input) { + let $input = $(input); + let name = input.getAttribute("id"); + + loadScript(globals.rootdir + "/assets/dist/js/ckeditor/ckeditor.js") + .then(function () { + CKEDITOR.addCss(".cke_editable img { max-width: 100% !important; height: auto !important; }"); + + CKEDITOR.replace(name, { + toolbar: globals.ckeditorToolbar, + language: globals.locale, + scayt_autoStartup: true, + scayt_sLang: globals.full_locale, + disableNativeSpellChecker: false, + }); + + CKEDITOR.instances[name].on("key", function (event) { + $input.trigger("keydown", event.data); + $input.trigger("keyup", event.data); + }); + + CKEDITOR.instances[name].on("change", function (event) { + $input.trigger("change", event); + }); + }); +} diff --git a/mail.php b/mail.php index 206332a69..b0271d110 100755 --- a/mail.php +++ b/mail.php @@ -152,7 +152,7 @@ echo ' diff --git a/plugins/notes.php b/plugins/notes.php index 507f7ea4a..aa9420c42 100755 --- a/plugins/notes.php +++ b/plugins/notes.php @@ -104,7 +104,7 @@ if ($structure->permission == 'rw') {
-
@@ -114,14 +114,12 @@ if ($structure->permission == 'rw') { echo ' '; diff --git a/src/HTMLBuilder/Handler/CKEditorHandler.php b/src/HTMLBuilder/Handler/CKEditorHandler.php index 1004a4231..a223d0a79 100755 --- a/src/HTMLBuilder/Handler/CKEditorHandler.php +++ b/src/HTMLBuilder/Handler/CKEditorHandler.php @@ -28,9 +28,13 @@ class CKEditorHandler implements HandlerInterface { public function handle(&$values, &$extras) { + $values['class'][] = 'openstamanager-input'; + $values['class'][] = 'editor-input'; + // Generazione del codice HTML return ' - + '; + /* '; + */ } } diff --git a/src/HTMLBuilder/Handler/ChoicesHandler.php b/src/HTMLBuilder/Handler/ChoicesHandler.php index e71eee13f..3f0f402c2 100755 --- a/src/HTMLBuilder/Handler/ChoicesHandler.php +++ b/src/HTMLBuilder/Handler/ChoicesHandler.php @@ -72,7 +72,7 @@ class ChoicesHandler implements HandlerInterface // "+ this.checked" rende il valore booleano un numero $result = '
- +