From afa12b9f041b6962dff8ed0cea32a8a20f5f2479 Mon Sep 17 00:00:00 2001 From: FrancoisGe Date: Tue, 12 Jul 2022 12:01:47 +0000 Subject: [PATCH] [FIX] web: X2many in list mode with several records in edition Before this commit, in an x2many in list mode, it was possible to switch several records to edit mode. Normally, it is not possible to have more than one record in edit mode in a list mode X2many. How to reproduce: - Have an X2many with at least two record already. - Modify a field of the first line and make it invalid - Click on the second record Result before the commit: Both records will be in edit mode. Result after the commit: The invalid record stays in edit mode and the other record stays in readonly mode. Part-of: odoo/odoo#96101 --- .../src/views/basic_relational_model.js | 8 +++- .../views/fields/one2many_field_tests.js | 38 +++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/views/basic_relational_model.js b/addons/web/static/src/views/basic_relational_model.js index 69fae62578c..4ba0d9397c5 100644 --- a/addons/web/static/src/views/basic_relational_model.js +++ b/addons/web/static/src/views/basic_relational_model.js @@ -790,8 +790,12 @@ export class StaticList extends DataPoint { } if (editedRecord) { const isValid = editedRecord.checkValidity(); - if (!isValid && editedRecord.canBeAbandoned) { - this.abandonRecord(editedRecord.id); + if (!isValid) { + if (editedRecord.canBeAbandoned) { + this.abandonRecord(editedRecord.id); + } else { + return false; + } } else { await editedRecord.switchMode("readonly"); } 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 bc0a0a563d4..e781d0ee9d6 100644 --- a/addons/web/static/tests/views/fields/one2many_field_tests.js +++ b/addons/web/static/tests/views/fields/one2many_field_tests.js @@ -7890,6 +7890,44 @@ QUnit.module("Fields", (hooks) => { } ); + QUnit.test("one2many with invalid value and click on another row", async function (assert) { + serverData.models.partner.records[0].p = [2, 4]; + + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: ` +
+ + + + + + +
`, + resId: 1, + }); + await clickEdit(target); + + let rows = target.querySelectorAll(".o_data_row"); + await click(rows[0].querySelector(".o_data_cell")); + assert.containsOnce(target, ".o_data_row.o_selected_row"); + rows = target.querySelectorAll(".o_data_row"); + assert.hasClass(rows[0], "o_selected_row"); + assert.doesNotHaveClass(rows[1], "o_selected_row"); + + await editInput(target, ".o_data_row [name='int_field'] input", "abc"); + rows = target.querySelectorAll(".o_data_row"); + await click(rows[1].querySelector(".o_data_cell")); + // Stays on the invalid row + assert.containsOnce(target, ".o_data_row.o_selected_row"); + rows = target.querySelectorAll(".o_data_row"); + assert.hasClass(rows[0], "o_selected_row"); + assert.containsOnce(rows[0], "[name='int_field'] .o_field_invalid"); + assert.doesNotHaveClass(rows[1], "o_selected_row"); + }); + QUnit.test( "default value for nested one2manys (coming from onchange)", async function (assert) {