From ad1fb20d25ff31288735c74f4ea08a921744e70a Mon Sep 17 00:00:00 2001 From: Sagar Vora <16315650+sagarvora@users.noreply.github.com> Date: Tue, 20 Jan 2026 00:04:02 +0530 Subject: [PATCH 1/6] refactor: improve `refresh_dependency` and remove legacy code --- frappe/public/js/frappe/form/layout.js | 42 +++----------------------- 1 file changed, 5 insertions(+), 37 deletions(-) diff --git a/frappe/public/js/frappe/form/layout.js b/frappe/public/js/frappe/form/layout.js index aad7c8c45a..7ae298756a 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(); } } @@ -773,8 +743,6 @@ frappe.ui.form.Layout = class Layout { ); } } - - this.refresh_section_count(); } set_dependant_property(condition, fieldname, property) { From 1011b59493aff17c23cab18264e9a06fa3c4b861 Mon Sep 17 00:00:00 2001 From: Sagar Vora <16315650+sagarvora@users.noreply.github.com> Date: Tue, 20 Jan 2026 00:50:47 +0530 Subject: [PATCH 2/6] perf: refresh grid only if props are changed --- frappe/public/js/frappe/form/grid_row.js | 38 +++++++++++++++--------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/frappe/public/js/frappe/form/grid_row.js b/frappe/public/js/frappe/form/grid_row.js index 61905990fe..af2974b3f6 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,31 @@ 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) => { + // re-evaluate dependency expressions and refresh only if something changed + let changed = false; + for (const df of this.docfields) { if (df.depends_on || df.mandatory_depends_on || df.read_only_depends_on) { - this.set_dependant_property(df); + changed ||= this.set_dependant_property(df); } - }); - this.refresh(); + } + if (changed) { + this.refresh(); + } } evaluate_depends_on_value(expression) { From e2d59693f7be428538d328d80df9e97c05f934f3 Mon Sep 17 00:00:00 2001 From: Sagar Vora <16315650+sagarvora@users.noreply.github.com> Date: Tue, 20 Jan 2026 00:56:26 +0530 Subject: [PATCH 3/6] chore: use constant in `refresh_dependency` --- frappe/public/js/frappe/form/grid_row.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/grid_row.js b/frappe/public/js/frappe/form/grid_row.js index af2974b3f6..555c8b192a 100644 --- a/frappe/public/js/frappe/form/grid_row.js +++ b/frappe/public/js/frappe/form/grid_row.js @@ -816,7 +816,7 @@ export default class GridRow { // re-evaluate dependency expressions and refresh only if something changed let changed = false; for (const df of this.docfields) { - if (df.depends_on || df.mandatory_depends_on || df.read_only_depends_on) { + if (DEPENDENCY_PROPERTIES.some((d) => df[d.expr])) { changed ||= this.set_dependant_property(df); } } From f9a11644b487ba450b2e350eaf3230c2e59da139 Mon Sep 17 00:00:00 2001 From: Sagar Vora <16315650+sagarvora@users.noreply.github.com> Date: Tue, 20 Jan 2026 01:12:35 +0530 Subject: [PATCH 4/6] perf: evaluate properties only for visible columns --- frappe/public/js/frappe/form/grid_row.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/form/grid_row.js b/frappe/public/js/frappe/form/grid_row.js index 555c8b192a..032fe6f40b 100644 --- a/frappe/public/js/frappe/form/grid_row.js +++ b/frappe/public/js/frappe/form/grid_row.js @@ -813,9 +813,10 @@ export default class GridRow { } refresh_dependency() { - // re-evaluate dependency expressions and refresh only if something changed + // re-evaluate dependency expressions of all columns + // refresh if some property changed let changed = false; - for (const df of this.docfields) { + for (const { df } of this.columns_list) { if (DEPENDENCY_PROPERTIES.some((d) => df[d.expr])) { changed ||= this.set_dependant_property(df); } From c5678b65e7defd02a14c3f134924acc32def4ddb Mon Sep 17 00:00:00 2001 From: Sagar Vora <16315650+sagarvora@users.noreply.github.com> Date: Tue, 20 Jan 2026 01:18:22 +0530 Subject: [PATCH 5/6] fix: refresh row deps on parent update --- frappe/public/js/frappe/form/layout.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frappe/public/js/frappe/form/layout.js b/frappe/public/js/frappe/form/layout.js index 7ae298756a..c0da70f26e 100644 --- a/frappe/public/js/frappe/form/layout.js +++ b/frappe/public/js/frappe/form/layout.js @@ -742,6 +742,12 @@ frappe.ui.form.Layout = class Layout { "read_only" ); } + + if (f.df.fieldtype === "Table") { + for (const row of f.grid?.grid_rows || []) { + row.refresh_dependency(); + } + } } } From 6bab4fa3a08199ff9b0e967fe22b0b73f0408daa Mon Sep 17 00:00:00 2001 From: Sagar Vora <16315650+sagarvora@users.noreply.github.com> Date: Tue, 20 Jan 2026 01:34:04 +0530 Subject: [PATCH 6/6] chore: improve comment --- frappe/public/js/frappe/form/grid_row.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/grid_row.js b/frappe/public/js/frappe/form/grid_row.js index 032fe6f40b..472e8a1780 100644 --- a/frappe/public/js/frappe/form/grid_row.js +++ b/frappe/public/js/frappe/form/grid_row.js @@ -813,7 +813,7 @@ export default class GridRow { } refresh_dependency() { - // re-evaluate dependency expressions of all columns + // re-evaluate dependency expressions of visible columns // refresh if some property changed let changed = false; for (const { df } of this.columns_list) {