diff --git a/addons/web/static/src/views/fields/input_field_hook.js b/addons/web/static/src/views/fields/input_field_hook.js index 030cb50b411..7eb9d3824e3 100644 --- a/addons/web/static/src/views/fields/input_field_hook.js +++ b/addons/web/static/src/views/fields/input_field_hook.js @@ -147,7 +147,7 @@ export function useInputField(params) { return; } - if (val !== component.props.value) { + if ((val || false) !== (component.props.value || false)) { await component.props.update(val); lastSetValue = inputRef.el.value; if (component.props.setDirty) { 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 bcd205e3249..45c0437e905 100644 --- a/addons/web/static/tests/views/form/form_view_tests.js +++ b/addons/web/static/tests/views/form/form_view_tests.js @@ -11670,6 +11670,40 @@ QUnit.module("Views", (hooks) => { assert.verifySteps([], "should not save because we do not change anything"); }); + QUnit.test("Auto save: save on closing tab/browser (not dirty) with text field", async function (assert) { + + serverData.models.partner.fields.bloup = { + string: "Bloup", + type: "text", + default: false, + }; + + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: ` +
`, + resId: 1, + mockRPC(route, { args, method, model }) { + if (method === "write" && model === "partner") { + assert.step("save"); // should not be called + } + }, + }); + + assert.strictEqual(target.querySelector(".o_field_widget[name=bloup] textarea").value, "", "should contain the default value"); + + window.dispatchEvent(new Event("beforeunload")); + await nextTick(); + + assert.verifySteps([], "should not save because we do not change anything"); + }); + QUnit.test("Auto save: save on closing tab/browser (detached form)", async function (assert) { serverData.actions[1] = { id: 1,