fix: set translated text to link field (#15451)
- Fixes [Issue/15324](https://github.com/frappe/frappe/issues/15324) - When selecting a value for Link Field, the English text was set as link field value. - This PR aims to fix it by setting the translated text as link field value on selection. Todo: - [x] Show translated text in the select dropdown - [x] Set translated value to Link field on select - [x] Show original value when link field is in focus - [x] Add option to toggle this behaviour ### Behaviour - Link field loses focus: show the translated name. - Link field is focused - If old value is present - If options **are** one of [Role, DocType]: show the translated name - Else: show the name (untranslated) to enable search in untranslated values - Else: show what the user typed (untranslated) to enable search in untranslated values - Value is selected: link field loses focus ## Demo ### Link to UOM in a custom Item DocType The UOM names are in english, so the search needs to happen in english. When possible, the translation is displayed. #### Before https://user-images.githubusercontent.com/14891507/156415248-e5e80d05-53dc-4ca8-89c7-998986ff6e99.mov #### After https://user-images.githubusercontent.com/14891507/156410386-a874430c-f340-43ed-9c3a-92e8d4d50fc9.mov ### Link to DocType in Customize Form The DocType names get translated before being searched. This is a preexisting hack in the framework for DocType and Role. In this case, we can search in the translations. #### Before https://user-images.githubusercontent.com/14891507/156414648-8e505f8c-9dee-4358-8182-3b358c28bb62.mov #### After https://user-images.githubusercontent.com/14891507/156411881-c4ca22e1-1397-4e13-9768-5e16b72f8d6d.mov https://docs.erpnext.com/docs/v13/user/manual/en/customize-erpnext/customize-form/edit?wiki_page_patch=fdafee2715
This commit is contained in:
parent
07dd2371b1
commit
70409a3c7b
12 changed files with 281 additions and 29 deletions
|
|
@ -20,7 +20,21 @@ context('Control Link', () => {
|
|||
'label': 'Select ToDo',
|
||||
'fieldname': 'link',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'ToDo'
|
||||
'options': 'ToDo',
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
function get_dialog_with_user_link() {
|
||||
return cy.dialog({
|
||||
title: 'Link',
|
||||
fields: [
|
||||
{
|
||||
'label': 'Select User',
|
||||
'fieldname': 'link',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'User',
|
||||
}
|
||||
]
|
||||
});
|
||||
|
|
@ -29,6 +43,24 @@ context('Control Link', () => {
|
|||
it('should set the valid value', () => {
|
||||
get_dialog_with_link().as('dialog');
|
||||
|
||||
cy.insert_doc("Property Setter", {
|
||||
"doctype": "Property Setter",
|
||||
"doc_type": "User",
|
||||
"property": "translate_link_fields",
|
||||
"property_type": "Check",
|
||||
"doctype_or_field": "DocType",
|
||||
"value": "0"
|
||||
}, true);
|
||||
|
||||
cy.insert_doc("Property Setter", {
|
||||
"doctype": "Property Setter",
|
||||
"doc_type": "ToDo",
|
||||
"property": "show_title_field_in_link",
|
||||
"property_type": "Check",
|
||||
"doctype_or_field": "DocType",
|
||||
"value": "0"
|
||||
}, true);
|
||||
|
||||
cy.intercept('POST', '/api/method/frappe.desk.search.search_link').as('search_link');
|
||||
|
||||
cy.get('.frappe-control[data-fieldname=link] input').focus().as('input');
|
||||
|
|
@ -88,7 +120,8 @@ context('Control Link', () => {
|
|||
cy.get('@input').type(todos[0]).blur();
|
||||
cy.wait('@validate_link');
|
||||
cy.get('@input').focus();
|
||||
cy.findByTitle('Open Link')
|
||||
cy.wait(500); // wait for arrow to show
|
||||
cy.get('.frappe-control[data-fieldname=link] .btn-open')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
cy.location('pathname').should('eq', `/app/todo/${todos[0]}`);
|
||||
|
|
@ -96,7 +129,15 @@ context('Control Link', () => {
|
|||
});
|
||||
|
||||
it('show title field in link', () => {
|
||||
get_dialog_with_link().as('dialog');
|
||||
|
||||
cy.insert_doc("Property Setter", {
|
||||
"doctype": "Property Setter",
|
||||
"doc_type": "User",
|
||||
"property": "translate_link_fields",
|
||||
"property_type": "Check",
|
||||
"doctype_or_field": "DocType",
|
||||
"value": "0"
|
||||
}, true);
|
||||
|
||||
cy.insert_doc("Property Setter", {
|
||||
"doctype": "Property Setter",
|
||||
|
|
@ -107,6 +148,10 @@ context('Control Link', () => {
|
|||
"value": "1"
|
||||
}, true);
|
||||
|
||||
cy.clear_cache();
|
||||
cy.wait(500);
|
||||
|
||||
get_dialog_with_link().as('dialog');
|
||||
cy.window().its('frappe').then(frappe => {
|
||||
if (!frappe.boot) {
|
||||
frappe.boot = {
|
||||
|
|
@ -134,8 +179,6 @@ context('Control Link', () => {
|
|||
|
||||
expect(value).to.eq(todos[0]);
|
||||
expect(label).to.eq('this is a test todo for link');
|
||||
|
||||
cy.remove_doc("Property Setter", "ToDo-main-show_title_field_in_link");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -143,6 +186,7 @@ context('Control Link', () => {
|
|||
it('should update dependant fields (via fetch_from)', () => {
|
||||
cy.get('@todos').then(todos => {
|
||||
cy.visit(`/app/todo/${todos[0]}`);
|
||||
cy.intercept('POST', '/api/method/frappe.desk.search.search_link').as('search_link');
|
||||
cy.intercept('POST', '/api/method/frappe.client.validate_link').as('validate_link');
|
||||
|
||||
cy.get('.frappe-control[data-fieldname=assigned_by] input').focus().as('input');
|
||||
|
|
@ -167,7 +211,9 @@ context('Control Link', () => {
|
|||
.should("eq", null);
|
||||
|
||||
// set valid value again
|
||||
cy.get('@input').clear().type('Administrator', {delay: 100}).blur();
|
||||
cy.get('@input').clear().focus();
|
||||
cy.wait('@search_link');
|
||||
cy.get('@input').type('Administrator', {delay: 100}).blur();
|
||||
cy.wait('@validate_link');
|
||||
|
||||
cy.window()
|
||||
|
|
@ -214,4 +260,130 @@ context('Control Link', () => {
|
|||
"contain", ""
|
||||
);
|
||||
});
|
||||
|
||||
it('show translated text for link with show_title_field_in_link enabled', () => {
|
||||
cy.insert_doc("Property Setter", {
|
||||
"doctype": "Property Setter",
|
||||
"doc_type": "ToDo",
|
||||
"property": "translate_link_fields",
|
||||
"property_type": "Check",
|
||||
"doctype_or_field": "DocType",
|
||||
"value": "1"
|
||||
}, true);
|
||||
|
||||
cy.insert_doc("Property Setter", {
|
||||
"doctype": "Property Setter",
|
||||
"doc_type": "ToDo",
|
||||
"property": "show_title_field_in_link",
|
||||
"property_type": "Check",
|
||||
"doctype_or_field": "DocType",
|
||||
"value": "1"
|
||||
}, true);
|
||||
|
||||
cy.window().its('frappe').then(frappe => {
|
||||
cy.insert_doc("Translation", {
|
||||
doctype: "Translation",
|
||||
language: frappe.boot.lang,
|
||||
source_text: "this is a test todo for link",
|
||||
translated_text: "this is a translated test todo for link",
|
||||
});
|
||||
});
|
||||
|
||||
cy.clear_cache();
|
||||
cy.wait(500);
|
||||
|
||||
cy.window().its('frappe').then(frappe => {
|
||||
if (!frappe.boot) {
|
||||
frappe.boot = {
|
||||
link_title_doctypes: ['ToDo'],
|
||||
translatable_doctypes: ['ToDo']
|
||||
};
|
||||
} else {
|
||||
frappe.boot.link_title_doctypes = ['ToDo'];
|
||||
frappe.boot.translatable_doctypes = ['ToDo'];
|
||||
}
|
||||
});
|
||||
|
||||
get_dialog_with_link().as('dialog');
|
||||
cy.intercept('POST', '/api/method/frappe.desk.search.search_link').as('search_link');
|
||||
|
||||
cy.get('.frappe-control[data-fieldname=link] input').focus().as('input');
|
||||
cy.wait('@search_link');
|
||||
cy.get('@input').type('todo for link', { delay: 100 });
|
||||
cy.wait('@search_link');
|
||||
cy.get('.frappe-control[data-fieldname=link] ul').should('be.visible');
|
||||
cy.get('.frappe-control[data-fieldname=link] input').type('{enter}', { delay: 100 });
|
||||
cy.get('.frappe-control[data-fieldname=link] input').blur();
|
||||
cy.get('@dialog').then(dialog => {
|
||||
cy.get('@todos').then(todos => {
|
||||
let field = dialog.get_field('link');
|
||||
let value = field.get_value();
|
||||
let label = field.get_label_value();
|
||||
|
||||
expect(value).to.eq(todos[0]);
|
||||
expect(label).to.eq('this is a translated test todo for link');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('show translated text for link with show_title_field_in_link disabled', () => {
|
||||
cy.insert_doc("Property Setter", {
|
||||
"doctype": "Property Setter",
|
||||
"doc_type": "User",
|
||||
"property": "translate_link_fields",
|
||||
"property_type": "Check",
|
||||
"doctype_or_field": "DocType",
|
||||
"value": "1"
|
||||
}, true);
|
||||
|
||||
cy.insert_doc("Property Setter", {
|
||||
"doctype": "Property Setter",
|
||||
"doc_type": "ToDo",
|
||||
"property": "show_title_field_in_link",
|
||||
"property_type": "Check",
|
||||
"doctype_or_field": "DocType",
|
||||
"value": "0"
|
||||
}, true);
|
||||
|
||||
cy.window().its('frappe').then(frappe => {
|
||||
cy.insert_doc("Translation", {
|
||||
doctype: "Translation",
|
||||
language: frappe.boot.lang,
|
||||
source_text: "test@erpnext.com",
|
||||
translated_text: "translatedtest@erpnext.com",
|
||||
});
|
||||
});
|
||||
|
||||
cy.clear_cache();
|
||||
cy.wait(500);
|
||||
|
||||
cy.window().its('frappe').then(frappe => {
|
||||
if (!frappe.boot) {
|
||||
frappe.boot = {
|
||||
translatable_doctypes: ['User']
|
||||
};
|
||||
} else {
|
||||
frappe.boot.translatable_doctypes = ['User'];
|
||||
}
|
||||
});
|
||||
|
||||
get_dialog_with_user_link().as('dialog');
|
||||
cy.intercept('POST', '/api/method/frappe.desk.search.search_link').as('search_link');
|
||||
|
||||
cy.get('.frappe-control[data-fieldname=link] input').focus().as('input');
|
||||
cy.wait('@search_link');
|
||||
cy.get('@input').type('test@erpnext.com', { delay: 100 });
|
||||
cy.wait('@search_link');
|
||||
cy.get('.frappe-control[data-fieldname=link] ul').should('be.visible');
|
||||
cy.get('.frappe-control[data-fieldname=link] input').type('{enter}', { delay: 100 });
|
||||
cy.get('.frappe-control[data-fieldname=link] input').blur();
|
||||
cy.get('@dialog').then(dialog => {
|
||||
let field = dialog.get_field('link');
|
||||
let value = field.get_value();
|
||||
let label = field.get_label_value();
|
||||
|
||||
expect(value).to.eq('test@erpnext.com');
|
||||
expect(label).to.eq('translatedtest@erpnext.com');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ def get_bootinfo():
|
|||
bootinfo.desk_settings = get_desk_settings()
|
||||
bootinfo.app_logo_url = get_app_logo()
|
||||
bootinfo.link_title_doctypes = get_link_title_doctypes()
|
||||
bootinfo.translatable_doctypes = get_translatable_doctypes()
|
||||
|
||||
return bootinfo
|
||||
|
||||
|
|
@ -408,3 +409,11 @@ def set_time_zone(bootinfo):
|
|||
"user": bootinfo.get("user_info", {}).get(frappe.session.user, {}).get("time_zone", None)
|
||||
or get_time_zone(),
|
||||
}
|
||||
|
||||
|
||||
def get_translatable_doctypes():
|
||||
dts = frappe.get_all("DocType", {"translate_link_fields": 1}, pluck="name")
|
||||
custom_dts = frappe.get_all(
|
||||
"Property Setter", {"property": "translate_link_fields", "value": "1"}, pluck="doc_type"
|
||||
)
|
||||
return dts + custom_dts
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
"view_settings",
|
||||
"title_field",
|
||||
"show_title_field_in_link",
|
||||
"translate_link_fields",
|
||||
"search_fields",
|
||||
"default_print_format",
|
||||
"sort_field",
|
||||
|
|
@ -591,6 +592,12 @@
|
|||
"fieldname": "show_title_field_in_link",
|
||||
"fieldtype": "Check",
|
||||
"label": "Show Title in Link Fields"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "translate_link_fields",
|
||||
"fieldtype": "Check",
|
||||
"label": "Translate Link Fields"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-bolt",
|
||||
|
|
@ -673,7 +680,7 @@
|
|||
"link_fieldname": "reference_doctype"
|
||||
}
|
||||
],
|
||||
"modified": "2022-02-15 21:47:16.467217",
|
||||
"modified": "2022-02-28 21:56:52.116915",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "DocType",
|
||||
|
|
@ -708,5 +715,6 @@
|
|||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": [],
|
||||
"track_changes": 1
|
||||
"track_changes": 1,
|
||||
"translate_link_fields": 1
|
||||
}
|
||||
|
|
@ -16,7 +16,6 @@ frappe.ui.form.on("Customize Form", {
|
|||
onload: function(frm) {
|
||||
frm.set_query("doc_type", function() {
|
||||
return {
|
||||
translate_values: false,
|
||||
filters: [
|
||||
["DocType", "issingle", "=", 0],
|
||||
["DocType", "custom", "=", 0],
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
"view_settings_section",
|
||||
"title_field",
|
||||
"show_title_field_in_link",
|
||||
"translate_link_fields",
|
||||
"image_field",
|
||||
"default_print_format",
|
||||
"column_break_29",
|
||||
|
|
@ -311,6 +312,12 @@
|
|||
"fieldname": "show_title_field_in_link",
|
||||
"fieldtype": "Check",
|
||||
"label": "Show Title in Link Fields"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "translate_link_fields",
|
||||
"fieldtype": "Check",
|
||||
"label": "Translate Link Fields"
|
||||
}
|
||||
],
|
||||
"hide_toolbar": 1,
|
||||
|
|
@ -319,7 +326,7 @@
|
|||
"index_web_pages_for_search": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2022-05-12 15:36:16.772277",
|
||||
"modified": "2022-05-13 15:36:16.772277",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Custom",
|
||||
"name": "Customize Form",
|
||||
|
|
|
|||
|
|
@ -577,6 +577,7 @@ doctype_properties = {
|
|||
"naming_rule": "Data",
|
||||
"autoname": "Data",
|
||||
"show_title_field_in_link": "Check",
|
||||
"translate_link_fields": "Check",
|
||||
}
|
||||
|
||||
docfield_properties = {
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ CREATE TABLE `tabDocType` (
|
|||
`sender_field` varchar(255) DEFAULT NULL,
|
||||
`show_title_field_in_link` int(1) NOT NULL DEFAULT 0,
|
||||
`migration_hash` varchar(255) DEFAULT NULL,
|
||||
`translate_link_fields` int(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`name`)
|
||||
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC CHARACTER SET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
|
|
|
|||
|
|
@ -231,6 +231,7 @@ CREATE TABLE "tabDocType" (
|
|||
"sender_field" varchar(255) DEFAULT NULL,
|
||||
"show_title_field_in_link" smallint NOT NULL DEFAULT 0,
|
||||
"migration_hash" varchar(255) DEFAULT NULL,
|
||||
"translate_link_fields" smallint NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY ("name")
|
||||
) ;
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat
|
|||
|
||||
if(!me.$input.val()) {
|
||||
me.$input.val("").trigger("input");
|
||||
|
||||
// hide link arrow to doctype if none is set
|
||||
me.$link.toggle(false);
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
|
|
@ -78,6 +81,12 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat
|
|||
}
|
||||
this.set_link_title(value);
|
||||
}
|
||||
get_translated(value) {
|
||||
return this.is_translatable() ? __(value) : value;
|
||||
}
|
||||
is_translatable() {
|
||||
return in_list(frappe.boot?.translatable_doctypes || [], this.get_options());
|
||||
}
|
||||
set_link_title(value) {
|
||||
let doctype = this.get_options();
|
||||
|
||||
|
|
@ -89,25 +98,32 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat
|
|||
link_title = frappe.utils
|
||||
.fetch_link_title(doctype, value)
|
||||
.then(link_title => {
|
||||
this.set_input_value(link_title);
|
||||
this.title_value_map[link_title] = value;
|
||||
this.translate_and_set_input_value(link_title, value);
|
||||
});
|
||||
} else {
|
||||
this.set_input_value(link_title);
|
||||
this.title_value_map[link_title] = value;
|
||||
this.translate_and_set_input_value(link_title, value);
|
||||
}
|
||||
} else {
|
||||
this.set_input_value(value);
|
||||
this.translate_and_set_input_value(value, value)
|
||||
}
|
||||
}
|
||||
translate_and_set_input_value(link_title, value) {
|
||||
let translated_link_text = this.get_translated(link_title)
|
||||
this.title_value_map[translated_link_text] = value;
|
||||
|
||||
this.set_input_value(translated_link_text);
|
||||
}
|
||||
parse_validate_and_set_in_model(value, e, label) {
|
||||
if (this.parse) value = this.parse(value, label);
|
||||
if (label) {
|
||||
this.label = label;
|
||||
this.label = this.get_translated(label);
|
||||
frappe.utils.add_link_title(this.df.options, value, label);
|
||||
}
|
||||
|
||||
return this.validate_and_set_in_model(value, e);
|
||||
return this.validate_and_set_in_model(value, e, true);
|
||||
}
|
||||
parse(value) {
|
||||
return strip_html(value);
|
||||
}
|
||||
get_input_value() {
|
||||
if (this.$input) {
|
||||
|
|
@ -164,7 +180,7 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat
|
|||
return false;
|
||||
}
|
||||
setup_awesomeplete() {
|
||||
var me = this;
|
||||
let me = this;
|
||||
|
||||
this.$input.cache = {};
|
||||
|
||||
|
|
@ -173,14 +189,14 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat
|
|||
maxItems: 99,
|
||||
autoFirst: true,
|
||||
list: [],
|
||||
replace: function (suggestion) {
|
||||
replace: function (item) {
|
||||
// Override Awesomeplete replace function as it is used to set the input value
|
||||
// https://github.com/LeaVerou/awesomplete/issues/17104#issuecomment-359185403
|
||||
this.input.value = suggestion.label || suggestion.value;
|
||||
this.input.value = me.get_translated(item.label || item.value);
|
||||
},
|
||||
data: function (item) {
|
||||
return {
|
||||
label: item.label || item.value,
|
||||
label: me.get_translated(item.label || item.value),
|
||||
value: item.value
|
||||
};
|
||||
},
|
||||
|
|
@ -188,11 +204,11 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat
|
|||
return true;
|
||||
},
|
||||
item: function (item) {
|
||||
var d = this.get_item(item.value);
|
||||
let d = this.get_item(item.value);
|
||||
if(!d.label) { d.label = d.value; }
|
||||
|
||||
var _label = (me.translate_values) ? __(d.label) : d.label;
|
||||
var html = d.html || "<strong>" + _label + "</strong>";
|
||||
let _label = me.get_translated(d.label);
|
||||
let html = d.html || "<strong>" + _label + "</strong>";
|
||||
if(d.description && d.value!==d.description) {
|
||||
html += '<br><span class="small">' + __(d.description) + '</span>';
|
||||
}
|
||||
|
|
@ -304,10 +320,20 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat
|
|||
|
||||
this.$input.on("awesomplete-open", () => {
|
||||
this.autocomplete_open = true;
|
||||
|
||||
if (!me.get_label_value()) {
|
||||
// hide link arrow to doctype if none is set
|
||||
me.$link.toggle(false);
|
||||
}
|
||||
});
|
||||
|
||||
this.$input.on("awesomplete-close", () => {
|
||||
this.$input.on("awesomplete-close", (e) => {
|
||||
this.autocomplete_open = false;
|
||||
|
||||
if (!me.get_label_value()) {
|
||||
// hide link arrow to doctype if none is set
|
||||
me.$link.toggle(false);
|
||||
}
|
||||
});
|
||||
|
||||
this.$input.on("awesomplete-select", function(e) {
|
||||
|
|
@ -317,7 +343,7 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat
|
|||
me.autocomplete_open = false;
|
||||
|
||||
// prevent selection on tab
|
||||
var TABKEY = 9;
|
||||
let TABKEY = 9;
|
||||
if (e.keyCode === TABKEY) {
|
||||
e.preventDefault();
|
||||
me.awesomplete.close();
|
||||
|
|
@ -347,6 +373,24 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat
|
|||
me.$input.val("");
|
||||
}
|
||||
});
|
||||
|
||||
this.$input.on("focus", function () {
|
||||
if (!frappe.boot.translated_search_doctypes.includes(me.df.options)) {
|
||||
me.show_untranslated();
|
||||
}
|
||||
});
|
||||
|
||||
this.$input.keydown((e) => {
|
||||
let BACKSPACE = 8;
|
||||
if (e.keyCode === BACKSPACE && !frappe.boot.translated_search_doctypes.includes(me.df.options)) {
|
||||
me.show_untranslated();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
show_untranslated() {
|
||||
let value = this.get_input_value();
|
||||
this.is_translatable() && this.set_input_value(value);
|
||||
}
|
||||
|
||||
merge_duplicates(results) {
|
||||
|
|
@ -591,4 +635,3 @@ if (Awesomplete) {
|
|||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -161,4 +161,14 @@ frappe.ui.form.ControlTableMultiSelect = class ControlTableMultiSelect extends f
|
|||
return true;
|
||||
};
|
||||
}
|
||||
get_input_value() {
|
||||
return this.$input ? this.$input.val() : undefined;
|
||||
}
|
||||
update_value() {
|
||||
let value = this.get_input_value();
|
||||
|
||||
if (value !== this.last_value) {
|
||||
this.parse_validate_and_set_in_model(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -184,6 +184,7 @@ def get():
|
|||
frappe.get_attr(hook)(bootinfo=bootinfo)
|
||||
|
||||
bootinfo["lang"] = frappe.translate.get_user_lang()
|
||||
bootinfo["translated_search_doctypes"] = frappe.get_hooks("translated_search_doctypes")
|
||||
bootinfo["disable_async"] = frappe.conf.disable_async
|
||||
|
||||
bootinfo["setup_complete"] = cint(frappe.db.get_single_value("System Settings", "setup_complete"))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue