diff --git a/frappe/public/js/frappe/form/column.js b/frappe/public/js/frappe/form/column.js
index 98ca28b9f5..27231da7e5 100644
--- a/frappe/public/js/frappe/form/column.js
+++ b/frappe/public/js/frappe/form/column.js
@@ -9,19 +9,25 @@ export default class Column {
}
make() {
- this.wrapper = $(`
').appendTo(this.layout_main);
- this.body = $('').appendTo(this.parent);
this.message = $('
').appendTo(this.wrapper);
-
this.page = $('
').appendTo(this.wrapper);
- this.tabbed_layout && this.setup_tabbed_layout();
if (!this.fields) {
this.fields = this.get_doctype_fields();
}
- this.setup_tabbing();
+ if (this.is_tabbed_layout()) {
+ this.setup_tabbed_layout();
+ }
+
+ this.setup_tab_events();
this.render();
}
setup_tabbed_layout() {
- $(`
`).appendTo(this.page);
+ $(`
+
+ `).appendTo(this.page);
this.tabs_list = this.page.find('.form-tabs');
this.tabs_content = $(`
`).appendTo(this.page);
-
this.setup_events();
}
@@ -114,16 +117,16 @@ frappe.ui.form.Layout = class Layout {
this.section = null;
this.column = null;
- // if (this.with_dashboard) {
- // this.setup_dashboard_section();
- // }
-
- if (this.tabbed_layout && this.no_opening_tab()) {
- this.make_tab({label: __('Details'), fieldname: 'details'});
+ if (this.no_opening_section() && !this.is_tabbed_layout()) {
+ this.fields.unshift({fieldtype: 'Section Break'});
}
- if (this.no_opening_section()) {
- this.make_section();
+ if (this.is_tabbed_layout()) {
+ let default_tab = {label: __('Details'), fieldname: 'details'};
+ let first_tab = this.fields[1].fieldtype === "Tab Break" ? this.fields[1] : null;
+ if (!first_tab) {
+ this.fields.splice(1, 0, default_tab);
+ }
}
fields.forEach(df => {
@@ -154,10 +157,8 @@ frappe.ui.form.Layout = class Layout {
return (this.fields[1] && this.fields[1].fieldtype != "Tab Break") || !this.fields.length;
}
- setup_dashboard_section() {
- if (this.no_opening_section()) {
- this.fields.unshift({fieldtype: 'Section Break'});
- }
+ is_tabbed_layout() {
+ return this.fields.find(f => f.fieldtype === "Tab Break");
}
replace_field(fieldname, df, render) {
@@ -190,7 +191,7 @@ frappe.ui.form.Layout = class Layout {
this.section.fields_list.push(fieldobj);
this.section.fields_dict[df.fieldname] = fieldobj;
fieldobj.section = this.section;
- fieldobj.tab = this.tab;
+ fieldobj.tab = this.current_tab;
}
init_field(df, render=false) {
@@ -239,7 +240,7 @@ frappe.ui.form.Layout = class Layout {
}
make_section(df) {
- this.section = new Section(this, df, this.tab || null);
+ this.section = new Section(this, df, this.current_tab || null);
// append to layout fields
if (df) {
@@ -258,14 +259,12 @@ frappe.ui.form.Layout = class Layout {
}
make_tab(df) {
- this.tab = new Tab(this, df);
-
- if (df) {
- this.fields_dict[df.fieldname] = this.tab;
- this.fields_list.push(this.tab);
- }
-
- return this.tab;
+ this.section = null;
+ let tab = new Tab(this, df, this.frm, this.tabs_list, this.tabs_content);
+ this.current_tab = tab;
+ this.make_section({fieldtype: 'Section Break'});
+ this.tabs.push(tab);
+ return tab;
}
refresh(doc) {
@@ -421,14 +420,15 @@ frappe.ui.form.Layout = class Layout {
});
}
- setup_tabbing() {
+ setup_tab_events() {
this.wrapper.on("keydown", (ev) => {
if (ev.which == 9) {
- let current = $(ev.target),
- doctype = current.attr("data-doctype"),
- fieldname = current.attr("data-fieldname");
- if (doctype)
+ let current = $(ev.target);
+ let doctype = current.attr("data-doctype");
+ let fieldname = current.attr("data-fieldname");
+ if (doctype) {
return this.handle_tab(doctype, fieldname, ev.shiftKey);
+ }
}
});
}
diff --git a/frappe/public/js/frappe/form/section.js b/frappe/public/js/frappe/form/section.js
index cbc8666883..72760aad62 100644
--- a/frappe/public/js/frappe/form/section.js
+++ b/frappe/public/js/frappe/form/section.js
@@ -1,10 +1,7 @@
-// import '../class';
-
export default class Section {
- constructor(layout, df, tab) {
- this.layout = layout;
- this.tab = tab;
- this.parent = this.tab && this.tab.wrapper || null;
+ constructor(parent, df) {
+ this.card_layout = true;
+ this.parent = parent;
this.df = df || {};
this.fields_list = [];
this.fields_dict = {};
@@ -23,18 +20,11 @@ export default class Section {
}
make() {
- if (!this.layout.page) {
- this.layout.page = $('
').appendTo(this.layout.wrapper);
- }
-
- let make_card = this.layout.card_layout;
-
+ let make_card = this.card_layout;
this.wrapper = $(`
- `).appendTo(this.parent || this.layout.page);
-
- this.layout.sections.push(this);
+ `).appendTo(this.parent);
if (this.df) {
if (this.df.label) {
@@ -86,17 +76,11 @@ export default class Section {
}
}
- refresh() {
+ refresh(hide) {
if (!this.df) return;
-
// hide if explicitly hidden
- let hide = this.df.hidden || this.df.hidden_due_to_dependency;
- if (!hide && this.layout && this.layout.frm && !this.layout.frm.get_perm(this.df.permlevel || 0, "read")) {
- hide = true;
- }
-
+ hide = hide || this.df.hidden || this.df.hidden_due_to_dependency;
this.wrapper.toggleClass("hide-control", !!hide);
- // this.tab && this.tab.refresh();
}
collapse(hide) {
@@ -136,9 +120,9 @@ export default class Section {
}
has_missing_mandatory () {
- var missing_mandatory = false;
- for (var j = 0, l = this.fields_list.length; j < l; j++) {
- var section_df = this.fields_list[j].df;
+ let missing_mandatory = false;
+ for (let j = 0, l = this.fields_list.length; j < l; j++) {
+ const section_df = this.fields_list[j].df;
if (section_df.reqd && this.layout.doc[section_df.fieldname] == null) {
missing_mandatory = true;
break;
@@ -148,11 +132,15 @@ export default class Section {
}
hide() {
- this.wrapper.toggleClass("hide-control", true);
+ this.on_section_toggle(false);
}
show() {
- this.wrapper.toggleClass("hide-control", false);
- this.tab && this.tab.toggle(true);
+ this.on_section_toggle(true);
+ }
+
+ on_section_toggle(show) {
+ this.wrapper.toggleClass("hide-control", !show);
+ this.on_section_toggle && this.on_section_toggle(show);
}
}
diff --git a/frappe/public/js/frappe/form/tab.js b/frappe/public/js/frappe/form/tab.js
index 84e50a7da1..c8ca016398 100644
--- a/frappe/public/js/frappe/form/tab.js
+++ b/frappe/public/js/frappe/form/tab.js
@@ -1,8 +1,12 @@
export default class Tab {
- constructor(layout, df) {
- this.layout = layout;
+ constructor(parent, df, frm, tabs_list, tabs_content) {
+ this.parent = parent;
this.df = df || {};
- this.label = this.df && this.df.label || 'Details';
+ this.frm = frm;
+ this.doctype = 'User';
+ this.label = this.df && this.df.label;
+ this.tabs_list = tabs_list;
+ this.tabs_content = tabs_content;
this.fields_list = [];
this.fields_dict = {};
this.make();
@@ -10,28 +14,21 @@ export default class Tab {
}
make() {
- if (!this.layout.page) {
- this.layout.page = $('
').appendTo(this.layout.wrapper);
- }
-
- const id = `${frappe.scrub(this.layout.doctype, '-')}-${this.df.fieldname}`;
- this.parent = $(`
-
- ${__(this.label)}
-
- `).appendTo(this.layout.tabs_list);
+ const id = `${frappe.scrub(this.doctype, '-')}-${this.df.fieldname}`;
+ this.parent = $(`
+
+
+ ${__(this.label)}
+
+
+ `).appendTo(this.tabs_list);
this.wrapper = $(`
- `).appendTo(this.layout.tabs_content);
-
- this.layout.tabs.push(this);
- }
-
- set_content() {
-
+ id="${id}" role="tabpanel" aria-labelledby="${id}-tab">`).appendTo(this.tabs_content);
}
refresh() {
@@ -39,15 +36,15 @@ export default class Tab {
// hide if explicitly hidden
let hide = this.df.hidden || this.df.hidden_due_to_dependency;
- if (!hide && this.layout && this.layout.frm && !this.layout.frm.get_perm(this.df.permlevel || 0, "read")) {
+ if (!hide && this.frm && !this.frm.get_perm(this.df.permlevel || 0, "read")) {
hide = true;
}
-
+
hide && this.toggle(false);
}
toggle(show) {
- this.parent.toggleClass('hide', !show);
+ this.parent.toggleClass('hide', !show);
this.wrapper.toggleClass('hide', !show);
this.parent.toggleClass('show', show);
this.wrapper.toggleClass('show', show);