/* * OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione * Copyright (C) DevCode s.r.l. * * 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 start_local_datatables() { $('.datatables').each(function () { if (!$.fn.DataTable.isDataTable($(this))) { $(this).DataTable({ language: globals.translations.datatables, retrieve: true, ordering: true, searching: true, paging: false, order: [], lengthChange: false, scrollY: "70vh", }); } }); } // Datatable function start_datatables( $elements ) { start_local_datatables(); $elements.each(function () { const $this = $(this); // Controlla che la tabella non sia già inizializzata if (!$.fn.DataTable.isDataTable('#' + $this.attr('id'))) { const id_module = $this.data('idmodule'); const id_plugin = $this.data('idplugin'); const id_parent = $this.data('idparent'); // Parametri di ricerca da url o sessione const search = getTableSearch(); const column_search = []; $this.find("th").each(function () { const id = $(this).attr('id').replace("th_", ""); const single_value = search["search_" + id] ? search["search_" + id] : ""; column_search.push({ "sSearch": single_value, }); }); $this.on('preInit.dt', function (ev, settings) { $('#mini-loader').show(); }); const table = $this.DataTable({ language: globals.translations.datatables, autoWidth: true, dom: "ti", serverSide: true, deferRender: true, ordering: true, searching: true, aaSorting: [], aoSearchCols: column_search, scrollY: "60vh", scrollX: '100%', retrieve: true, stateSave: true, rowId: 'id', stateSaveCallback: function (settings, data) { sessionStorage.setItem('DataTables_' + id_module + '-' + id_plugin + '-' + id_parent, JSON.stringify(data)); }, stateLoadCallback: function (settings) { return JSON.parse(sessionStorage.getItem('DataTables_' + id_module + '-' + id_plugin + '-' + id_parent)); }, columnDefs: [{ searchable: false, orderable: false, width: '1%', className: 'select-checkbox', targets: 0 }], select: { style: 'multi', selector: 'td:first-child' }, buttons: getDatatablesButtons($this), scroller: { loadingIndicator: true, displayBuffer: globals.dataload_page_buffer, }, ajax: { url: "ajax_dataload.php?id_module=" + id_module + "&id_plugin=" + id_plugin + "&id_parent=" + id_parent, type: 'GET', dataSrc: "data", }, initComplete: initComplete, drawCallback: drawCallback, footerCallback: footerCallback, }); table.on('processing.dt', function (e, settings, processing) { if (processing) { $('#mini-loader').show(); } else { $('#mini-loader').hide(); } }); } }); } /** * Funzione per evitare il sorting al click della colonna. * Utilizzata per evitare il sorting nelle ricerche. * @param {*} e */ function stopTableSorting(e) { if (!e) var e = window.event; e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); } /** * Funzione per resettare il campo di ricerca in una specifica colonna. * @param {string} type */ function resetTableSearch(type) { if (type == null) $('[id^=th_] input').val('').trigger('keyup'); else $('[id^=th_' + type + '] input').val('').trigger('keyup'); } /** * Sostituisce i caratteri speciali per la ricerca attraverso le tabelle Datatables. * * @param {string} field * @return string */ function searchFieldName(field) { return field.replace(' ', '-').replace('.', ''); } /** * Salva nella sessione la ricerca per le tabelle Datatables. * * @param {int} module_id * @param {string} field * @param {string} value */ function setTableSearch(module_id, field, value) { session_set('module_' + module_id + ',' + 'search_' + searchFieldName(field), value, 0); } /** * Restituisce i valori di ricerca impostati nell'URL della pagina. * @returns {{}} */ function getTableSearch() { // Parametri di ricerca da url o sessione const search = getUrlVars(); globals.search.forEach(function (value, index, array) { if (search[array[index]] === undefined) { search[array[index]] = array[value]; } }); return search; } /** * Restituisce i pulsanti da generare per la tabella Datatables. * @returns */ function getDatatablesButtons(table) { return [ // Pulsante di esportazione CSV { extend: 'csv', footer: true, fieldSeparator: ";", exportOptions: { modifier: { selected: true }, format: { body: function (data, row, column, node) { data = $('

' + data + '

').text(); data_edit = data.replace('.', ''); // Rimozione punto delle migliaia return data_edit.match(/^[0-9,]+$/) ? data_edit : data; } } } }, // Pulsante di esportazione tramite copia { extend: 'copy', footer: true, exportOptions: { modifier: { selected: true } } }, // Pulsante di esportazione via stampa della tabella { extend: 'print', autoPrint: true, footer: false, // Non funzionante in Firefox, e saltuarmente in Chrome customize: function (win, config, datatable) { const footer = datatable.table().footer().children[0]; const body = $(win.document.body); body.find('table') .addClass('compact') .css('font-size', 'inherit') .append(footer.cloneNode(true)); body.find('td:first-child, th:first-child') .addClass('hide'); }, exportOptions: { modifier: { selected: true } } }, // Pulsante di esportazione in formato Excel { extend: 'excel', footer: true, exportOptions: { modifier: { selected: true }, format: { body: function (data, row, column, node) { data = $('

' + data + '

').text(); data_edit = data.replace('.', ''); // Fix specifico per i numeri italiani data_edit = data_edit.replace(',', '.'); return data_edit.match(/^[0-9\.]+$/) ? data_edit : data; } } } }, // Pulsante di esportazione in formato PDF { extend: 'pdf', orientation: 'landscape', footer: true, exportOptions: { modifier: { selected: true } } }, ]; } function initComplete(settings) { const api = this.api(); const $this = $(this); const search = getTableSearch(); var forceSearch = false; api.columns('.search').every(function () { const column = this; // Valore predefinito della ricerca let tempo; const header = $(column.header()); const name = header.attr('id').replace('th_', ''); const value = search['search_' + name] ? search['search_' + name] : ''; if (value !== '') { forceSearch = true; } $('
') .appendTo(column.header()) .on('keyup', function (e) { clearInterval(tempo); // Fix del pulsante di pulizia ricerca e del messaggio sulla ricerca lenta if (e.which != 9) { if (!$(this).val()) { if ($(this).parent().data("slow") != undefined) $("#slow").remove(); $(this).removeClass('input-searching'); $(this).next('.deleteicon').addClass('hide'); } else { if ($(this).parent().data("slow") != undefined && $("#slow").length == 0) { $("#" + $this.attr('id') + "_info").parent().append(' ' + globals.translations.long + ''); } $(this).addClass('input-searching'); $(this).next('.deleteicon').removeClass('hide'); } } function start_search(module_id, field, search_value) { // Rimozione righe selezionate per problemi di calcolo totale righe selezionate var table_selector = "#" + $this.attr('id'); var wrapper = getTable(table_selector); var table = wrapper.datatable; var row_ids = wrapper.getSelectedRows(); wrapper.removeSelectedRows(row_ids); table.clear().draw(); setTableSearch(module_id, field, search_value); column.search(search_value).draw(); } // Impostazione delle sessioni per le ricerche del modulo e del campo specificati const module_id = $this.data('idmodule'); //+ "-" + $this.data('idplugin'); const field = $(this).parent().attr('id').replace('th_', ''); const value = $(this).val(); if (e.keyCode == 13 || $(this).val() == '') { start_search(module_id, field, value); } else { const tempo_attesa_ricerche = (globals.tempo_attesa_ricerche * 1000); tempo = window.setTimeout(start_search, tempo_attesa_ricerche, module_id, field, value); } }); }); if (forceSearch) { $('table.main-records:visible .search > input:not(:emptyVal)').first().trigger('keyup'); } // Disabilito l'ordinamento alla pressione del tasto invio sull' $("thead input, .search").on('keypress', function (e) { stopTableSorting(e); }); // Disabilito l'ordinamento al click sull' $("thead input, .deleteicon").click(function (e) { stopTableSorting(e); }); $('.deleteicon').on("click", function (e) { resetTableSearch($(this).parent().attr("id").replace("th_", "")); }); setTimeout(function () { $('.select-checkbox').each(function(){ var row = $(this).parent(); var row_id = row.attr("id"); var table_selector = $(this).closest(".dataTable"); var wrapper = getTable(table_selector); if(typeof row_id !== "undefined"){ if (row.hasClass("selected")) { wrapper.addSelectedRows(row_id); } else if (!row.hasClass("selected") && row.hasClass("clicked")) { wrapper.removeSelectedRows(row_id); } } }); }, 100); } function drawCallback(settings) { const table = getTable(settings.nTable); const datatable = table.datatable; $(".dataTables_sizing .deleteicon").addClass('hide'); $("[data-background]").each(function () { $(this).parent().css("background", $(this).data("background")); }); $("[data-color]").each(function () { $(this).parent().css("color", $(this).data("color")); }); $("[data-link]").each(function () { const $link = $(this); $(this).parent().not('.bound').addClass('bound').click(function (event) { if ($link.data('type') === 'dialog') { launch_modal(globals.translations.details, $link.data('link')); } else { openLink(event, $link.data('link')) } }); $(this).parent().addClass("clickable"); }); // Reimposto il flag sulle righe ricaricate selezionate in precedenza const selected = table.getSelectedRows(); datatable.rows().every(function (rowIdx) { if (selected.includes(this.id())) { datatable.row(':eq(' + rowIdx + ')', { page: 'current' }).select(); } }); // Fix larghezza colonne datatables setTimeout( function(){ datatable.columns.adjust() }, 100); } function footerCallback(row, data, start, end, display) { let i = -1; const json = this.api().ajax.json(); this.api().columns().every(function () { if (json.summable[i] !== undefined) { $(this.footer()).addClass("text-right") .attr("id", "summable") .html(json.summable[i]); } i++; }); } /** * Restituisce un oggetto che permette di gestire le tabelle DataTables. * * @param selector */ function getTable(selector) { const table = $(selector); const selected = new Map(); const selected_ids = table.data('selected') ? table.data('selected').split(';') : []; selected_ids.forEach(function (item, index) { selected.set(item, true); }); return { table: table, id_module: table.data('idmodule'), id_plugin: table.data('idplugin'), initDatatable: function () { if (table.hasClass('datatables')) { start_local_datatables(); } else { start_datatables( $('.main-records') ); } }, datatable: table.DataTable(), // Funzioni per i contenitori relativi alla tabella getSelectControllerContainer: function () { return $('.row[data-target="' + table.attr('id') + '"]').find('.select-controller-container'); }, getExportContainer: function () { return $('.row[data-target="' + table.attr('id') + '"]').find('.export-container'); }, getActionsContainer: function () { return $('.row[data-target="' + table.attr('id') + '"]').find('.actions-container'); }, // Gestione delle righe selezionate selected: selected, getSelectedRows: function () { return Array.from(selected.keys()); }, saveSelectedRows: function () { const selected_rows = this.getSelectedRows(); table.data('selected', selected_rows.join(';')); // Abilitazione dinamica di azioni di gruppo e esportazione const bulk_container = this.getActionsContainer(); const export_buttons = this.getExportContainer().find('.table-btn'); if (selected_rows.length > 0) { bulk_container.removeClass('disabled').attr('disabled', false); export_buttons.removeClass('disabled').attr('disabled', false); } else { bulk_container.addClass('disabled').attr('disabled', true); export_buttons.addClass('disabled').attr('disabled', true); } // Aggiornamento contatore delle selezioni this.getSelectControllerContainer() .find('.selected-count').html(selected_rows.length); // Aggiornamento del footer nel caso sia richiesto if (globals.restrict_summables_to_selected) { this.updateFooterForSelectedRows(); } }, addSelectedRows: function (row_ids) { row_ids = Array.isArray(row_ids) ? row_ids : [row_ids]; row_ids.forEach(function (item, index) { // Aggiungo una classe per definire che questo elemento è stato cliccato ora, // per poterlo de-cliccare correttamente $('tr[id='+item.toString()+']').addClass('clicked'); selected.set(item.toString(), true); }); this.saveSelectedRows(); }, removeSelectedRows: function (row_ids) { row_ids = Array.isArray(row_ids) ? row_ids : [row_ids]; row_ids.forEach(function (item, index) { selected.delete(item.toString()); }); this.saveSelectedRows(); }, clearSelectedRows: function () { selected.clear(); this.saveSelectedRows(); }, /** * Nuovi valori dei campi summable * @returns */ getSelectedRowsFooter: function () { let ids = this.getSelectedRows(); return $.ajax({ url: globals.rootdir + "/ajax.php", type: "POST", dataType: "json", data: { id_module: this.id_module, id_plugin: this.id_plugin, op: "summable-results", ids: ids, } }); }, /** * Aggiornamento dei campi summable */ updateFooterForSelectedRows: function () { let datatable = this.datatable; this.getSelectedRowsFooter().then(function (response) { for (let [column, value] of Object.entries(response)) { let index = parseInt(column) + 1; let sel = datatable.column(index).footer(); $(sel).addClass("text-right") .attr("id", "summable") .html(value); } }); }, }; } $.expr[':'].emptyVal = function(obj){ return obj.value === ''; };