diff --git a/addons/web/static/src/views/record.js b/addons/web/static/src/views/record.js index 29dbb85d1dd..ab9dac7fead 100644 --- a/addons/web/static/src/views/record.js +++ b/addons/web/static/src/views/record.js @@ -15,6 +15,8 @@ class _Record extends Component { viewMode: "form", rootType: "record", activeFields: this.getActiveFields(), + onRecordSaved: this.props.info.onRecordSaved || (() => {}), + onWillSaveRecord: this.props.info.onWillSaveRecord || (() => {}), }; const modelServices = Object.fromEntries( RelationalModel.services.map((servName) => { @@ -107,4 +109,6 @@ Record.props = [ "mode?", "values?", "onRecordChanged?", + "onRecordSaved?", + "onWillSaveRecord?", ]; diff --git a/addons/web/static/tests/views/record_tests.js b/addons/web/static/tests/views/record_tests.js index 4008695ff74..1c47aa11ee4 100644 --- a/addons/web/static/tests/views/record_tests.js +++ b/addons/web/static/tests/views/record_tests.js @@ -240,6 +240,43 @@ QUnit.module("Record Component", (hooks) => { assert.strictEqual(target.querySelector("[name='foo'] input").value, "753"); }); + QUnit.test("provides a way to handle before/after saved the record", async function (assert) { + class Parent extends Component { + onRecordSaved(record) { + assert.step("onRecordSaved"); + } + + onWillSaveRecord(record) { + assert.step("onWillSaveRecord"); + } + } + Parent.components = { Record, Field }; + Parent.template = xml` + + + + `; + + const env = await makeTestEnv({ + serverData, + mockRPC(route, args) { + assert.step(args.method); + }, + }); + await mount(Parent, target, { env }); + + await editInput(target, "[name='foo'] input", "abc"); + await click(target, "button.save"); + assert.verifySteps([ + "fields_get", + "read", + "onWillSaveRecord", + "write", + "read", + "onRecordSaved", + ]); + }); + QUnit.test("handles many2one fields", async function (assert) { patchWithCleanup(browser, { setTimeout: (fn) => fn(),