Ottimizzazione selezione totale su DataTables

This commit is contained in:
Thomas Zilio 2020-07-08 21:12:16 +02:00
parent deace5d010
commit 5523b3db7d
6 changed files with 177 additions and 113 deletions

View File

@ -4,7 +4,7 @@ include_once __DIR__.'/core.php';
use Models\Hook;
switch (get('op')) {
switch (filter('op')) {
// Imposta un valore ad un array di $_SESSION
// esempio: push di un valore in $_SESSION['dashboard']['idtecnici']
// iversed: specifica se rimuovere dall'array il valore trovato e applicare quindi una deselezione (valori 0 o 1, default 1)
@ -140,5 +140,30 @@ switch (get('op')) {
echo json_encode($response);
break;
// Impostazione di selezione di tutti le righe della tabella
case 'table-row-selection':
$row_ids = filter('row_ids');
$type = filter('type');
$selected = &$_SESSION['module_'.$id_module]['selected'];
if (isset($row_ids)) {
foreach ($row_ids as $row_id) {
if (!isset($row_id)) {
continue;
}
// Toggle per la riga indicata
if ($type == 'deselect' && isset($selected[$row_id])) {
unset($selected[$row_id]);
} elseif ($type == 'select') {
$selected[$row_id] = true;
}
}
}
echo json_encode(array_keys($selected));
break;
}

View File

@ -77,6 +77,7 @@ if (!empty($query)) {
// Creazione della tabella
foreach ($rows as $i => $r) {
$result = [
'id' => $r['id'],
'<span class="hide" data-id="'.$r['id'].'"></span>', // Colonna ID
];

View File

@ -31,24 +31,64 @@ $(document).ready(function () {
});
$(".btn-select-all").click(function () {
var id = $(document).find("#" + $(this).parent().parent().parent().data("target"));
var table = id.DataTable();
var table_selector = "#" + $(this).closest("[data-target]").data("target");
var wrapper = getTable(table_selector);
var table = wrapper.datatable;
// Visualizzazione del caricamento
$("#main_loading").show();
// Parametri della richiesta
var params = table.ajax.params();
params.length = -1;
$.ajax({
url: table.ajax.url(),
data: params,
type: 'GET',
dataType: "json",
success: function (response) {
var row_ids = response.data.map(function(a) {return a.id;});
// Chiamata di selezione completa
rowSelection(wrapper, "select", row_ids).then(function () {
table.clear().draw();
$(id).data('page-length', table.page.len());
$("#main_loading").hide();
})
}
})
table.page.len(-1).draw();
});
$(".btn-select-none").click(function () {
var id = $(document).find("#" + $(this).parent().parent().parent().data("target"));
var table = id.DataTable();
var table_selector = "#" + $(this).closest("[data-target]").data("target");
var wrapper = getTable(table_selector);
var table = wrapper.datatable;
table.rows().deselect();
// Chiamata di deselezione completa
var row_ids = wrapper.getSelectedRows();
rowSelection(wrapper, "deselect", row_ids).then(function () {
table.clear().draw();
})
});
table.page.len($(id).data('page-length'));
$(document).on("click", ".select-checkbox", function () {
var row = $(this).parent();
var row_id = row.attr("id");
var table_selector = $(this).closest(".dataTable");
var wrapper = getTable(table_selector);
var type;
if (row.hasClass("selected")) {
//table.datatable.rows("#" + row_id).select();
type = "select";
} else {
//table.datatable.rows("#" + row_id).deselect();
type = "deselect";
}
rowSelection(wrapper, type, row_id);
});
$(".bulk-action").click(function () {
@ -58,7 +98,7 @@ $(document).ready(function () {
$(this).attr("data-id_records", table.data('selected'));
$(this).data("id_records", table.data('selected'));
if ($(this).data("type") == "modal") {
if ($(this).data("type") === "modal") {
var data = JSON.parse(JSON.stringify($(this).data()));
var href = data.url;

View File

@ -22,8 +22,6 @@ function start_datatables() {
$('.main-records').each(function () {
var $this = $(this);
$this.data('selected', '');
// Controlla che la tabella non sia già inizializzata
if (!$.fn.DataTable.isDataTable('#' + $this.attr('id'))) {
var id_module = $this.data('idmodule');
@ -43,7 +41,6 @@ function start_datatables() {
});
});
var sum;
var tempo_attesa_ricerche = (globals.tempo_attesa_ricerche * 1000);
$this.on('preInit.dt', function (ev, settings) {
@ -66,6 +63,7 @@ function start_datatables() {
scrollX: '100%',
retrieve: true,
stateSave: true,
rowId: 'id',
stateSaveCallback: function (settings, data) {
sessionStorage.setItem('DataTables_' + id_module + '-' + id_plugin + '-' + id_parent, JSON.stringify(data));
},
@ -165,10 +163,7 @@ function start_datatables() {
ajax: {
url: "ajax_dataload.php?id_module=" + id_module + "&id_plugin=" + id_plugin + "&id_parent=" + id_parent,
type: 'GET',
dataSrc: function (data) {
sum = data;
return data.data;
}
dataSrc: "data",
},
initComplete: function (settings) {
var api = this.api();
@ -233,17 +228,8 @@ function start_datatables() {
$('.deleteicon').on("click", function (e) {
resetTableSearch($(this).parent().attr("id").replace("th_", ""));
if (api.page.len() == -1) {
api.page.len($(id).data('page-length'));
}
});
},
rowCallback: function (row, data, index) {
if ($(data[0]).data('id') && $.inArray($(data[0]).data('id'), $this.data('selected').split(';')) !== -1) {
table.row(index).select();
}
},
drawCallback: function (settings) {
var api = new $.fn.dataTable.Api(settings);
@ -260,7 +246,7 @@ function start_datatables() {
$("[data-link]").each(function () {
var $link = $(this);
$(this).parent().not('.bound').addClass('bound').click(function (event) {
if ($link.data('type') == 'dialog') {
if ($link.data('type') === 'dialog') {
launch_modal(globals.translations.details, $link.data('link'));
} else {
openLink(event, $link.data('link'))
@ -270,7 +256,6 @@ function start_datatables() {
});
var container = $(document).find('[data-target=' + $this.attr('id') + ']');
if (api.rows({
selected: true
}).count() > 0) {
@ -279,105 +264,37 @@ function start_datatables() {
container.find('.table-btn').addClass('disabled').attr('disabled', true);
}
// Seleziona tutto
if (api.page.len() == -1) {
api.rows({
search: "applied"
// Reimposto il flag sulle righe ricaricate selezionate in precedenza
var selected = $this.data('selected') ? $this.data('selected').split(';') : [];
table.rows().every(function (rowIdx) {
if ($.inArray(this.id().toString(), selected) !== -1) {
table.row(':eq(' + rowIdx + ')', {
page: 'current'
}).select();
if (this.fnSettings().fnRecordsDisplay() == api.rows({
selected: true
}).count()) {
$("#main_loading").fadeOut();
}
}
});
},
footerCallback: function (row, data, start, end, display) {
var i = -1;
var json = this.api().ajax.json();
this.api().columns().every(function () {
if (sum.summable[i] != undefined) {
$(this.footer()).addClass("text-right");
$(this.footer()).attr("id", "summable");
$(this.footer()).html(sum.summable[i]);
if (json.summable[i] !== undefined) {
$(this.footer()).addClass("text-right")
.attr("id", "summable")
.html(json.summable[i]);
}
i++;
});
}
});
table.on('select deselect', function (e, dt, type, indexes) {
if (type === 'row') {
var selected = $this.data('selected').split(';');
selected = selected.filter(function (value, index, self) {
return value != '' && self.indexOf(value) === index;
});
var data = table.rows(indexes).data();
data.each(function (item) {
var id = $(item[0]).data('id');
if (id) {
if (e.type == 'select') {
selected.push(id);
} else {
var index = selected.indexOf("" + id);
if (index > -1) {
delete selected[index];
}
}
}
});
selected = selected.filter(function (value, index, self) {
return value != '' && self.indexOf(value) === index;
});
$this.data('selected', selected.join(';'));
var container = $(document).find('[data-target=' + $this.attr('id') + ']');
if (selected.length > 0) {
container.find('.bulk-container').removeClass('disabled');
container.find('.bulk-container').attr('disabled', false);
} else {
container.find('.bulk-container').addClass('disabled');
container.find('.bulk-container').attr('disabled', true);
}
if (table.rows({
selected: true
}).count() > 0) {
container.find('.table-btn').removeClass('disabled').attr('disabled', false);
} else {
container.find('.table-btn').addClass('disabled').attr('disabled', true);
}
}
});
table.on('processing.dt', function (e, settings, processing) {
if (processing) {
$('#mini-loader').show();
} else {
$('#mini-loader').hide();
//Reimposto il flag sulle righe ricaricate selezionate in precedenza
var selected = $this.data('selected').split(';');
table.rows().every(function (rowIdx, tableLoop, rowLoop) {
var object_span = $.parseHTML(this.data()[0])[0];
var id = $(object_span).data('id');
for (i = 0; i < selected.length; i++) {
var value = selected[i];
if (value == id) {
table.row(':eq(' + rowIdx + ')', {
page: 'current'
}).select();
}
}
});
}
})
}
@ -433,3 +350,76 @@ function getTableSearch() {
return search;
}
/**
* Invia una richiesta di selezione per un insieme di righe delle tabelle Datatables.
*/
function rowSelection(wrapper, type, row_ids) {
return $.ajax({
url: globals.rootdir + "/ajax.php",
type: "POST",
dataType: "json",
data: {
id_module: wrapper.id_module,
id_plugin: wrapper.id_plugin,
op: "table-row-selection",
type: type,
row_ids: row_ids,
},
success: function (selected) {
wrapper.table.data('selected', selected.join(';'));
var bulk_container = wrapper.getActionsContainer();
var btn_container = wrapper.getButtonsContainer();
if (selected.length > 0) {
bulk_container.removeClass('disabled').attr('disabled', false);
btn_container.removeClass('disabled').attr('disabled', false);
} else {
bulk_container.addClass('disabled').attr('disabled', true);
btn_container.addClass('disabled').attr('disabled', true);
}
}
});
}
/**
* Restituisce un oggetto che permette di gestire le tabelle DataTables.
*
* @param selector
*/
function getTable(selector) {
var table = $(selector);
if (!$.fn.DataTable.isDataTable(table)) {
if(table.hasClass('datatables')){
start_local_datatables();
} else {
start_datatables();
}
}
var id_module = table.data('idmodule');
var id_plugin = table.data('idplugin');
var datatable = table.DataTable();
return {
table: table,
id_module: id_module,
id_plugin: id_plugin,
datatable: datatable,
getSelectedRows: function () {
var list = table.data('selected');
return list ? list.split(';') : [];
},
setSelectedRows: function (list) {
return table.data('selected', list.join(';'));
},
getButtonsContainer: function () {
return $('.row[data-target="' + table.attr('id') + '"]').find('.table-btn');
},
getActionsContainer: function () {
return $('.row[data-target="' + table.attr('id') + '"]').find('.bulk-container');
}
};
}

View File

@ -380,6 +380,10 @@ function clean() {
// Operazioni di default per la generazione degli assets
const bower = gulp.series(clean, gulp.parallel(JS, CSS, images, fonts, phpDebugBar, ckeditor, colorpicker, i18n, pdfjs, hotkeys, chartjs, password_strength, csrf));
// Debug su CSS e JS
exports.srcJS = srcJS;
exports.srcCSS = srcCSS;
exports.bower = bower;
exports.release = release;
exports.default = bower;

View File

@ -71,9 +71,13 @@ if (!empty($type) && $type != 'menu' && $type != 'custom') {
</script>';
}
// Reset della selezione precedente
$_SESSION['module_'.$id_module]['selected'] = [];
$selezione = array_keys($_SESSION['module_'.$id_module]['selected']);
$table_id = 'main_'.rand(0, 99);
echo '
<table data-idmodule="'.$id_module.'" data-idplugin="'.$id_plugin.'" data-idparent="'.$id_record.'" id="'.$table_id.'" width="100%" class="main-records table table-condensed table-bordered">
<table data-idmodule="'.$id_module.'" data-selected="'.implode(';', $selezione).'" data-idplugin="'.$id_plugin.'" data-idparent="'.$id_record.'" id="'.$table_id.'" width="100%" class="main-records table table-condensed table-bordered">
<thead>
<tr>
<th id="th_selector"></th>';