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;