diff options
| author | Nicolas Lempereur <nle@odoo.com> | 2020-01-10 16:01:25 +0000 |
|---|---|---|
| committer | Nicolas Lempereur <nle@odoo.com> | 2020-01-13 17:59:30 +0000 |
| commit | b048a6fc2750bb2111c5627b054bbfde5b8e8cfa (patch) | |
| tree | 3d2b2b4b15f52d879f0462ca7ca266246c0436e1 /addons/web/static/src/js/views/basic/basic_renderer.js | |
| parent | ac930249ba09b2aad572799ea8c04c4b13283ae9 (diff) | |
[FIX] web: widget noreset if rerendered for modifier
If we have a many2many_tags widget that is writable then becomes
readonly, we can have in the code this chain of event:
- get list of widgets we need to reset some data for
- apply modifiers
- reset the widgets
but applying modifiers can delete a widget (eg. an editable field that
becomes readonly), so when resetting we could call code on a deleted
widget which caused an error.
For example, if we have an attribute:
`<field widget="many2many_tags" attrs="{'readonly': 'condition'}"/>`
if the field goes from editable to readonly and is affected by an
onchange, we will call `setIDForLabel` on the deleted instance of the
widget which will cause an error.
Added test without fix fails with error:
TypeError: Cannot read property 'attr' of undefined
at Class.setIDForLabel (/web/static/src/js/fields/abstract_field.js:324:35)
because as said, the function is called on the editable widget that is
removed and replaced with readonly widget at that point.
opw-2154471
closes #43137
closes odoo/odoo#43244
X-original-commit: 6f5ca16524be7c5bb45b03e7421154a20edc4cf6
Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com>
Diffstat (limited to 'addons/web/static/src/js/views/basic/basic_renderer.js')
| -rw-r--r-- | addons/web/static/src/js/views/basic/basic_renderer.js | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/addons/web/static/src/js/views/basic/basic_renderer.js b/addons/web/static/src/js/views/basic/basic_renderer.js index 99e6926d503..8af8540dd57 100644 --- a/addons/web/static/src/js/views/basic/basic_renderer.js +++ b/addons/web/static/src/js/views/basic/basic_renderer.js @@ -93,6 +93,7 @@ var BasicRenderer = AbstractRenderer.extend({ * that have been reset */ confirmChange: function (state, id, fields, ev) { + var self = this; this.state = state; var record = this._getRecord(id); if (!record) { @@ -106,12 +107,10 @@ var BasicRenderer = AbstractRenderer.extend({ // Reset all the field widgets that are marked as changed and the ones // which are configured to always be reset on any change - var resetWidgets = []; _.each(this.allFieldWidgets[id], function (widget) { var fieldChanged = _.contains(fields, widget.name); if (fieldChanged || widget.resetOnAnyFieldChange) { defs.push(widget.reset(record, ev, fieldChanged)); - resetWidgets.push(widget); } }); @@ -121,7 +120,10 @@ var BasicRenderer = AbstractRenderer.extend({ defs.push(this._updateAllModifiers(record)); return Promise.all(defs).then(function () { - return resetWidgets; + return _.filter(self.allFieldWidgets[id], function (widget) { + var fieldChanged = _.contains(fields, widget.name); + return fieldChanged || widget.resetOnAnyFieldChange; + }); }); }, /** |
