diff --git a/addons/web/static/src/views/form/form_arch_parser.js b/addons/web/static/src/views/form/form_arch_parser.js index 0ac621be33a..3dc52ceec9c 100644 --- a/addons/web/static/src/views/form/form_arch_parser.js +++ b/addons/web/static/src/views/form/form_arch_parser.js @@ -29,14 +29,22 @@ export class FormArchParser extends XMLParser { if (archParseBoolean(node.getAttribute("default_focus") || "")) { autofocusFieldId = fieldId; } - addFieldDependencies(activeFields, fieldInfo.FieldComponent.fieldDependencies); + addFieldDependencies( + activeFields, + models[modelName], + fieldInfo.FieldComponent.fieldDependencies + ); return false; } else if (node.tagName === "div" && node.classList.contains("oe_chatter")) { // remove this when chatter fields are declared as attributes on the root node return false; } else if (node.tagName === "widget") { const { WidgetComponent } = Widget.parseWidgetNode(node); - addFieldDependencies(activeFields, WidgetComponent.fieldDependencies); + addFieldDependencies( + activeFields, + models[modelName], + WidgetComponent.fieldDependencies + ); } }); // TODO: generate activeFields for the model based on fieldNodes (merge duplicated fields) diff --git a/addons/web/static/src/views/kanban/kanban_arch_parser.js b/addons/web/static/src/views/kanban/kanban_arch_parser.js index e0328de8922..e97fcc897e6 100644 --- a/addons/web/static/src/views/kanban/kanban_arch_parser.js +++ b/addons/web/static/src/views/kanban/kanban_arch_parser.js @@ -84,11 +84,19 @@ export class KanbanArchParser extends XMLParser { if (fieldInfo.widget === "handle") { handleField = name; } - addFieldDependencies(activeFields, fieldInfo.FieldComponent.fieldDependencies); + addFieldDependencies( + activeFields, + models[modelName], + fieldInfo.FieldComponent.fieldDependencies + ); } if (node.tagName === "widget") { const { WidgetComponent } = Widget.parseWidgetNode(node); - addFieldDependencies(activeFields, WidgetComponent.fieldDependencies); + addFieldDependencies( + activeFields, + models[modelName], + WidgetComponent.fieldDependencies + ); } // Keep track of last update so images can be reloaded when they may have changed. diff --git a/addons/web/static/src/views/list/list_arch_parser.js b/addons/web/static/src/views/list/list_arch_parser.js index fe415739c4e..f945dcdb423 100644 --- a/addons/web/static/src/views/list/list_arch_parser.js +++ b/addons/web/static/src/views/list/list_arch_parser.js @@ -86,7 +86,11 @@ export class ListArchParser extends XMLParser { if (fieldInfo.widget === "handle") { handleField = fieldInfo.name; } - addFieldDependencies(activeFields, fieldInfo.FieldComponent.fieldDependencies); + addFieldDependencies( + activeFields, + models[modelName], + fieldInfo.FieldComponent.fieldDependencies + ); if (fieldInfo.modifiers.column_invisible !== true) { const label = fieldInfo.FieldComponent.label; columns.push({ diff --git a/addons/web/static/src/views/utils.js b/addons/web/static/src/views/utils.js index f4a58ac957e..f4b03dc9fcd 100644 --- a/addons/web/static/src/views/utils.js +++ b/addons/web/static/src/views/utils.js @@ -13,13 +13,16 @@ const NUMERIC_TYPES = ["integer", "float", "monetary"]; * @param {Object} activeFields * @param {Object} [dependencies={}] */ -export function addFieldDependencies(activeFields, dependencies = {}) { +export function addFieldDependencies(activeFields, fields, dependencies = {}) { for (const [name, dependency] of Object.entries(dependencies)) { if (!(name in activeFields)) { activeFields[name] = Object.assign({ name, rawAttrs: {} }, dependency, { modifiers: { invisible: true }, }); } + if (!(name in fields)) { + fields[name] = { ...dependency }; + } } } diff --git a/addons/web/static/tests/views/form/form_view_tests.js b/addons/web/static/tests/views/form/form_view_tests.js index d166ec06d7d..5bec517bc41 100644 --- a/addons/web/static/tests/views/form/form_view_tests.js +++ b/addons/web/static/tests/views/form/form_view_tests.js @@ -673,6 +673,38 @@ QUnit.module("Views", (hooks) => { } ); + QUnit.test("form with o2m having a field with fieldDependencies", async function (assert) { + // In this scenario, the x2many form view isn't inline, so when we click on the record, + // it does an independant getView, which doesn't return all fields of the model. In the + // x2many list view, there's a field with fieldDependencies, and the dependency field + // (int_field) in our case, isn't in the form view. This test ensures that we can open + // the form view in this situation. + class MyField extends CharField {} + MyField.fieldDependencies = { + int_field: { type: "integer" }, + }; + fieldRegistry.add("my_widget", MyField); + serverData.models.partner.records[1].p = [1]; + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: ` +
`, + resId: 2, + }); + + assert.containsOnce(target, ".o_field_widget[name=p] .o_data_row"); + await click(target.querySelector(".o_field_widget[name=p] .o_data_row .o_data_cell")); + assert.containsOnce(target, ".modal .o_form_view .o_field_widget[name=p]"); + }); + QUnit.test("decoration-bf works on fields", async function (assert) { await makeView({ type: "form",