diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js
index 3687c622039..2e14ee56e8d 100644
--- a/addons/web/static/src/js/fields/relational_fields.js
+++ b/addons/web/static/src/js/fields/relational_fields.js
@@ -726,8 +726,13 @@ var FieldMany2One = AbstractField.extend({
readonly: !self.can_write,
on_saved: function (record, changed) {
if (changed) {
- self._setValue(self.value.data, {forceChange: true}).then(function() {
- self.trigger_up('reload', {db_id: self.value.id});
+ const _setValue = self._setValue.bind(self, self.value.data, {
+ forceChange: true,
+ });
+ self.trigger_up('reload', {
+ db_id: self.value.id,
+ onSuccess: _setValue,
+ onFailure: _setValue,
});
}
},
diff --git a/addons/web/static/src/js/views/basic/basic_controller.js b/addons/web/static/src/js/views/basic/basic_controller.js
index df1a03e0f42..7639d2dea99 100644
--- a/addons/web/static/src/js/views/basic/basic_controller.js
+++ b/addons/web/static/src/js/views/basic/basic_controller.js
@@ -705,21 +705,25 @@ var BasicController = AbstractController.extend(FieldManagerMixin, {
* re-render (reload the whole form by default)
* @param {string[]} [ev.data.fieldNames] list of the record's fields to
* reload
+ * @param {Function} [ev.data.onSuccess] callback executed after reload is resolved
+ * @param {Function} [ev.data.onFailure] callback executed when reload is rejected
*/
_onReload: function (ev) {
ev.stopPropagation(); // prevent other controllers from handling this request
var data = ev && ev.data || {};
var handle = data.db_id;
+ var prom;
if (handle) {
// reload the relational field given its db_id
- this.model.reload(handle).then(this._confirmSave.bind(this, handle));
+ prom = this.model.reload(handle).then(this._confirmSave.bind(this, handle));
} else {
// no db_id given, so reload the main record
- this.reload({
+ prom = this.reload({
fieldNames: data.fieldNames,
keepChanges: data.keepChanges || false,
});
}
+ prom.then(ev.data.onSuccess).guardedCatch(ev.data.onFailure);
},
/**
* Resequence records in the given order.
diff --git a/addons/web/static/tests/fields/relational_fields/field_many2one_tests.js b/addons/web/static/tests/fields/relational_fields/field_many2one_tests.js
index a8743a4cddf..081bd4e3598 100644
--- a/addons/web/static/tests/fields/relational_fields/field_many2one_tests.js
+++ b/addons/web/static/tests/fields/relational_fields/field_many2one_tests.js
@@ -557,7 +557,7 @@ QUnit.module('fields', {}, function () {
// save the modal and make sure an onchange is triggered
await testUtils.dom.click($('.modal .modal-footer .btn-primary').first());
- assert.verifySteps(['read', 'get_formview_id', 'load_views', 'read', 'write', 'onchange', 'read']);
+ assert.verifySteps(['read', 'get_formview_id', 'load_views', 'read', 'write', 'read', 'onchange']);
// save the main record, and check that no extra rpcs are done (record
// is not dirty, only a related record was modified)
diff --git a/addons/web/static/tests/views/list_tests.js b/addons/web/static/tests/views/list_tests.js
index 141a98e9a80..32c868a9bb0 100644
--- a/addons/web/static/tests/views/list_tests.js
+++ b/addons/web/static/tests/views/list_tests.js
@@ -6074,6 +6074,48 @@ QUnit.module('Views', {
list.destroy();
});
+ QUnit.test('editable list: edit many2one from external link', async function (assert) {
+ assert.expect(2);
+
+ const list = await createView({
+ arch: `
+