fixed column size final

This commit is contained in:
Claudio 2026-02-18 10:04:27 +01:00
parent bdc4e0e60c
commit 73dd8f4ce8

View File

@ -1723,60 +1723,13 @@ function fixedDefaultValue(array $f): string
}
});
});
// === AUTO WIDTH BY HEADER LABEL (initial only) ===
function autoFitColumnsByHeader({
minPx = 150,
maxPx = 380,
extraPx = 40, // padding + resizer + un po' di aria
ignoreIndexes = [] // es: [1,2] se vuoi escludere main/client ecc
} = {}) {
// misura testo in modo affidabile
function measureTextWidth(text, font) {
const canvas = measureTextWidth._canvas || (measureTextWidth._canvas = document.createElement("canvas"));
const ctx = canvas.getContext("2d");
ctx.font = font;
return ctx.measureText(text).width;
}
// prendi tutti gli header con data-index
const headers = document.querySelectorAll(".grid-row .grid-header[data-index]");
headers.forEach(header => {
const idx = parseInt(header.getAttribute("data-index"), 10);
if (!idx || ignoreIndexes.includes(idx)) return;
// se lutente ha già ridimensionato manualmente, non tocchiamo più
if (header.dataset.userResized === "1") return;
// testo label pulito (toglie il resizer dal calcolo)
const text = (header.childNodes[0]?.textContent || header.textContent || "").trim();
// font reale dell'header per la misura
const cs = window.getComputedStyle(header);
const font = `${cs.fontStyle} ${cs.fontVariant} ${cs.fontWeight} ${cs.fontSize} / ${cs.lineHeight} ${cs.fontFamily}`;
const wText = measureTextWidth(text, font);
const desired = Math.max(minPx, Math.min(maxPx, Math.ceil(wText + extraPx)));
// applica a header + cells + top cells
const selHeader = `.grid-header[data-index="${idx}"]`;
const selCell = `.grid-cell[data-index="${idx}"]`;
const selTop = `.grid-top .grid-cell[data-index="${idx}"]`;
document.querySelectorAll(selHeader).forEach(el => el.style.flex = `0 0 ${desired}px`);
document.querySelectorAll(selCell).forEach(el => el.style.flex = `0 0 ${desired}px`);
document.querySelectorAll(selTop).forEach(el => el.style.flex = `0 0 ${desired}px`);
});
}
requestAnimationFrame(() => {
setTimeout(() => {
autoFitColumnsByHeader({
autoFitColumnsByHeaderKeepWider({
minPx: 150,
maxPx: 380,
extraPx: 40,
ignoreIndexes: []
ignoreIndexes: [] // es: ['2'] se vuoi escludere Client
});
}, 50);
});
@ -1806,8 +1759,6 @@ function fixedDefaultValue(array $f): string
const cells = document.querySelectorAll(`.grid-cell[data-index="${columnIndex}"]`);
const topCells = document.querySelectorAll(`.grid-top .grid-cell[data-index="${columnIndex}"]`);
headers.forEach(header => header.style.flex = `0 0 ${newWidth}px`);
headers.forEach(header => header.dataset.userResized = "1");
cells.forEach(cell => cell.style.flex = `0 0 ${newWidth}px`);
topCells.forEach(cell => cell.style.flex = `0 0 ${newWidth}px`);
}
@ -1894,17 +1845,9 @@ function fixedDefaultValue(array $f): string
populateDropdowns();
});
autoFitColumnsByHeader({
minPx: 150,
maxPx: 380,
extraPx: 40,
ignoreIndexes: [] // lascia vuoto per applicare a tutte le colonne indicizzate
});
document.addEventListener("DOMContentLoaded", function() {
let clientData = [];
async function loadClients(retryCount = 0, maxRetries = 3) {
const clientLoadingStatus = document.getElementById("clientLoadingStatus");
try {
@ -2489,6 +2432,64 @@ function fixedDefaultValue(array $f): string
}
});
</script>
<script>
function autoFitColumnsByHeaderKeepWider({
minPx = 150,
maxPx = 380, // limite solo per l'auto-fit (NON riduce se già più largo)
extraPx = 40,
ignoreIndexes = []
} = {}) {
// misura testo con stesso font dell'header
const measurer = document.createElement('span');
measurer.style.position = 'absolute';
measurer.style.visibility = 'hidden';
measurer.style.whiteSpace = 'nowrap';
measurer.style.left = '-99999px';
measurer.style.top = '-99999px';
document.body.appendChild(measurer);
const headers = document.querySelectorAll('.grid-row .grid-header[data-index]');
headers.forEach(header => {
const idx = header.getAttribute('data-index');
if (!idx || ignoreIndexes.includes(String(idx))) return;
// testo header senza il resizer
const clone = header.cloneNode(true);
clone.querySelectorAll('.resizer').forEach(r => r.remove());
const label = (clone.textContent || '').replace(/\s+/g, ' ').trim();
// misura
const headerStyle = window.getComputedStyle(header);
measurer.style.font = headerStyle.font; // importante: usa stesso font completo
measurer.textContent = label;
let desired = Math.ceil(measurer.offsetWidth + extraPx);
desired = Math.max(minPx, desired);
desired = Math.min(maxPx, desired); // clamp SOLO della misura calcolata
// larghezza corrente (flex-basis), fallback a offsetWidth
const cs = window.getComputedStyle(header);
let current = parseFloat(cs.flexBasis);
if (Number.isNaN(current) || !current) current = header.offsetWidth;
// ✅ non restringere mai
const finalWidth = Math.max(current, desired);
// applica a header + celle + top
const targets = document.querySelectorAll(
`.grid-header[data-index="${idx}"], .grid-cell[data-index="${idx}"], .grid-top .grid-cell[data-index="${idx}"]`
);
targets.forEach(el => {
el.style.flex = `0 0 ${finalWidth}px`;
});
});
measurer.remove();
}
</script>
<!-- Modale di conferma per l'esportazione -->
<div class="modal fade" id="exportConfirmModal" tabindex="-1" aria-labelledby="exportConfirmModalLabel" aria-hidden="true">
<div class="modal-dialog">