diff --git a/addons/web/static/src/views/fields/relational_utils.js b/addons/web/static/src/views/fields/relational_utils.js index 585cc222ac9..68d0038adc8 100644 --- a/addons/web/static/src/views/fields/relational_utils.js +++ b/addons/web/static/src/views/fields/relational_utils.js @@ -558,7 +558,10 @@ async function getFormViewInfo({ list, activeField, viewService, userService, en views: [[false, "form"]], }); const archInfo = new FormArchParser().parse(views.form.arch, relatedModels, comodel); - formViewInfo = { ...archInfo, fields }; // should be good to memorize this on activeField + // Fields that need to be defined are the ones in the form view, this is natural, + // plus the ones that the list record has, that is, present in either the list arch or the kanban arch + // of the one2many field + formViewInfo = { ...archInfo, fields: { ...list.fields, ...fields } }; // should be good to memorize this on activeField } await loadSubViews( diff --git a/addons/web/static/tests/views/fields/one2many_field_tests.js b/addons/web/static/tests/views/fields/one2many_field_tests.js index 9f4f2bf043a..ebabc21cea9 100644 --- a/addons/web/static/tests/views/fields/one2many_field_tests.js +++ b/addons/web/static/tests/views/fields/one2many_field_tests.js @@ -12500,4 +12500,57 @@ QUnit.module("Fields", (hooks) => { assert.hasAttrValue(target.querySelector(".o_dialog .o_form_button_save_new"), "disabled", undefined); assert.hasAttrValue(target.querySelector(".o_dialog .o_form_button_cancel"), "disabled", undefined); }); + + QUnit.test("field in list but not in fetched form", async function (assert) { + serverData.models.partner.fields.o2m = { + type: "one2many", + relation: "partner_type", + relation_field: "p_id", + }; + serverData.models.partner_type.onchanges = { + display_name: (rec) => { + if (rec.display_name === "changed") { + rec.color = 5; + } + }, + }; + + serverData.models.partner_type.fields.p_id = { type: "many2one", relation: "partner" }; + serverData.views = { + "partner_type,false,form": `
`, + }; + + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: ` + `, + mockRPC(route, args) { + assert.step(`${args.method}: ${args.model}`); + }, + }); + + assert.verifySteps(["get_views: partner", "onchange: partner"]); + await click(target, ".o_field_x2many_list_row_add a"); + assert.verifySteps(["get_views: partner_type", "onchange: partner_type"]); + await editInput( + target.querySelector(".modal"), + ".o_field_widget[name='display_name'] input", + "changed" + ); + assert.verifySteps(["onchange: partner_type"]); + await click(target.querySelector(".modal .o_form_button_save")); + assert.strictEqual(target.querySelector(".o_data_row").textContent, "changed5"); + await click(target, ".o_form_button_save"); + assert.verifySteps(["create: partner", "read: partner", "read: partner_type"]); + assert.strictEqual(target.querySelector(".o_data_row").textContent, "changed5"); + }); });