1
0
mirror of https://github.com/devcode-it/openstamanager.git synced 2025-06-05 22:09:38 +02:00

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.
This commit is contained in:
Dasc3er
2020-10-11 09:46:38 +02:00
parent 210d1575bd
commit 82e1b15251
17 changed files with 339 additions and 125 deletions

View File

@@ -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);
});
}

View File

@@ -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;
}

View File

@@ -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.
*

View File

@@ -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);
});
}

View File

@@ -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;

View File

@@ -18,10 +18,12 @@
/**
* Select.
*
* @deprecated
*/
function start_superselect() {
$('.superselect, .superselectajax').each(function () {
initSelectInput(this);
input(this);
});
}

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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);
});
});
}

View File

@@ -152,7 +152,7 @@ echo '
<script>
var emails = [];
$(document).ready(function(){';
$(document).ready(function() {';
// Autocompletamento destinatario
if (!empty($id_anagrafica)) {
@@ -180,13 +180,13 @@ echo '
});
function send(){
function send() {
if($("#email-form").parsley().validate() && confirm("Inviare e-mail?")) {
$("#email-form").submit();
}
}
function aggiungi_destinatario(){
function aggiungi_destinatario() {
var last = $("#lista-destinatari input").last();
if (last.val()) {

View File

@@ -253,7 +253,7 @@ WHERE (SELECT COUNT(*) FROM in_interventi_tecnici WHERE in_interventi_tecnici.id
->sortBy('data');
echo '
<select class="superselect" id="mese-promemoria">';
<select class="superselect openstamanager-input" id="mese-promemoria">';
foreach ($mesi as $mese) {
$data = new Carbon\Carbon($mese['data']);

View File

@@ -62,61 +62,78 @@ include_once __DIR__.'/../../core.php';
</div>
<div class="panel-body">
<div class="data">
<div id="elenco-rate">
<?php
$values = '';
$giorni_pagamento = [];
for ($i = 1; $i <= 31; ++$i) {
$values .= '\"'.$i.'\": \"'.$i.'\"';
if ($i != 31) {
$values .= ',';
}
$giorni_pagamento[] = [
'id' => $i,
'text' => $i,
];
}
$tipi_scadenza_pagamento = [
[
'id' => 1,
'text' => tr('Data fatturazione'),
],
[
'id' => 2,
'text' => tr('Data fatturazione fine mese'),
],
[
'id' => 3,
'text' => tr('Data fatturazione giorno fisso'),
],
[
'id' => 4,
'text' => tr('Data fatturazione fine mese (giorno fisso)'),
],
];
$results = $dbo->fetchArray('SELECT * FROM `co_pagamenti` WHERE descrizione='.prepare($record['descrizione']).' ORDER BY `num_giorni` ASC');
$cont = 1;
$numero_rata = 1;
foreach ($results as $result) {
$tipo_scadenza_pagamento = 3;
if ($result['giorno'] == 0) {
$tipo_scadenza_pagamento = 1;
} elseif ($result['giorno'] == -1) {
$tipo_scadenza_pagamento = 2;
} elseif ($result['giorno'] < -1) {
$tipo_scadenza_pagamento = 4;
}
$giorno_pagamento = null;
if ($result['giorno'] != 0 && $result['giorno'] != -1) {
$giorno_pagamento = ($result['giorno'] < -1) ? -$result['giorno'] - 1 : $result['giorno'];
}
echo '
<div class="box box-success">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Rata _NUMBER_', [
'_NUMBER_' => $cont,
'_NUMBER_' => $numero_rata,
]).'</h3>
<a class="btn btn-danger pull-right" onclick="';
echo "if(confirm('".tr('Eliminare questo elemento?')."')){ location.href='".base_path().'/editor.php?id_module='.$id_module.'&id_record='.$id_record.'&op=delete_rata&id='.$result['id']."'; }";
echo '"><i class="fa fa-trash"></i> '.tr('Elimina').'</a>
<button type="button" class="btn btn-danger pull-right" onclick="rimuoviRata('.$result['id'].')">
<i class="fa fa-trash"></i> '.tr('Elimina').'
</button>
</div>
<div class="box-body">
<input type="hidden" value="'.$result['id'].'" name="id[]">
<input type="hidden" value="'.$result['id'].'" name="id['.$numero_rata.']">
<div class="row">
<div class="col-md-6">
{[ "type": "number", "label": "'.tr('Percentuale').'", "name": "percentuale[]", "decimals": "2", "min-value": "0", "value": "'.$result['prc'].'", "icon-after": "<i class=\"fa fa-percent\"></i>" ]}
{[ "type": "number", "label": "'.tr('Percentuale').'", "name": "percentuale['.$numero_rata.']", "decimals": "2", "min-value": "0", "value": "'.$result['prc'].'", "icon-after": "<i class=\"fa fa-percent\"></i>" ]}
</div>
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Scadenza').'", "name": "scadenza[]", "values": "list=\"1\":\"'.tr('Data fatturazione').'\",\"2\":\"'.tr('Data fatturazione fine mese').'\",\"3\":\"'.tr('Data fatturazione giorno fisso').'\",\"4\":\"'.tr('Data fatturazione fine mese (giorno fisso)').'\"", "value": "';
if ($result['giorno'] == 0) {
$select = 1;
} elseif ($result['giorno'] == -1) {
$select = 2;
} elseif ($result['giorno'] < -1) {
$select = 4;
} elseif ($result['giorno'] > 0) {
$select = 3;
}
echo $select;
echo '" ]}
{[ "type": "select", "label": "'.tr('Scadenza').'", "name": "scadenza['.$numero_rata.']", "values": '.json_encode($tipi_scadenza_pagamento).', "value": "'.$tipo_scadenza_pagamento.'" ]}
</div>
</div>
<div class="row">
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Giorno').'", "name": "giorno[]", "values": "list='.$values.'", "value": "';
if ($result['giorno'] != 0 && $result['giorno'] != -1) {
echo ($result['giorno'] < -1) ? -$result['giorno'] - 1 : $result['giorno'];
}
echo '", "extra": "';
{[ "type": "select", "label": "'.tr('Giorno').'", "name": "giorno['.$numero_rata.']", "values": '.json_encode($giorni_pagamento).', "value": "'.$giorno_pagamento.'", "extra": "';
if ($result['giorno'] == 0 || $result['giorno'] == -1) {
echo ' disabled';
}
@@ -124,27 +141,34 @@ foreach ($results as $result) {
</div>
<div class="col-md-6">
{[ "type": "number", "label": "'.tr('Distanza in giorni').'", "name": "distanza[]", "decimals": "0", "min-value": "0", "value": "'.$result['num_giorni'].'" ]}
{[ "type": "number", "label": "'.tr('Distanza in giorni').'", "name": "distanza['.$numero_rata.']", "decimals": "0", "min-value": "0", "value": "'.$result['num_giorni'].'" ]}
</div>
</div>
</div>
</div>';
++$cont;
++$numero_rata;
}
?>
</div>
<div class="pull-right">
<button type="button" class="btn btn-info" id="add"><i class="fa fa-plus"></i> <?php echo tr('Aggiungi'); ?></button>
<button type="submit" class="btn btn-success"><i class="fa fa-check"></i> <?php echo tr('Salva'); ?></button>
<button type="button" class="btn btn-info" onclick="aggiungiRata()">
<i class="fa fa-plus"></i> <?php echo tr('Aggiungi'); ?>
</button>
<button type="submit" class="btn btn-success">
<i class="fa fa-check"></i> <?php echo tr('Salva'); ?>
</button>
</div>
</div>
</div>
</form>
<div class="box box-warning box-solid text-center hide" id="wait">
<div class="box-header with-border">
<h3 class="box-title"><i class="fa fa-warning"></i> <?php echo tr('Attenzione!'); ?></h3>
<h3 class="box-title">
<i class="fa fa-warning"></i> <?php echo tr('Attenzione!'); ?>
</h3>
</div>
<div class="box-body">
<p><?php echo tr('Prima di poter continuare con il salvataggio è necessario che i valori percentuali raggiungano in totale il 100%'); ?>.</p>
@@ -162,25 +186,25 @@ echo '
<h3 class="box-title">'.tr('Nuova rata').'</h3>
</div>
<div class="box-body">
<input type="hidden" value="" name="id[]">
<input type="hidden" value="" name="id[-id-]">
<div class="row">
<div class="col-md-6">
{[ "type": "number", "label": "'.tr('Percentuale').'", "name": "percentuale[]", "icon-after": "<i class=\"fa fa-percent\"></i>" ]}
{[ "type": "number", "label": "'.tr('Percentuale').'", "name": "percentuale[-id-]", "icon-after": "<i class=\"fa fa-percent\"></i>" ]}
</div>
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Scadenza').'", "name": "scadenza[]", "values": "list=\"1\":\"'.tr('Data fatturazione').'\",\"2\":\"'.tr('Data fatturazione fine mese').'\",\"3\":\"'.tr('Data fatturazione giorno fisso').'\",\"4\":\"'.tr('Data fatturazione fine mese (giorno fisso)').'\"", "value": 1 ]}
{[ "type": "select", "label": "'.tr('Scadenza').'", "name": "scadenza[-id-]", "values": '.json_encode($tipi_scadenza_pagamento).', "value": 1 ]}
</div>
</div>
<div class="row">
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Giorno').'", "name": "giorno[]", "values": "list='.$values.'" ]}
{[ "type": "select", "label": "'.tr('Giorno').'", "name": "giorno[-id-]", "values": '.json_encode($giorni_pagamento).' ]}
</div>
<div class="col-md-6">
{[ "type": "number", "label": "'.tr('Distanza in giorni').'", "name": "distanza[]", "decimals": "0" ]}
{[ "type": "number", "label": "'.tr('Distanza in giorni').'", "name": "distanza[-id-]", "decimals": "0" ]}
</div>
</div>
</div>
@@ -190,44 +214,54 @@ echo '
?>
<script>
var indice_rata = "<?php echo $numero_rata; ?>";
$(document).ready(function() {
$(document).on('click', '#add', function() {
cleanup_inputs();
$(document).on("change", "[id^=scadenza]", function() {
const giorno = $(this).parentsUntil(".box").find("[id*=giorno]");
const giorno_input = input(giorno[0]);
$(this).parent().parent().find('.data').append($('#template').html());
const tipo_scadenza = parseInt(input(this).get());
restart_inputs();
});
$(document).on('change', '[id*=scadenza]', function() {
if($(this).val() == 1 || $(this).val() == 2){
$(this).parentsUntil('.box').find('[id*=giorno]').prop('disabled', true);
}else{
$(this).parentsUntil('.box').find('[id*=giorno]').prop('disabled', false);
}
giorno_input.setDisabled(tipo_scadenza === 1 || tipo_scadenza === 2);
});
$(document).on('change', '[id*=percentuale]', function() {
$('button[type=submit]').prop( 'disabled', false ).removeClass('disabled');
$(document).on("change", "input[id^=percentuale]", function() {
controllaRate();
});
$('#edit-form').submit( function(event) {
var tot = 0;
$(this).find('[id*=percentuale]').each(function() {
prc = $(this).val().toEnglish();
prc = !isNaN(prc) ? prc : 0;
tot += prc;
});
if( tot != 100) {
$('#wait').removeClass("hide");
event.preventDefault();
} else {
$('#wait').addClass("hide");
$(this).unbind('submit').submit();
}
$("#edit-form").submit(function(event) {
const result = controllaRate();
if (!result) {
event.preventDefault();
return false;
}
});
});
function aggiungiRata() {
aggiungiContenuto("#elenco-rate", "#template", {"-id-": indice_rata});
indice_rata++;
}
function controllaRate() {
let totale = 0;
$("#elenco-rate").find("input[id^=percentuale]").each(function() {
totale += input(this).get();
});
if(totale !== 100) {
$("#wait").removeClass("hide");
} else {
$("#wait").addClass("hide");
}
return totale === 100;
}
function rimuoviRata(id) {
if(confirm("<?php echo tr('Eliminare questo elemento?'); ?>")){
location.href = "<?php echo base_path(); ?>/editor.php?id_module=<?php echo $id_module; ?>&id_record=<?php echo $id_record; ?>&op=delete_rata&id=" + id;
}
}
</script>

View File

@@ -104,7 +104,7 @@ if ($structure->permission == 'rw') {
<!-- PULSANTI -->
<div class="row">
<div class="col-md-12 text-right">
<button type="submit" class="btn btn-primary" disabled id="aggiungi_nota" >
<button type="submit" class="btn btn-primary" disabled id="aggiungi_nota" >
<i class="fa fa-plus"></i> '.tr('Aggiungi').'
</button>
</div>
@@ -114,14 +114,12 @@ if ($structure->permission == 'rw') {
echo '
<script>
$(document).ready(function(){
CKEDITOR.instances["contenuto"].on("key", function() {
setTimeout(function(){
if(CKEDITOR.instances["contenuto"].getData() == ""){
$("#aggiungi_nota").prop("disabled", true);
}
else $("#aggiungi_nota").prop("disabled", false);
}, 10);
});
});
var contenuto_nota = input("contenuto");
contenuto_nota.on("change", function() {
if (contenuto_nota.get() === "") {
$("#aggiungi_nota").prop("disabled", true);
} else {
$("#aggiungi_nota").prop("disabled", false);
}
});
</script>';

View File

@@ -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 '
<textarea |attr|>|value|</textarea>
<textarea |attr|>|value|</textarea>';
/*
<script src="'.base_path().'/assets/dist/js/ckeditor/ckeditor.js"></script>
<script>
CKEDITOR.addCss(".cke_editable img { max-width: 100% !important; height: auto !important; }");
@@ -42,6 +46,6 @@ class CKEditorHandler implements HandlerInterface
scayt_sLang: globals.full_locale,
disableNativeSpellChecker: false,
});
</script>';
</script>*/
}
}

View File

@@ -72,7 +72,7 @@ class ChoicesHandler implements HandlerInterface
// "+ this.checked" rende il valore booleano un numero
$result = '
<div class="form-group checkbox-group">
<input type="hidden" name="|name|" value="|value|">
<input type="hidden" name="|name|" value="|value|" class="openstamanager-input">
<input type="checkbox" id="|id|" value="|value|" autocomplete="off" class="hidden" |attr| onchange="$(this).parent().find(\'[type = hidden]\').val(+this.checked).trigger(\'change\')"/>
<div class="btn-group checkbox-buttons">
<label for="|id|" class="btn btn-default'.$class.'">

View File

@@ -28,6 +28,8 @@ class DateHandler implements HandlerInterface
{
public function handle(&$values, &$extras)
{
$values['class'][] = 'openstamanager-input';
// Impostazione alla data corrente se il contenuto corrisponde a "now"
$detect = [
'value',

View File

@@ -28,6 +28,8 @@ class DefaultHandler implements HandlerInterface
{
public function handle(&$values, &$extras)
{
$values['class'][] = 'openstamanager-input';
// Delega della gestione al metodo specifico per il tipo di input richiesto
if (in_array($values['type'], get_class_methods($this))) {
$result = $this->{$values['type']}($values, $extras);

View File

@@ -28,6 +28,8 @@ class MediaHandler implements HandlerInterface
{
public function handle(&$values, &$extras)
{
$values['class'][] = 'openstamanager-input';
// Delega della gestione al metodo specifico per il tipo di input richiesto
$result = $this->{$values['type']}($values, $extras);

View File

@@ -30,6 +30,8 @@ class SelectHandler implements HandlerInterface
{
public function handle(&$values, &$extras)
{
$values['class'][] = 'openstamanager-input';
$source = isset($values['ajax-source']) ? $values['ajax-source'] : (isset($values['select-source']) ? $values['select-source'] : null);
// Individuazione della classe per la corretta gestione JavaScript