diff --git a/frappe/core/doctype/docfield/docfield.json b/frappe/core/doctype/docfield/docfield.json index 3acf1d5ea8..fe7f5e78ef 100644 --- a/frappe/core/doctype/docfield/docfield.json +++ b/frappe/core/doctype/docfield/docfield.json @@ -82,7 +82,8 @@ "documentation_url", "placeholder", "oldfieldname", - "oldfieldtype" + "oldfieldtype", + "show_description_on_click" ], "fields": [ { @@ -633,6 +634,12 @@ "fieldtype": "Select", "label": "Button Color", "options": "\nDefault\nPrimary\nInfo\nSuccess\nWarning\nDanger" + }, + { + "default": "0", + "fieldname": "show_description_on_click", + "fieldtype": "Check", + "label": "Show Description on Click" } ], "grid_page_length": 50, @@ -640,7 +647,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2026-01-06 01:37:29.723265", + "modified": "2026-02-06 15:13:03.688027", "modified_by": "Administrator", "module": "Core", "name": "DocField", diff --git a/frappe/core/doctype/docfield/docfield.py b/frappe/core/doctype/docfield/docfield.py index 94d99fe5e9..b97291b754 100644 --- a/frappe/core/doctype/docfield/docfield.py +++ b/frappe/core/doctype/docfield/docfield.py @@ -14,10 +14,10 @@ class DocField(Document): if TYPE_CHECKING: from frappe.types import DF + alignment: DF.Literal["", "Left", "Center", "Right"] allow_bulk_edit: DF.Check allow_in_quick_entry: DF.Check allow_on_submit: DF.Check - alignment: DF.Literal["", "Left", "Center", "Right"] bold: DF.Check button_color: DF.Literal["", "Default", "Primary", "Info", "Success", "Warning", "Danger"] collapsible: DF.Check @@ -117,6 +117,7 @@ class DocField(Document): search_index: DF.Check set_only_once: DF.Check show_dashboard: DF.Check + show_description_on_click: DF.Check show_on_timeline: DF.Check sort_options: DF.Check sticky: DF.Check diff --git a/frappe/public/js/frappe/form/controls/base_input.js b/frappe/public/js/frappe/form/controls/base_input.js index 3cd277a239..7daa4ce30b 100644 --- a/frappe/public/js/frappe/form/controls/base_input.js +++ b/frappe/public/js/frappe/form/controls/base_input.js @@ -1,3 +1,4 @@ +import { createPopper } from "@popperjs/core"; frappe.ui.form.ControlInput = class ControlInput extends frappe.ui.form.Control { static horizontal = true; make() { @@ -7,7 +8,7 @@ frappe.ui.form.ControlInput = class ControlInput extends frappe.ui.form.Control // set description this.set_max_width(); - + this.info_card_display = false; // set initial value if set if (this.df.initial_value) { this.set_value(this.df.initial_value); @@ -147,6 +148,7 @@ frappe.ui.form.ControlInput = class ControlInput extends frappe.ui.form.Control me.set_description(); me.set_label(); me.set_doc_url(); + // me.set_info_url(); me.set_mandatory(me.value); me.set_bold(); me.set_required(); @@ -189,6 +191,7 @@ frappe.ui.form.ControlInput = class ControlInput extends frappe.ui.form.Control } } set_label(label) { + const me = this; if (label) this.df.label = label; if (this.only_input || this.df.label == this._label) return; @@ -197,14 +200,64 @@ frappe.ui.form.ControlInput = class ControlInput extends frappe.ui.form.Control this.label_span.innerHTML = (icon ? ' ' : "") + __(this.df.label, null, this.df.parent) || " "; + if (this.df.show_description_on_click) { + $(`${frappe.utils.icon("message-circle-question-mark", "sm")}`).appendTo( + $(this.label_span) + ); + this.$info_card = $("
").appendTo(this.label_span); + $(this.label_area).css({ + display: "flex", + gap: "6px", + "align-items": "center", + "white-space": "nowrap", + }); + let popper = createPopper( + $(this.label_span).find("a").get(0), + this.$info_card.get(0), + { + modifiers: [ + { + name: "offset", + options: { + offset: [0, 8], + }, + }, + ], + } + ); + $(this.label_span) + .find("a") + .on("click", (event) => { + event.preventDefault(); + me.$info_card.html(""); + let card = new frappe.ui.SidebarCard({ + // title: "Trial ends in 3 days", + // icon: "info", + message: me.df.description, + parent: me.$info_card, + // primary_action_icon: "zap", + // primary_action_label: "Upgrade", + close_button: true, + // primary_action: () => {}, + }); + if (me.info_card_display) { + me.info_card_display = false; + me.$info_card.removeAttr("data-show"); + } else { + me.info_card_display = true; + me.$info_card.attr("data-show", ""); + popper.update(); + } + }); + } this._label = this.df.label; } set_doc_url() { + if (this.df.show_description_on_click) return; let unsupported_fieldtypes = frappe.model.no_value_type.filter( (x) => frappe.model.table_fields.indexOf(x) === -1 ); - if ( !this.df.label || !this.df?.documentation_url || @@ -214,6 +267,7 @@ frappe.ui.form.ControlInput = class ControlInput extends frappe.ui.form.Control let $help = this.$wrapper.find("span.help"); $help.empty(); + $(` + {% if(!card.close_button) { %}