diff --git a/public/userarea/gridRenderer.js b/public/userarea/gridRenderer.js index a1d0149..87cc0d1 100644 --- a/public/userarea/gridRenderer.js +++ b/public/userarea/gridRenderer.js @@ -242,7 +242,88 @@ return _pendingFixed[cacheKey]; } + async function refreshDependentFixedFieldsForRow(rowIndex) { + const row = data[rowIndex]; + if (!row) return; + + const clientId = row.idclient || ""; + + // Find fixed fields that depend on idclient + const dependentFields = Object.keys(fixedFieldApiConfig).filter( + (key) => { + return fixedFieldApiConfig[key].dependsOn === "idclient"; + }, + ); + + if (dependentFields.length === 0) return; + + for (const fieldKey of dependentFields) { + // When client changes, the old responsible is no longer reliable + if ( + row.fixedFields && + Object.prototype.hasOwnProperty.call(row.fixedFields, fieldKey) + ) { + row.fixedFields[fieldKey] = ""; + row._dirty = true; + } + + // Reload options for the new client + if (clientId) { + await loadFixedFieldOptions(fieldKey, clientId); + } + } + + // Re-render only this row so ClienteResponsabile select is rebuilt with the new options + renderSingleRow(rowIndex); + + // If the first row client changes, update the top propagation select too + if (rowIndex === 0) { + await refreshTopDependentFixedSelect( + "ClienteResponsabile", + clientId, + ); + } + + updateDirtyIndicator(); + } // ── Custom field dropdown data loading ───────────────────────────────── + async function refreshTopDependentFixedSelect(fieldKey, clientId) { + if (!topContainer || !fieldKey) return; + + const sel = topContainer.querySelector( + `.api-fixed-select[data-fixed-key="${fieldKey}"]`, + ); + + if (!sel) return; + + // Destroy Select2 if already initialized + if ($(sel).hasClass("select2-hidden-accessible")) { + $(sel).select2("destroy"); + } + + sel.innerHTML = ''; + + if (!clientId) { + $(sel).select2({ + placeholder: "Seleziona...", + allowClear: true, + width: "100%", + }); + return; + } + + const items = await loadFixedFieldOptions(fieldKey, clientId); + + items.forEach((item) => { + sel.add(new Option(item.text, item.id)); + }); + + $(sel).select2({ + placeholder: "Seleziona...", + allowClear: true, + width: "100%", + }); + } // Select2 AJAX config factory for SceltaMultipla function sceltaSelect2Config(fieldId) { @@ -886,23 +967,27 @@ } if (config && config.dependsOn) { - // For dependent fields: merge all cached values across all clientIds - const allItems = new Map(); - for (const [key, items] of Object.entries(fixedFieldCache)) { - if (key.startsWith(fieldKey + "_")) { - items.forEach((item) => - allItems.set(String(item.id), item), - ); - } - } + // Dependent fixed fields, for example ClienteResponsabile: + // use the first row client, not all cached clients. + const firstClientId = + data[0]?.idclient || meta.defaultIdclient || ""; + sel.innerHTML = ''; - [...allItems.values()] - .sort((a, b) => - String(a.text).localeCompare(String(b.text), "it", { - sensitivity: "base", - }), - ) - .forEach((item) => sel.add(new Option(item.text, item.id))); + + if (firstClientId) { + const items = + fixedFieldCache[fieldKey + "_" + firstClientId] || []; + + items.forEach((item) => { + sel.add(new Option(item.text, item.id)); + }); + } + + $(sel).select2({ + placeholder: "Seleziona...", + allowClear: true, + width: "100%", + }); } else { const items = fixedFieldCache[fieldKey] || []; sel.innerHTML = ''; @@ -950,6 +1035,8 @@ } else if (colType === "idclient") { data[rowIndex].idclient = value; data[rowIndex]._dirty = true; + + refreshDependentFixedFieldsForRow(rowIndex); } else if (colType === "cliente_fornitore_id") { data[rowIndex].cliente_fornitore_id = value; data[rowIndex]._dirty = true; @@ -1042,8 +1129,37 @@ if (column === "idclient") { data.forEach((row) => { row.idclient = value; + + // Clear dependent fixed fields when client changes + if ( + row.fixedFields && + Object.prototype.hasOwnProperty.call( + row.fixedFields, + "ClienteResponsabile", + ) + ) { + row.fixedFields["ClienteResponsabile"] = ""; + } + row._dirty = true; }); + + // Reload ClienteResponsabile options for the propagated client + if (value) { + loadFixedFieldOptions("ClienteResponsabile", value).then( + () => { + refreshTopDependentFixedSelect( + "ClienteResponsabile", + value, + ); + renderVisibleRows(); + updateDirtyIndicator(); + }, + ); + return; + } else { + refreshTopDependentFixedSelect("ClienteResponsabile", ""); + } } else if (column === "cliente_fornitore_id") { data.forEach((row) => { row.cliente_fornitore_id = value; @@ -1086,6 +1202,8 @@ if (colType === "idclient") { data[rowIndex].idclient = value; data[rowIndex]._dirty = true; + + refreshDependentFixedFieldsForRow(rowIndex); } else if (colType === "cliente_fornitore_id") { data[rowIndex].cliente_fornitore_id = value; data[rowIndex]._dirty = true;