fix render gird for doppi apici
This commit is contained in:
@@ -36,6 +36,15 @@
|
|||||||
return d.innerHTML;
|
return d.innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function escAttr(str) {
|
||||||
|
if (str === null || str === undefined) return "";
|
||||||
|
return String(str)
|
||||||
|
.replace(/&/g, "&")
|
||||||
|
.replace(/"/g, """)
|
||||||
|
.replace(/'/g, "'")
|
||||||
|
.replace(/</g, "<")
|
||||||
|
.replace(/>/g, ">");
|
||||||
|
}
|
||||||
function getDetailValue(rowIndex, mappingId) {
|
function getDetailValue(rowIndex, mappingId) {
|
||||||
return data[rowIndex].details[String(mappingId)] ?? "";
|
return data[rowIndex].details[String(mappingId)] ?? "";
|
||||||
}
|
}
|
||||||
@@ -519,7 +528,7 @@
|
|||||||
case "tested_component":
|
case "tested_component":
|
||||||
div.style.overflow = "visible";
|
div.style.overflow = "visible";
|
||||||
div.innerHTML = `<div style="display:flex; align-items:center; gap:4px; width:100%; height:100%;">
|
div.innerHTML = `<div style="display:flex; align-items:center; gap:4px; width:100%; height:100%;">
|
||||||
<input type="text" class="cell-input manual-input tested-component-input" value="${esc(row.tested_component || "")}" style="flex:1; min-width:0; height:28px;">
|
<input type="text" class="cell-input manual-input tested-component-input" value="${escAttr(row.tested_component || "")}" style="flex:1; min-width:0; height:28px;">
|
||||||
<button type="button" class="add-part-btn btn btn-sm btn-primary" data-row="${rowIndex}" data-iddatadb="${row.iddatadb}" style="display:inline-flex; align-items:center; justify-content:center; min-width:28px; width:28px; height:28px; padding:0; font-size:12px; flex-shrink:0; text-align:center;">
|
<button type="button" class="add-part-btn btn btn-sm btn-primary" data-row="${rowIndex}" data-iddatadb="${row.iddatadb}" style="display:inline-flex; align-items:center; justify-content:center; min-width:28px; width:28px; height:28px; padding:0; font-size:12px; flex-shrink:0; text-align:center;">
|
||||||
<i class="fas fa-plus" style="margin:0; padding:0;"></i>
|
<i class="fas fa-plus" style="margin:0; padding:0;"></i>
|
||||||
</button>
|
</button>
|
||||||
@@ -565,7 +574,7 @@
|
|||||||
const cls = col.isManual ? "manual-input" : "auto-input";
|
const cls = col.isManual ? "manual-input" : "auto-input";
|
||||||
const reqCls = col.isRequired ? " required-input" : "";
|
const reqCls = col.isRequired ? " required-input" : "";
|
||||||
const req = col.isRequired ? " required" : "";
|
const req = col.isRequired ? " required" : "";
|
||||||
const v = esc(value);
|
const v = escAttr(value);
|
||||||
|
|
||||||
if (col.dataType === "SceltaMultipla") {
|
if (col.dataType === "SceltaMultipla") {
|
||||||
const options = buildDropdownOptionsHTML(col.fieldId, value);
|
const options = buildDropdownOptionsHTML(col.fieldId, value);
|
||||||
@@ -590,7 +599,7 @@
|
|||||||
if (col.dataType === "DATE") {
|
if (col.dataType === "DATE") {
|
||||||
const reqCls = col.isRequired ? " required-input" : "";
|
const reqCls = col.isRequired ? " required-input" : "";
|
||||||
const req = col.isRequired ? " required" : "";
|
const req = col.isRequired ? " required" : "";
|
||||||
return `<input type="text" class="cell-input date-picker manual-input${reqCls} fixed-input" data-fixed-key="${col.key}" value="${esc(value)}"${req}>`;
|
return `<input type="text" class="cell-input date-picker manual-input${reqCls} fixed-input" data-fixed-key="${escAttr(col.key)}" value="${escAttr(value)}"${req}>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client-sourced fields → AJAX Select2 (like idclient)
|
// Client-sourced fields → AJAX Select2 (like idclient)
|
||||||
@@ -603,7 +612,7 @@
|
|||||||
const label = clientNameCache[value] || value;
|
const label = clientNameCache[value] || value;
|
||||||
opts += `<option value="${esc(String(value))}" selected>${esc(String(label))}</option>`;
|
opts += `<option value="${esc(String(value))}" selected>${esc(String(label))}</option>`;
|
||||||
}
|
}
|
||||||
return `<select class="cell-input manual-input fixed-input searchable-client api-fixed-select${reqCls}" data-fixed-key="${col.key}" data-current-value="${esc(value)}"${req}>${opts}</select>`;
|
return `<select class="cell-input manual-input fixed-input searchable-client api-fixed-select${reqCls}" data-fixed-key="${escAttr(col.key)}" data-current-value="${escAttr(value)}"${req}>${opts}</select>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select — build from cache
|
// Select — build from cache
|
||||||
@@ -621,7 +630,7 @@
|
|||||||
|
|
||||||
const reqCls = col.isRequired ? " required-input" : "";
|
const reqCls = col.isRequired ? " required-input" : "";
|
||||||
const req = col.isRequired ? " required" : "";
|
const req = col.isRequired ? " required" : "";
|
||||||
return `<select class="cell-input manual-input fixed-input ${selectClass}${reqCls}" data-fixed-key="${col.key}" data-current-value="${esc(value)}"${req}>${options}</select>`;
|
return `<select class="cell-input manual-input fixed-input ${selectClass}${reqCls}" data-fixed-key="${escAttr(col.key)}" data-current-value="${escAttr(value)}"${req}>${options}</select>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildDropdownOptionsHTML(fieldId, selectedValue) {
|
function buildDropdownOptionsHTML(fieldId, selectedValue) {
|
||||||
@@ -826,6 +835,75 @@
|
|||||||
flatpickr(this, { dateFormat: "Y-m-d", allowInput: true });
|
flatpickr(this, { dateFormat: "Y-m-d", allowInput: true });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
function getInputTextWidth(input) {
|
||||||
|
const span = document.createElement("span");
|
||||||
|
const style = window.getComputedStyle(input);
|
||||||
|
|
||||||
|
span.style.position = "absolute";
|
||||||
|
span.style.visibility = "hidden";
|
||||||
|
span.style.whiteSpace = "pre";
|
||||||
|
span.style.font = style.font;
|
||||||
|
span.style.fontSize = style.fontSize;
|
||||||
|
span.style.fontFamily = style.fontFamily;
|
||||||
|
span.style.fontWeight = style.fontWeight;
|
||||||
|
span.textContent = input.value || input.placeholder || "";
|
||||||
|
|
||||||
|
document.body.appendChild(span);
|
||||||
|
|
||||||
|
const width = span.offsetWidth + 60;
|
||||||
|
|
||||||
|
document.body.removeChild(span);
|
||||||
|
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
function autoExpandColumnFromInput(input) {
|
||||||
|
if (!input) return;
|
||||||
|
|
||||||
|
const cell = input.closest(".grid-cell");
|
||||||
|
if (!cell || !cell.dataset.index) return;
|
||||||
|
|
||||||
|
const columnIndex = parseInt(cell.dataset.index, 10);
|
||||||
|
if (!columnIndex) return;
|
||||||
|
|
||||||
|
const wantedWidth = Math.max(120, getInputTextWidth(input));
|
||||||
|
const currentWidth = cell.offsetWidth || 0;
|
||||||
|
|
||||||
|
// Only expand, do not shrink automatically
|
||||||
|
if (wantedWidth <= currentWidth) return;
|
||||||
|
|
||||||
|
const newWidth = Math.min(wantedWidth, 900);
|
||||||
|
|
||||||
|
const header = document.querySelector(
|
||||||
|
`.grid-header[data-index="${columnIndex}"]`,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (header) {
|
||||||
|
header.style.flex = `0 0 ${newWidth}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const topCell = document.querySelector(
|
||||||
|
`.grid-top .grid-cell:nth-child(${columnIndex + 1})`,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (topCell) {
|
||||||
|
topCell.style.flex = `0 0 ${newWidth}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cells = document.querySelectorAll(
|
||||||
|
`.grid-row .grid-cell[data-index="${columnIndex}"]`,
|
||||||
|
);
|
||||||
|
|
||||||
|
cells.forEach((c) => {
|
||||||
|
c.style.flex = `0 0 ${newWidth}px`;
|
||||||
|
});
|
||||||
|
|
||||||
|
const colPos = columnIndex - 1;
|
||||||
|
|
||||||
|
if (columns[colPos]) {
|
||||||
|
columns[colPos].width = newWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function syncVisibleRowsToGridData() {
|
function syncVisibleRowsToGridData() {
|
||||||
if (!rowContainer) return;
|
if (!rowContainer) return;
|
||||||
@@ -1127,6 +1205,10 @@
|
|||||||
const cell = e.target.closest(".grid-cell");
|
const cell = e.target.closest(".grid-cell");
|
||||||
if (!cell || !cell.dataset.row) return;
|
if (!cell || !cell.dataset.row) return;
|
||||||
|
|
||||||
|
if (e.target.classList.contains("cell-input")) {
|
||||||
|
autoExpandColumnFromInput(e.target);
|
||||||
|
}
|
||||||
|
|
||||||
const rowIndex = parseInt(cell.dataset.row, 10);
|
const rowIndex = parseInt(cell.dataset.row, 10);
|
||||||
const colType = cell.dataset.colType;
|
const colType = cell.dataset.colType;
|
||||||
|
|
||||||
@@ -1138,6 +1220,16 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
rowContainer.addEventListener("focusin", function (e) {
|
||||||
|
if (!e.target.classList.contains("cell-input")) return;
|
||||||
|
|
||||||
|
autoExpandColumnFromInput(e.target);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
autoExpandColumnFromInput(e.target);
|
||||||
|
}, 50);
|
||||||
|
});
|
||||||
|
|
||||||
// Persist tested_component before clicking +
|
// Persist tested_component before clicking +
|
||||||
document.addEventListener("mousedown", function (e) {
|
document.addEventListener("mousedown", function (e) {
|
||||||
const btn = e.target.closest(".add-part-btn");
|
const btn = e.target.closest(".add-part-btn");
|
||||||
|
|||||||
Reference in New Issue
Block a user