From 813bd66f96e4617c9f841c945dc476915b9e0558 Mon Sep 17 00:00:00 2001 From: solocla Date: Mon, 4 May 2026 12:10:12 +0200 Subject: [PATCH] scroll table parts --- public/userarea/modal_partsTable.php | 184 +++++++++++++++++++-------- public/userarea/partsTable.js | 138 ++++++++++++++++++++ 2 files changed, 268 insertions(+), 54 deletions(-) diff --git a/public/userarea/modal_partsTable.php b/public/userarea/modal_partsTable.php index cb26f7a..2080ebc 100644 --- a/public/userarea/modal_partsTable.php +++ b/public/userarea/modal_partsTable.php @@ -32,6 +32,10 @@ + @@ -44,45 +48,54 @@ - - - - - - - - + + + + + + + + + + + +
NumDescrizioneMatrice - - - - Azioni +
+ + + + + + + + + + + + + + + - - - - - - - - - - - -
NumDescrizioneMatrice + + + + Azioni -
-
- - -
-
- - - - - -
+
+
+ + +
+
+ + + + + +
+
Foto del Campione
@@ -290,28 +303,20 @@ white-space: nowrap; } - /* Select delle righe (colonna Matrice) = 150px */ + /* Select delle righe Matrice: si adatta alla colonna */ .part-matrice { - width: 300px !important; - min-width: 300px !important; - max-width: 300px !important; - flex: 0 0 300px !important; + width: 100% !important; + min-width: 0 !important; + max-width: 100% !important; } .part-matrice.select2-hidden-accessible+.select2 { - width: 300px !important; - min-width: 300px !important; - max-width: 300px !important; - flex: 0 0 300px !important; + width: 100% !important; + min-width: 0 !important; + max-width: 100% !important; } - /* Colonna Descrizione (2ª colonna) = 420px */ - #partsTable th:nth-child(2), - #partsTable td:nth-child(2) { - width: 300px !important; - min-width: 300px !important; - max-width: 300px !important; - } + #partsTable .part-number { text-align: center; @@ -516,6 +521,77 @@ } } + /* Resizable parts table - stable */ + .parts-table-scroll { + width: 100%; + overflow-x: auto; + overflow-y: visible; + contain: inline-size; + } + + #partsTable { + table-layout: fixed !important; + width: max-content !important; + min-width: unset !important; + } + + #partsTable col.parts-col-num { + width: 55px; + } + + #partsTable col.parts-col-description { + width: 320px; + } + + #partsTable col.parts-col-matrice { + width: 360px; + } + + #partsTable col.parts-col-date { + width: 150px; + } + + #partsTable col.parts-col-actions { + width: 230px; + } + + #partsTable th, + #partsTable td { + position: relative; + box-sizing: border-box; + } + + #partsTable th { + user-select: none; + } + + #partsTable th .parts-resizer { + position: absolute; + top: 0; + right: 0; + width: 9px; + height: 100%; + cursor: col-resize; + z-index: 50; + background: rgba(108, 117, 125, 0.12); + border-right: 1px solid rgba(108, 117, 125, 0.45); + } + + #partsTable th .parts-resizer:hover { + background: rgba(108, 117, 125, 0.25); + border-right: 2px solid rgba(73, 80, 87, 0.7); + } + + #partsTable td { + overflow: hidden; + text-overflow: ellipsis; + } + + #partsTable td input, + #partsTable td select, + #partsTable td .select2-container { + max-width: 100% !important; + } /* rosso */ \ No newline at end of file diff --git a/public/userarea/partsTable.js b/public/userarea/partsTable.js index b8b148a..2ed3109 100644 --- a/public/userarea/partsTable.js +++ b/public/userarea/partsTable.js @@ -2463,4 +2463,142 @@ $(document).on("click", "#showHideImageBtn", function () { "", ); } + + if (typeof window.applyPartsColumnWidths === "function") { + setTimeout(window.applyPartsColumnWidths, 150); + } }); +// =================== +// RESIZABLE PARTS TABLE COLUMNS - FIXED COLGROUP VERSION +// =================== +(function () { + // Larghezze default per indice colonna (0-based) + const defaultWidths = [55, 320, 360, 150, 230]; + const savedWidths = [...defaultWidths]; + + function getColgroup() { + return $("#partsTableColgroup"); + } + + function syncColgroupToHeaders() { + const $table = $("#partsTable"); + const $ths = $table.find("thead tr:first th"); + const $colgroup = getColgroup(); + const thCount = $ths.length; + + // Assicura che ci siano esattamente tante quante + while ($colgroup.find("col").length < thCount) { + $colgroup.append(""); + } + while ($colgroup.find("col").length > thCount) { + $colgroup.find("col:last").remove(); + } + + // Applica le larghezze salvate + $colgroup.find("col").each(function (i) { + const w = savedWidths[i] !== undefined ? savedWidths[i] : 150; + $(this).css("width", w + "px"); + }); + + // Imposta larghezza totale della tabella = somma colonne (evita reflow) + const total = savedWidths.slice(0, thCount).reduce((a, b) => a + b, 0); + $table.css("width", total + "px"); + } + + function applyColumnWidth(colIndex, newWidth) { + const w = Math.max(40, Math.round(newWidth)); + savedWidths[colIndex] = w; + + const $col = getColgroup().find("col").eq(colIndex); + if ($col.length) { + $col.css("width", w + "px"); + } + + // Aggiorna larghezza totale tabella senza toccare le altre colonne + const thCount = $("#partsTable thead tr:first th").length; + const total = savedWidths.slice(0, thCount).reduce((a, b) => a + b, 0); + $("#partsTable").css("width", total + "px"); + } + + function addResizers() { + const $table = $("#partsTable"); + if (!$table.length) return; + + $table.find("thead tr:first th").each(function (colIndex) { + const $th = $(this); + + // Salta colonna Num (indice 0) — non ridimensionabile + if (colIndex === 0) return; + + // Non aggiungere due volte + if ($th.find(".parts-resizer").length) return; + + const $resizer = $(""); + $th.css("position", "relative"); // necessario per il posizionamento assoluto + $th.append($resizer); + + $resizer.on("mousedown", function (e) { + e.preventDefault(); + e.stopPropagation(); + + const startX = e.pageX; + // Leggi la larghezza ESATTA dalla , non dal + const startWidth = + savedWidths[colIndex] !== undefined + ? savedWidths[colIndex] + : parseInt( + getColgroup() + .find("col") + .eq(colIndex) + .css("width"), + 10, + ) || 150; + + $("body") + .css("user-select", "none") + .css("cursor", "col-resize"); + + $(document).on("mousemove.partsResize", function (ev) { + const delta = ev.pageX - startX; + applyColumnWidth(colIndex, startWidth + delta); + }); + + $(document).on("mouseup.partsResize", function () { + $("body").css("user-select", "").css("cursor", ""); + $(document).off(".partsResize"); + }); + }); + }); + } + + function init() { + syncColgroupToHeaders(); + addResizers(); + } + + // Init al primo show del modale + $(document).on("shown.bs.modal", "#partsModal", function () { + setTimeout(init, 120); + }); + + // Re-init dopo ogni AJAX (nuove righe, caricamenti) + $(document).ajaxComplete(function () { + if ($("#partsModal").hasClass("show")) { + setTimeout(syncColgroupToHeaders, 200); + setTimeout(addResizers, 220); + } + }); + + // Re-init dopo aggiunta/rimozione righe + $(document).on( + "click", + ".add-row-global, .add-mix-global, .add-mix-row, .remove-row, #renumberPartsBtn, #clonePartsBtn", + function () { + setTimeout(syncColgroupToHeaders, 120); + setTimeout(addResizers, 140); + }, + ); + + window.initPartsResizableColumns = init; + window.applyPartsColumnWidths = syncColgroupToHeaders; +})();