scroll table parts
This commit is contained in:
@@ -32,6 +32,10 @@
|
|||||||
<button type="button" class="btn btn-secondary btn-sm ms-2" id="toggleVoiceBtn" style="padding: 0.1rem 0.5rem; font-size: 0.8rem;">
|
<button type="button" class="btn btn-secondary btn-sm ms-2" id="toggleVoiceBtn" style="padding: 0.1rem 0.5rem; font-size: 0.8rem;">
|
||||||
<i class="fas fa-microphone"></i> Voce
|
<i class="fas fa-microphone"></i> Voce
|
||||||
</button>
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-primary btn-sm ms-2" id="showHideImageBtn" style="padding: 0.1rem 0.5rem; font-size: 0.8rem;">
|
||||||
|
<i class="fas fa-eye-slash" style="font-size: 0.8rem;"></i>
|
||||||
|
<i class="fas fa-image ms-1" style="font-size: 0.8rem;"></i>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Seconda riga: +, M, MacroMatrice, Matrice globale, Propaga -->
|
<!-- Seconda riga: +, M, MacroMatrice, Matrice globale, Propaga -->
|
||||||
@@ -44,7 +48,15 @@
|
|||||||
<select id="global-matrice" class="form-control form-control-sm" style="width: 350px !important; margin-right: 10px;"></select>
|
<select id="global-matrice" class="form-control form-control-sm" style="width: 350px !important; margin-right: 10px;"></select>
|
||||||
<button type="button" class="btn btn-primary btn-sm propagate-all-btn" style="padding: 0.1rem 0.5rem; font-size: 0.8rem;"><i class="fas fa-arrow-right"></i> Propaga a tutte</button>
|
<button type="button" class="btn btn-primary btn-sm propagate-all-btn" style="padding: 0.1rem 0.5rem; font-size: 0.8rem;"><i class="fas fa-arrow-right"></i> Propaga a tutte</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="parts-table-scroll">
|
||||||
<table class="table table-striped table-sm" id="partsTable">
|
<table class="table table-striped table-sm" id="partsTable">
|
||||||
|
<colgroup id="partsTableColgroup">
|
||||||
|
<col class="parts-col-num">
|
||||||
|
<col class="parts-col-description">
|
||||||
|
<col class="parts-col-matrice">
|
||||||
|
<col class="parts-col-date">
|
||||||
|
<col class="parts-col-actions">
|
||||||
|
</colgroup>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width: 55px;">Num</th>
|
<th style="width: 55px;">Num</th>
|
||||||
@@ -84,6 +96,7 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<h6>Foto del Campione</h6>
|
<h6>Foto del Campione</h6>
|
||||||
<div style="display: flex; align-items: center; margin-bottom: 10px;">
|
<div style="display: flex; align-items: center; margin-bottom: 10px;">
|
||||||
@@ -290,28 +303,20 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Select delle righe (colonna Matrice) = 150px */
|
/* Select delle righe Matrice: si adatta alla colonna */
|
||||||
.part-matrice {
|
.part-matrice {
|
||||||
width: 300px !important;
|
width: 100% !important;
|
||||||
min-width: 300px !important;
|
min-width: 0 !important;
|
||||||
max-width: 300px !important;
|
max-width: 100% !important;
|
||||||
flex: 0 0 300px !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.part-matrice.select2-hidden-accessible+.select2 {
|
.part-matrice.select2-hidden-accessible+.select2 {
|
||||||
width: 300px !important;
|
width: 100% !important;
|
||||||
min-width: 300px !important;
|
min-width: 0 !important;
|
||||||
max-width: 300px !important;
|
max-width: 100% !important;
|
||||||
flex: 0 0 300px !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 {
|
#partsTable .part-number {
|
||||||
text-align: center;
|
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 */
|
/* rosso */
|
||||||
</style>
|
</style>
|
||||||
@@ -2463,4 +2463,142 @@ $(document).on("click", "#showHideImageBtn", function () {
|
|||||||
"<i class='fas fa-eye' style='font-size: 0.8rem;'></i><i class='fas fa-image ms-1' style='font-size: 0.8rem;'></i>",
|
"<i class='fas fa-eye' style='font-size: 0.8rem;'></i><i class='fas fa-image ms-1' style='font-size: 0.8rem;'></i>",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 <col> quante <th>
|
||||||
|
while ($colgroup.find("col").length < thCount) {
|
||||||
|
$colgroup.append("<col>");
|
||||||
|
}
|
||||||
|
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 = $("<span class='parts-resizer'></span>");
|
||||||
|
$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 <col>, non dal <th>
|
||||||
|
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;
|
||||||
|
})();
|
||||||
|
|||||||
Reference in New Issue
Block a user