From 921562a1dd422ae9b84886303ca5741ff4e50502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 25 Aug 2026 13:09:25 +0200 Subject: [PATCH] Ensure it is still the same record when executing the display callback of a widget When a widget display is asynchronous, we must ensure that it is still the same record that is being displayed when the callback is finally executed. Otherwise it may render the data of a different record in the HTML. Closes #15041 (grafted from dbd215ffb07150c2f476922bd7c66dc896ed2665) --HG-- branch : 8.0 --- sao/src/view/form.js | 82 +++++++++++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 23 deletions(-) diff --git a/sao/src/view/form.js b/sao/src/view/form.js index f465bebed5..d69fd05f2a 100644 --- a/sao/src/view/form.js +++ b/sao/src/view/form.js @@ -2278,14 +2278,22 @@ function eval_pyson(value){ Sao.common.selection_mixin.init_selection.call(this, key, this.set_selection.bind(this)); }, - update_selection: function(record, field, callbak) { + update_selection: function(record, field, callback) { + let deferred = jQuery.Deferred(); Sao.common.selection_mixin.update_selection.call(this, record, field, (selection, help) => { this.set_selection(selection, help); - if (callbak) { - callbak(selection, help); + let prm; + if (callback) { + prm = callback(selection, help); + } + if (prm) { + prm.always(deferred.resolve); + } else { + deferred.resolve(); } }); + return deferred; }, set_selection: function(selection, help) { var select = this.select; @@ -2299,9 +2307,13 @@ function eval_pyson(value){ } }, display_update_selection: function() { - var record = this.record; - var field = this.field; - this.update_selection(record, field, (selection, help) => { + let record = this.record, + field = this.field; + return this.update_selection(record, field, (selection, help) => { + if (record !== this.record) { + return; + } + if (!field) { this.select.val(''); return; @@ -2317,7 +2329,7 @@ function eval_pyson(value){ if (!found) { prm = Sao.common.selection_mixin.get_inactive_selection .call(this, value); - prm.done(inactive => { + prm = prm.then(inactive => { this.select.append(jQuery('