diff --git a/frappe/public/js/frappe/form/grid_row.js b/frappe/public/js/frappe/form/grid_row.js index 61905990fe..472e8a1780 100644 --- a/frappe/public/js/frappe/form/grid_row.js +++ b/frappe/public/js/frappe/form/grid_row.js @@ -1,5 +1,11 @@ import GridRowForm from "./grid_row_form"; +const DEPENDENCY_PROPERTIES = [ + { expr: "depends_on", prop: "hidden_due_to_dependency", negate: true }, + { expr: "mandatory_depends_on", prop: "reqd", negate: false }, + { expr: "read_only_depends_on", prop: "read_only", negate: false }, +]; + export default class GridRow { constructor(opts) { this.on_grid_fields_dict = {}; @@ -792,27 +798,32 @@ export default class GridRow { } set_dependant_property(df) { - if (df.depends_on) { - df.hidden_due_to_dependency = !this.evaluate_depends_on_value(df.depends_on) ? 1 : 0; + let changed = false; + + for (const { expr, prop, negate } of DEPENDENCY_PROPERTIES) { + if (df[expr]) { + const result = this.evaluate_depends_on_value(df[expr]); + const new_value = (negate ? !result : result) ? 1 : 0; + changed ||= df[prop] !== new_value; + df[prop] = new_value; + } } - if (df.mandatory_depends_on) { - df.reqd = this.evaluate_depends_on_value(df.mandatory_depends_on) ? 1 : 0; - } - - if (df.read_only_depends_on) { - df.read_only = this.evaluate_depends_on_value(df.read_only_depends_on) ? 1 : 0; - } + return changed; } refresh_dependency() { - // re-evaluate all fields that have dependency expressions - this.docfields.forEach((df) => { - if (df.depends_on || df.mandatory_depends_on || df.read_only_depends_on) { - this.set_dependant_property(df); + // re-evaluate dependency expressions of visible columns + // refresh if some property changed + let changed = false; + for (const { df } of this.columns_list) { + if (DEPENDENCY_PROPERTIES.some((d) => df[d.expr])) { + changed ||= this.set_dependant_property(df); } - }); - this.refresh(); + } + if (changed) { + this.refresh(); + } } evaluate_depends_on_value(expression) { diff --git a/frappe/public/js/frappe/form/layout.js b/frappe/public/js/frappe/form/layout.js index aad7c8c45a..c0da70f26e 100644 --- a/frappe/public/js/frappe/form/layout.js +++ b/frappe/public/js/frappe/form/layout.js @@ -529,12 +529,6 @@ frappe.ui.form.Layout = class Layout { } } - refresh_section_count() { - this.wrapper.find(".section-count-label:visible").each(function (i) { - $(this).html(i + 1); - }); - } - setup_events() { let last_scroll = 0; let tabs_list = $(".form-tabs-list"); @@ -724,40 +718,16 @@ frappe.ui.form.Layout = class Layout { build dependants' dictionary */ - let has_dep = false; - const fields = this.fields_list.concat(this.tabs); - for (let fkey in fields) { - let f = fields[fkey]; - if (f.df.depends_on || f.df.mandatory_depends_on || f.df.read_only_depends_on) { - has_dep = true; - break; - } - } - - if (!has_dep) return; - // show / hide based on values - for (let i = fields.length - 1; i >= 0; i--) { - let f = fields[i]; - f.guardian_has_value = true; + for (const f of fields) { if (f.df.depends_on) { - // evaluate guardian + const should_hide = !this.evaluate_depends_on_value(f.df.depends_on); - f.guardian_has_value = this.evaluate_depends_on_value(f.df.depends_on); - - // show / hide - if (f.guardian_has_value) { - if (f.df.hidden_due_to_dependency) { - f.df.hidden_due_to_dependency = false; - f.refresh(); - } - } else { - if (!f.df.hidden_due_to_dependency) { - f.df.hidden_due_to_dependency = true; - f.refresh(); - } + if (f.df.hidden_due_to_dependency !== should_hide) { + f.df.hidden_due_to_dependency = should_hide; + f.refresh(); } } @@ -772,9 +742,13 @@ frappe.ui.form.Layout = class Layout { "read_only" ); } - } - this.refresh_section_count(); + if (f.df.fieldtype === "Table") { + for (const row of f.grid?.grid_rows || []) { + row.refresh_dependency(); + } + } + } } set_dependant_property(condition, fieldname, property) {