fixed matrici reload

This commit is contained in:
2026-10-22 17:34:51 +02:00
parent 8d1f7cb35b
commit a499e7acbd
+211 -39
View File
@@ -64,6 +64,7 @@ function revisionLabel($rev)
<!-- DataTables --> <!-- DataTables -->
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/dataTables.bootstrap5.min.css"> <link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/dataTables.bootstrap5.min.css">
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script> <script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/dataTables.bootstrap5.min.js"></script>
<!-- Select2 --> <!-- Select2 -->
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" /> <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
@@ -125,6 +126,57 @@ function revisionLabel($rev)
text-align: center; text-align: center;
} }
/* paginazione tabella: pulsanti distanziati e cliccabili */
.dataTables_wrapper .dataTables_paginate {
margin-top: 12px;
}
.dataTables_wrapper .dataTables_paginate .pagination {
flex-wrap: wrap;
gap: 4px;
justify-content: flex-end;
}
.dataTables_wrapper .dataTables_paginate .page-link,
.dataTables_wrapper .dataTables_paginate a.paginate_button {
display: inline-block;
min-width: 40px;
padding: 8px 12px;
margin: 0 2px;
border-radius: 10px !important;
border: 1px solid #dee2e6;
text-align: center;
cursor: pointer;
user-select: none;
}
.dataTables_wrapper .dataTables_paginate .page-item.active .page-link,
.dataTables_wrapper .dataTables_paginate a.paginate_button.current {
background: #198754;
border-color: #198754;
color: #fff;
}
.dataTables_wrapper .dataTables_paginate .page-item.disabled .page-link,
.dataTables_wrapper .dataTables_paginate a.paginate_button.disabled {
opacity: .5;
cursor: default;
}
@keyframes rowFlash {
from {
background-color: #fde68a;
}
to {
background-color: transparent;
}
}
#tabellaMatrici tbody tr.row-flash>td {
animation: rowFlash 1.8s ease-out;
}
.action-btn { .action-btn {
border: none; border: none;
background: none; background: none;
@@ -1371,10 +1423,109 @@ function revisionLabel($rev)
$("#filePreviewContainer").html(html); $("#filePreviewContainer").html(html);
const modal = new bootstrap.Modal(document.getElementById('filePreviewModal')); const modal = bootstrap.Modal.getOrCreateInstance(document.getElementById('filePreviewModal'));
modal.show(); modal.show();
} }
/* ---------- aggiornamento tabella senza ricaricare la pagina ----------
* Dopo un salvataggio rilegge la pagina in background e aggiorna solo le righe cambiate:
* ricerca, pagina e ordinamento restano dove l'utente li aveva lasciati. */
function rowId(tr) {
const b = tr && tr.querySelector('.action-btn.edit[data-id]');
return b ? String(b.getAttribute('data-id')) : null;
}
function hideTooltips() {
document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(el => {
const t = bootstrap.Tooltip.getInstance(el);
if (t) t.hide();
});
document.querySelectorAll('.tooltip').forEach(el => el.remove());
}
function toastOk(msg) {
Swal.fire({
toast: true,
position: 'top-end',
icon: 'success',
title: msg || 'Salvato',
showConfirmButton: false,
timer: 1600
});
}
function flashRow(tr) {
if (!tr) return;
tr.classList.remove('row-flash');
void tr.offsetWidth;
tr.classList.add('row-flash');
}
// focusId: riga da evidenziare; se è nuova e non visibile con il filtro attuale, cerco il suo nome
function refreshTable(focusId) {
const dt = $('#tabellaMatrici').DataTable();
return fetch(location.href, {
cache: 'no-store',
credentials: 'same-origin'
})
.then(r => r.text())
.then(html => {
const doc = new DOMParser().parseFromString(html, 'text/html');
const fresh = {};
doc.querySelectorAll('#tabellaMatrici tbody tr').forEach(tr => {
const id = rowId(tr);
if (id) fresh[id] = tr;
});
if (!Object.keys(fresh).length) return location.reload(); // risposta inattesa: ricarico come prima
hideTooltips();
const seen = {};
const added = [];
const gone = [];
dt.rows().every(function() {
const tr = this.node();
const id = rowId(tr);
if (!id || !fresh[id]) { // eliminata (o riga "Nessuna matrice presente")
gone.push(tr);
return;
}
seen[id] = true;
const nw = fresh[id];
if (tr.innerHTML !== nw.innerHTML) {
Array.from(nw.cells).forEach((td, i) => {
const old = tr.cells[i];
if (!old) return;
old.innerHTML = td.innerHTML;
if (td.hasAttribute('title')) old.setAttribute('title', td.getAttribute('title'));
});
this.invalidate('dom');
flashRow(tr);
}
});
gone.forEach(tr => dt.row(tr).remove());
Object.keys(fresh).forEach(id => {
if (!seen[id]) {
const node = document.importNode(fresh[id], true);
dt.row.add(node);
added.push(node);
}
});
dt.draw(false);
added.forEach(flashRow);
// matrice nuova: la mostro (filtrando per il suo nome se non è in pagina)
if (focusId && fresh[focusId]) {
const node = dt.rows().nodes().toArray().find(tr => rowId(tr) === String(focusId));
if (node && !document.body.contains(node)) {
const nome = (fresh[focusId].cells[1] && fresh[focusId].cells[1].textContent.trim()) || '';
if (nome) dt.search(nome).draw();
}
flashRow(node);
}
})
.catch(() => location.reload());
}
$(document).ready(function() { $(document).ready(function() {
$('#tabellaMatrici').DataTable({ $('#tabellaMatrici').DataTable({
@@ -1477,12 +1628,24 @@ function revisionLabel($rev)
}) })
.then(r => r.json()) .then(r => r.json())
.then(data => { .then(data => {
Swal.fire({ if (!data.success) {
icon: data.success ? "success" : "error", Swal.fire({
title: data.success ? "Salvato!" : "Errore", icon: "error",
text: data.message || "" title: "Errore",
}).then(() => location.reload()); text: data.message || ""
}); });
return;
}
bootstrap.Modal.getOrCreateInstance(document.getElementById('addMatriceModal')).hide();
toastOk(data.message || "Matrice salvata");
// id della matrice nuova (se il salvataggio lo restituisce), altrimenti quella modificata
refreshTable(data.id || data.idmatrice || id || null);
})
.catch(() => Swal.fire({
icon: "error",
title: "Errore",
text: "Errore di comunicazione con il server"
}));
}); });
$(document).on("click", ".delete", function() { $(document).on("click", ".delete", function() {
@@ -1500,17 +1663,26 @@ function revisionLabel($rev)
fetch("delete_matrice.php?id=" + encodeURIComponent(id)) fetch("delete_matrice.php?id=" + encodeURIComponent(id))
.then(r => r.json()) .then(r => r.json())
.then(data => { .then(data => {
Swal.fire({ if (!data.success) {
icon: data.success ? "success" : "error", Swal.fire({
title: data.success ? "Eliminata!" : "Errore", icon: "error",
text: data.message || "" title: "Errore",
}).then(() => location.reload()); text: data.message || ""
});
return;
}
toastOk(data.message || "Matrice eliminata");
refreshTable();
}); });
} }
}); });
}); });
document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(el => new bootstrap.Tooltip(el)); new bootstrap.Tooltip(document.body, {
selector: '[data-bs-toggle="tooltip"]',
trigger: 'hover'
});
document.addEventListener('show.bs.modal', hideTooltips);
$('#ml_linee').select2({ $('#ml_linee').select2({
theme: 'bootstrap-5', theme: 'bootstrap-5',
@@ -1547,7 +1719,7 @@ function revisionLabel($rev)
}); });
$sel.val((data.selected_ids || []).map(String)).trigger("change"); $sel.val((data.selected_ids || []).map(String)).trigger("change");
new bootstrap.Modal(document.getElementById('matriceLineeModal')).show(); bootstrap.Modal.getOrCreateInstance(document.getElementById('matriceLineeModal')).show();
}); });
}); });
@@ -1565,16 +1737,17 @@ function revisionLabel($rev)
}) })
.then(r => r.json()) .then(r => r.json())
.then(data => { .then(data => {
Swal.fire({ if (!data.success) {
icon: data.success ? "success" : "error", Swal.fire({
title: data.success ? "Salvato!" : "Errore", icon: "error",
text: data.message || "" title: "Errore",
}).then(() => { text: data.message || ""
if (data.success) { });
bootstrap.Modal.getInstance(document.getElementById('matriceLineeModal')).hide(); return;
location.reload(); }
} bootstrap.Modal.getOrCreateInstance(document.getElementById('matriceLineeModal')).hide();
}); toastOk(data.message || "Linee salvate");
refreshTable(idmatrice);
}); });
}); });
@@ -1599,9 +1772,7 @@ function revisionLabel($rev)
const loadingOption = new Option("Caricamento mescole...", "", false, false); const loadingOption = new Option("Caricamento mescole...", "", false, false);
$sel.append(loadingOption).trigger("change"); $sel.append(loadingOption).trigger("change");
const modalEl = document.getElementById('matriceMescoleModal'); bootstrap.Modal.getOrCreateInstance(document.getElementById('matriceMescoleModal')).show();
const modal = new bootstrap.Modal(modalEl);
modal.show();
fetch("get_matrice_mescole.php?id=" + encodeURIComponent(idmatrice)) fetch("get_matrice_mescole.php?id=" + encodeURIComponent(idmatrice))
.then(r => { .then(r => {
@@ -1652,16 +1823,17 @@ function revisionLabel($rev)
}) })
.then(r => r.json()) .then(r => r.json())
.then(data => { .then(data => {
Swal.fire({ if (!data.success) {
icon: data.success ? "success" : "error", Swal.fire({
title: data.success ? "Salvato!" : "Errore", icon: "error",
text: data.message || "" title: "Errore",
}).then(() => { text: data.message || ""
if (data.success) { });
bootstrap.Modal.getInstance(document.getElementById('matriceMescoleModal')).hide(); return;
location.reload(); }
} bootstrap.Modal.getOrCreateInstance(document.getElementById('matriceMescoleModal')).hide();
}); toastOk(data.message || "Mescole salvate");
refreshTable(idmatrice);
}); });
}); });
@@ -1678,7 +1850,7 @@ function revisionLabel($rev)
$("#mlm_list").html(items.map(x => `<span class="badge bg-secondary me-1 mb-1">${escapeHtml(x)}</span>`).join('')); $("#mlm_list").html(items.map(x => `<span class="badge bg-secondary me-1 mb-1">${escapeHtml(x)}</span>`).join(''));
} }
new bootstrap.Modal(document.getElementById('mescoleListModal')).show(); bootstrap.Modal.getOrCreateInstance(document.getElementById('mescoleListModal')).show();
}); });
$(document).on("click", ".files", function() { $(document).on("click", ".files", function() {
@@ -1692,7 +1864,7 @@ function revisionLabel($rev)
renderSelectedAttachments(); renderSelectedAttachments();
loadExistingAttachments(idmatrice); loadExistingAttachments(idmatrice);
new bootstrap.Modal(document.getElementById('matriceFilesModal')).show(); bootstrap.Modal.getOrCreateInstance(document.getElementById('matriceFilesModal')).show();
}); });
$("#mf_pick_files_btn, #attachmentsDropzone").on("click", function() { $("#mf_pick_files_btn, #attachmentsDropzone").on("click", function() {