[FIX] web: multi edit list: crash after validating with ENTER

Have a multi edit list view, select several records and edit a
field represented by an input (e.g. a char field). After typing the
new value, press ENTER to validate. The confirmation dialog opens,
click on OK/Confirm to save. Before this commit, an error was
thrown afterwards, because we tried to retrieve the value from the
input, but the input doesn't exist anymore as the edited row has
already been switched back to readonly. This commit fixes the
issue.

closes odoo/odoo#119082

Related: odoo/enterprise#40012
Signed-off-by: Géry Debongnie <ged@odoo.com>
This commit is contained in:
Aaron Bohy
2023-04-21 23:46:11 +02:00
parent 105299eb1d
commit e8b75e4d99
2 changed files with 48 additions and 2 deletions
@@ -150,9 +150,10 @@ export function useInputField(params) {
}
if ((val || false) !== (component.props.record.data[component.props.name] || false)) {
const nextValue = inputRef.el.value;
await component.props.record.update({ [component.props.name]: val });
lastSetValue = inputRef.el.value;
component.props.record.model.bus.trigger("FIELD_IS_DIRTY", isDirty);
component.props.record.model.bus.trigger("FIELD_IS_DIRTY", false);
lastSetValue = nextValue;
}
}
}
@@ -14316,6 +14316,51 @@ QUnit.module("Views", (hooks) => {
assert.strictEqual(document.activeElement, getDataRow(3).querySelector("[name=foo] input"));
});
QUnit.test("multi-edit records with ENTER does not crash", async (assert) => {
serviceRegistry.add("error", errorService);
const def = makeDeferred();
await makeView({
type: "list",
resModel: "foo",
serverData,
arch: `
<tree multi_edit="1">
<field name="foo"/>
<field name="int_field"/>
</tree>
`,
async mockRPC(route, args) {
if (args.method === "write") {
await def;
}
},
});
await click(getDataRow(2).querySelector(".o_data_row .o_list_record_selector input"));
await click(getDataRow(3).querySelector(".o_data_row .o_list_record_selector input"));
await click(getDataRow(2).querySelector(".o_data_row .o_data_cell[name=int_field]"));
assert.containsOnce(target, ".o_selected_row");
const input = getDataRow(2).querySelector("[name=int_field] input");
assert.strictEqual(document.activeElement, input);
input.value = "234";
await triggerEvent(input, null, "input");
triggerHotkey("Enter");
await triggerEvent(input, null, "change");
assert.containsOnce(target, ".o_dialog"); // confirmation dialog
await click(target.querySelector(".o_dialog .modal-footer .btn-primary"));
await new Promise((r) => setTimeout(r, 20)); // delay a bit the save s.t. there's a rendering
def.resolve();
await nextTick();
assert.deepEqual(
getNodesTextContent(target.querySelectorAll(".o_data_cell.o_list_number")),
["10", "234", "234", "-4"]
);
assert.containsNone(target, ".o_dialog"); // no more confirmation dialog, no error dialog
});
QUnit.test(
"editable grouped list: adding a second record pass the first in readonly",
async (assert) => {