diff --git a/cypress/integration/web_form.js b/cypress/integration/web_form.js index 9173bfaeb3..d7f210e7d2 100644 --- a/cypress/integration/web_form.js +++ b/cypress/integration/web_form.js @@ -45,7 +45,7 @@ context("Web Form", () => { cy.login(); cy.visit("/app/web-form/note"); - cy.findByRole("tab", { name: "Form Settings" }).click(); + cy.findByRole("tab", { name: "Settings" }).click(); cy.get('input[data-fieldname="login_required"]').check({ force: true }); cy.save(); @@ -65,7 +65,8 @@ context("Web Form", () => { cy.login(); cy.visit("/app/web-form/note"); - cy.findByRole("tab", { name: "List Settings" }).click(); + cy.findByRole("tab", { name: "Settings" }).click(); + cy.get(".section-head").contains("List Settings").click(); cy.get('input[data-fieldname="show_list"]').check(); cy.save(); @@ -78,7 +79,7 @@ context("Web Form", () => { it("Show Custom List Title", () => { cy.visit("/app/web-form/note"); - cy.findByRole("tab", { name: "List Settings" }).click(); + cy.findByRole("tab", { name: "Settings" }).click(); cy.fill_field("list_title", "Note List"); cy.save(); @@ -97,7 +98,7 @@ context("Web Form", () => { cy.visit("/app/web-form/note"); - cy.findByRole("tab", { name: "List Settings" }).click(); + cy.findByRole("tab", { name: "Settings" }).click(); cy.get('[data-fieldname="list_columns"] .grid-footer button') .contains("Add Row") @@ -108,19 +109,19 @@ context("Web Form", () => { cy.get("@grid-rows").find('.grid-row:first [data-fieldname="fieldname"]').click(); cy.get("@grid-rows") .find('.grid-row:first select[data-fieldname="fieldname"]') - .select("Title (Data)"); + .select("Title"); cy.get("@add-row").click(); cy.get("@grid-rows").find('.grid-row[data-idx="2"] [data-fieldname="fieldname"]').click(); cy.get("@grid-rows") .find('.grid-row[data-idx="2"] select[data-fieldname="fieldname"]') - .select("Public (Check)"); + .select("Public"); cy.get("@add-row").click(); cy.get("@grid-rows").find('.grid-row:last [data-fieldname="fieldname"]').click(); cy.get("@grid-rows") .find('.grid-row:last select[data-fieldname="fieldname"]') - .select("Content (Text Editor)"); + .select("Content"); cy.save(); @@ -171,7 +172,7 @@ context("Web Form", () => { it("Edit Mode", () => { cy.visit("/app/web-form/note"); - cy.findByRole("tab", { name: "Form Settings" }).click(); + cy.findByRole("tab", { name: "Settings" }).click(); cy.get('input[data-fieldname="allow_edit"]').check(); cy.save(); @@ -179,7 +180,7 @@ context("Web Form", () => { cy.visit("/note/Note 1"); cy.url().should("include", "/note/Note%201"); - cy.get(".web-form-actions a").contains("Edit").click(); + cy.get(".web-form-actions a").contains("Edit Response").click(); cy.url().should("include", "/note/Note%201/edit"); // Editable Field @@ -194,7 +195,7 @@ context("Web Form", () => { it("Allow Multiple Response", () => { cy.visit("/app/web-form/note"); - cy.findByRole("tab", { name: "Form Settings" }).click(); + cy.findByRole("tab", { name: "Settings" }).click(); cy.get('input[data-fieldname="allow_multiple"]').check(); cy.save(); @@ -212,7 +213,7 @@ context("Web Form", () => { it("Allow Delete", () => { cy.visit("/app/web-form/note"); - cy.findByRole("tab", { name: "Form Settings" }).click(); + cy.findByRole("tab", { name: "Settings" }).click(); cy.get('input[data-fieldname="allow_delete"]').check(); cy.save(); @@ -235,7 +236,7 @@ context("Web Form", () => { it("Navigate and Submit a WebForm", () => { cy.visit("/update-profile"); - cy.get(".web-form-actions a").contains("Edit").click(); + cy.get(".web-form-actions a").contains("Edit Response").click(); cy.fill_field("middle_name", "_Test User"); @@ -247,7 +248,7 @@ context("Web Form", () => { cy.call("frappe.tests.ui_test_helpers.update_webform_to_multistep").then(() => { cy.visit("/update-profile-duplicate"); - cy.get(".web-form-actions a").contains("Edit").click(); + cy.get(".web-form-actions a").contains("Edit Response").click(); cy.fill_field("middle_name", "_Test User"); diff --git a/frappe/public/js/bootstrap-4-web.bundle.js b/frappe/public/js/bootstrap-4-web.bundle.js index 083b7aecaa..3845a7b185 100644 --- a/frappe/public/js/bootstrap-4-web.bundle.js +++ b/frappe/public/js/bootstrap-4-web.bundle.js @@ -32,10 +32,7 @@ frappe.get_modal = function (title, content) { ${content}
@@ -49,11 +46,19 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.Dialog { return this.$wrapper.find(".modal-footer .btn-primary"); } + get_secondary_btn() { + return this.$wrapper.find(".modal-footer .btn-secondary"); + } + set_primary_action(label, click) { this.$wrapper.find(".modal-footer").removeClass("hidden"); return super.set_primary_action(label, click).removeClass("hidden"); } + set_secondary_action(click) { + return super.set_secondary_action(click).removeClass("hidden"); + } + make() { super.make(); if (this.fields) { diff --git a/frappe/public/js/frappe/form/controls/base_control.js b/frappe/public/js/frappe/form/controls/base_control.js index a315abc7e0..aed3f9ff3d 100644 --- a/frappe/public/js/frappe/form/controls/base_control.js +++ b/frappe/public/js/frappe/form/controls/base_control.js @@ -82,7 +82,7 @@ frappe.ui.form.Control = class BaseControl { is_null(value) && !in_list(["HTML", "Image", "Button"], this.df.fieldtype) ) - status = "None"; + status = "Read"; return status; } diff --git a/frappe/public/js/frappe/form/controls/color.js b/frappe/public/js/frappe/form/controls/color.js index 7fcadc6638..e9f88faec5 100644 --- a/frappe/public/js/frappe/form/controls/color.js +++ b/frappe/public/js/frappe/form/controls/color.js @@ -93,11 +93,11 @@ frappe.ui.form.ControlColor = class ControlColor extends frappe.ui.form.ControlD set_formatted_input(value) { super.set_formatted_input(value); - this.$input.val(value); - this.selected_color.css({ + this.$input?.val(value); + this.selected_color?.css({ "background-color": value || "transparent", }); - this.selected_color.toggleClass("no-value", !value); + this.selected_color?.toggleClass("no-value", !value); } get_color() { diff --git a/frappe/public/js/frappe/form/formatters.js b/frappe/public/js/frappe/form/formatters.js index e0286a4af1..7c580ff2b3 100644 --- a/frappe/public/js/frappe/form/formatters.js +++ b/frappe/public/js/frappe/form/formatters.js @@ -294,7 +294,10 @@ frappe.form.formatters = { let formatted_value = frappe.form.formatters.Text(value); // to use ql-editor styles try { - if (!$(formatted_value).find(".ql-editor").length) { + if ( + !$(formatted_value).find(".ql-editor").length && + !$(formatted_value).hasClass("ql-editor") + ) { formatted_value = `${value}
{{ _(title) }}
+ {% else %} +
+ ${__("login_required")}
+
`;
+ let message = __(
+ "Login is required to see web form list view. Enable {0} to see list settings",
+ [go_to_login_required_field]
+ );
$(frm.fields_dict["list_setting_message"].wrapper)
- .html(
- $(
- ` `
- )
- )
- .find("span")
+ .html($(` `))
+ .find("code")
.click(() => frm.scroll_to_field("login_required"));
} else {
$(frm.fields_dict["list_setting_message"].wrapper).empty();
diff --git a/frappe/website/doctype/web_form/web_form.json b/frappe/website/doctype/web_form/web_form.json
index 8faa263e5b..f5ab147c64 100644
--- a/frappe/website/doctype/web_form/web_form.json
+++ b/frappe/website/doctype/web_form/web_form.json
@@ -5,50 +5,50 @@
"document_type": "Document",
"engine": "InnoDB",
"field_order": [
- "title_and_route_tab",
+ "form_tab",
"title",
"route",
"published",
- "column_break_4",
+ "column_break_1",
"doc_type",
"module",
"is_standard",
- "introduction",
+ "section_break_1",
"introduction_text",
- "form_settings_tab",
+ "web_form_fields",
+ "settings_tab",
"login_required",
"allow_multiple",
"allow_edit",
"allow_delete",
- "column_break_18",
+ "column_break_2",
"apply_document_permissions",
"allow_print",
"print_format",
"allow_comments",
"show_attachments",
"allow_incomplete",
- "form_fields",
- "web_form_fields",
+ "section_break_2",
"max_attachment_size",
- "list_settings_tab",
+ "section_break_3",
"list_setting_message",
"show_list",
"list_title",
"list_columns",
- "sidebar_settings_tab",
+ "section_break_4",
"show_sidebar",
"website_sidebar",
"customization_tab",
"button_label",
"banner_image",
- "column_break_37",
+ "column_break_3",
"breadcrumbs",
- "section_break_43",
+ "section_break_5",
"success_title",
"success_url",
- "column_break_41",
+ "column_break_4",
"success_message",
- "scripting_style_tab",
+ "section_break_6",
"client_script",
"custom_css"
],
@@ -81,10 +81,6 @@
"label": "Module",
"options": "Module Def"
},
- {
- "fieldname": "column_break_4",
- "fieldtype": "Column Break"
- },
{
"default": "0",
"fieldname": "is_standard",
@@ -158,12 +154,6 @@
"fieldtype": "Check",
"label": "Allow Incomplete Forms"
},
- {
- "collapsible": 1,
- "fieldname": "introduction",
- "fieldtype": "Section Break",
- "label": "Introduction"
- },
{
"fieldname": "introduction_text",
"fieldtype": "Text Editor",
@@ -250,21 +240,6 @@
"label": "List Columns",
"options": "Web Form List Column"
},
- {
- "fieldname": "title_and_route_tab",
- "fieldtype": "Tab Break",
- "label": "Title & Route"
- },
- {
- "collapsible": 1,
- "fieldname": "form_fields",
- "fieldtype": "Section Break",
- "label": "Form Fields"
- },
- {
- "fieldname": "column_break_18",
- "fieldtype": "Column Break"
- },
{
"fieldname": "website_sidebar",
"fieldtype": "Link",
@@ -277,62 +252,89 @@
"label": "List Setting Message"
},
{
- "fieldname": "form_settings_tab",
+ "fieldname": "customization_tab",
"fieldtype": "Tab Break",
- "label": "Form Settings"
+ "label": "Customization"
},
{
- "collapsible": 1,
- "collapsible_depends_on": "show_list",
- "fieldname": "list_settings_tab",
- "fieldtype": "Tab Break",
- "label": "List Settings"
+ "fieldname": "success_title",
+ "fieldtype": "Data",
+ "label": "Success Title"
},
{
- "collapsible": 1,
- "fieldname": "sidebar_settings_tab",
- "fieldtype": "Tab Break",
- "label": "Sidebar Settings"
+ "fieldname": "banner_image",
+ "fieldtype": "Attach Image",
+ "label": "Banner Image"
},
{
- "fieldname": "scripting_style_tab",
+ "fieldname": "form_tab",
"fieldtype": "Tab Break",
- "label": "Scripting / Style"
+ "label": "Form"
},
{
- "fieldname": "customization_tab",
+ "fieldname": "column_break_1",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "section_break_1",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "settings_tab",
"fieldtype": "Tab Break",
- "label": "Customization"
+ "label": "Settings"
},
{
- "fieldname": "success_title",
- "fieldtype": "Data",
- "label": "Success Title"
+ "fieldname": "column_break_2",
+ "fieldtype": "Column Break"
},
{
- "fieldname": "banner_image",
- "fieldtype": "Attach Image",
- "label": "Banner Image"
+ "collapsible": 1,
+ "fieldname": "section_break_2",
+ "fieldtype": "Section Break"
},
{
- "fieldname": "column_break_41",
+ "collapsible": 1,
+ "collapsible_depends_on": "show_list",
+ "fieldname": "section_break_3",
+ "fieldtype": "Section Break",
+ "label": "List Settings"
+ },
+ {
+ "collapsible": 1,
+ "collapsible_depends_on": "show_sidebar",
+ "fieldname": "section_break_4",
+ "fieldtype": "Section Break",
+ "label": "Sidebar Settings"
+ },
+ {
+ "fieldname": "column_break_3",
"fieldtype": "Column Break"
},
{
- "fieldname": "section_break_43",
+ "collapsible": 1,
+ "collapsible_depends_on": "eval: doc.success_title || doc.success_message || doc.success_url",
+ "fieldname": "section_break_5",
"fieldtype": "Section Break",
"label": "After Submission"
},
{
- "fieldname": "column_break_37",
+ "fieldname": "column_break_4",
"fieldtype": "Column Break"
+ },
+ {
+ "collapsible": 1,
+ "collapsible_depends_on": "eval: doc.client_script || doc.custom_css",
+ "fieldname": "section_break_6",
+ "fieldtype": "Section Break",
+ "label": "Scripting / Style"
}
],
"has_web_view": 1,
"icon": "icon-edit",
"is_published_field": "published",
"links": [],
- "modified": "2022-08-11 16:27:25.914627",
+ "modified": "2022-08-17 18:58:49.451658",
"modified_by": "Administrator",
"module": "Website",
"name": "Web Form",
diff --git a/frappe/website/doctype/web_form/web_form.py b/frappe/website/doctype/web_form/web_form.py
index 718088212f..08e0c39ccd 100644
--- a/frappe/website/doctype/web_form/web_form.py
+++ b/frappe/website/doctype/web_form/web_form.py
@@ -124,7 +124,8 @@ def get_context(context):
def get_context(self, context):
"""Build context to render the `web_form.html` template"""
- context.is_form_editable = False
+ context.in_edit_mode = False
+ context.in_view_mode = False
self.set_web_form_module()
if frappe.form_dict.is_list:
@@ -156,10 +157,14 @@ def get_context(context):
frappe.redirect(f"/{self.route}/new")
if frappe.form_dict.is_edit and not self.allow_edit:
+ context.in_view_mode = True
frappe.redirect(f"/{self.route}/{frappe.form_dict.name}")
if frappe.form_dict.is_edit:
- context.is_form_editable = True
+ context.in_edit_mode = True
+
+ if frappe.form_dict.is_read:
+ context.in_view_mode = True
if (
not frappe.form_dict.is_edit
@@ -167,7 +172,7 @@ def get_context(context):
and self.allow_edit
and frappe.form_dict.name
):
- context.is_form_editable = True
+ context.in_edit_mode = True
frappe.redirect(f"/{frappe.local.path}/edit")
if (
@@ -179,6 +184,7 @@ def get_context(context):
):
name = frappe.db.get_value(self.doc_type, {"owner": frappe.session.user}, "name")
if name:
+ context.in_view_mode = True
frappe.redirect(f"/{self.route}/{name}")
# Show new form when
@@ -203,7 +209,9 @@ def get_context(context):
# load web form doc
context.web_form_doc = self.as_dict(no_nulls=True)
- context.web_form_doc.update(dict_with_keys(context, ["is_list", "is_new", "is_form_editable"]))
+ context.web_form_doc.update(
+ dict_with_keys(context, ["is_list", "is_new", "in_edit_mode", "in_view_mode"])
+ )
if self.show_sidebar and self.website_sidebar:
context.sidebar_items = get_sidebar_items(self.website_sidebar)
@@ -278,17 +286,11 @@ def get_context(context):
if frappe.form_dict.name:
context.doc_name = frappe.form_dict.name
context.reference_doc = frappe.get_doc(self.doc_type, context.doc_name)
- context.title = strip_html(
- context.reference_doc.get(context.reference_doc.meta.get_title_field())
+ context.web_form_title = context.title
+ context.title = (
+ strip_html(context.reference_doc.get(context.reference_doc.meta.get_title_field()))
+ or context.doc_name
)
- if context.is_form_editable and context.parents:
- context.parents.append(
- {
- "label": _(context.title),
- "route": f"{self.route}/{context.doc_name}",
- }
- )
- context.title = _("Editing {0}").format(context.title)
context.reference_doc.add_seen()
context.reference_doctype = context.reference_doc.doctype
context.reference_name = context.reference_doc.name
@@ -309,7 +311,7 @@ def get_context(context):
context.reference_doc.doctype, context.reference_doc.name
)
- context.reference_doc = json.loads(context.reference_doc.as_json())
+ context.reference_doc = context.reference_doc.as_dict(no_nulls=True)
def add_custom_context_and_script(self, context):
"""Update context from module if standard and append script"""
@@ -481,7 +483,7 @@ def accept(web_form, data, docname=None):
for field in web_form.web_form_fields:
fieldname = field.fieldname
df = meta.get_field(fieldname)
- value = data.get(fieldname, None)
+ value = data.get(fieldname, "")
if df and df.fieldtype in ("Attach", "Attach Image"):
if value and "data:" and "base64" in value:
diff --git a/frappe/website/doctype/web_form_field/web_form_field.json b/frappe/website/doctype/web_form_field/web_form_field.json
index dbadf52881..4fb566be88 100644
--- a/frappe/website/doctype/web_form_field/web_form_field.json
+++ b/frappe/website/doctype/web_form_field/web_form_field.json
@@ -32,20 +32,20 @@
"fieldname": "fieldname",
"fieldtype": "Select",
"in_list_view": 1,
- "label": "Fieldname"
+ "label": "Field"
},
{
"fieldname": "fieldtype",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Fieldtype",
- "options": "Attach\nAttach Image\nCheck\nCurrency\nData\nDate\nDatetime\nDuration\nFloat\nHTML\nInt\nLink\nPassword\nRating\nSelect\nSignature\nSmall Text\nText\nText Editor\nTable\nTime\nSection Break\nColumn Break\nPage Break"
+ "options": "Attach\nAttach Image\nCheck\nCurrency\nColor\nData\nDate\nDatetime\nDuration\nFloat\nHTML\nInt\nLink\nPassword\nRating\nSelect\nSignature\nSmall Text\nText\nText Editor\nTable\nTime\nSection Break\nColumn Break\nPage Break"
},
{
"fieldname": "label",
"fieldtype": "Data",
"in_list_view": 1,
- "label": "Label"
+ "label": "Custom Label"
},
{
"default": "0",
@@ -58,6 +58,7 @@
"default": "0",
"fieldname": "reqd",
"fieldtype": "Check",
+ "in_list_view": 1,
"label": "Mandatory"
},
{
@@ -146,7 +147,7 @@
],
"istable": 1,
"links": [],
- "modified": "2022-08-10 12:59:51.170546",
+ "modified": "2022-08-22 17:22:39.026893",
"modified_by": "Administrator",
"module": "Website",
"name": "Web Form Field",
diff --git a/frappe/website/doctype/web_form_list_column/web_form_list_column.json b/frappe/website/doctype/web_form_list_column/web_form_list_column.json
index e55aeadca6..8be724f426 100644
--- a/frappe/website/doctype/web_form_list_column/web_form_list_column.json
+++ b/frappe/website/doctype/web_form_list_column/web_form_list_column.json
@@ -15,14 +15,14 @@
"fieldname": "fieldname",
"fieldtype": "Select",
"in_list_view": 1,
- "label": "Fieldname",
+ "label": "Field",
"reqd": 1
},
{
"fieldname": "label",
"fieldtype": "Data",
"in_list_view": 1,
- "label": "Label"
+ "label": "Custom Label"
},
{
"fieldname": "fieldtype",
@@ -35,7 +35,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2022-06-21 17:22:14.978947",
+ "modified": "2022-08-17 19:09:01.417841",
"modified_by": "Administrator",
"module": "Website",
"name": "Web Form List Column",