From 745d00362ab8353bf88457b05f090c470f780ef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Thu, 16 Nov 2017 11:10:03 +0100 Subject: [PATCH] [FIX] web: make sure modifiers works for async widgets Before this commit, asynchronous field widgets (with willStart async), with a non empty template had a problem: the invisible modifier was not applied properly. The reason is that the code that applied the modifiers was called directly after the widget was 'willStarted'. This means that if this is async, and if there is a template, the $el in willStart will be replaced by another $el after, which will remove the invisible modifier. This was an interesting problem with the pad widget (it is asynchronous the first time a pad widget is instantiated) --- .../src/js/views/basic/basic_renderer.js | 21 ++++++----- addons/web/static/tests/views/form_tests.js | 36 +++++++++++++++++++ 2 files changed, 48 insertions(+), 9 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 09b264be0b5..7b5cd87daaa 100644 --- a/addons/web/static/src/js/views/basic/basic_renderer.js +++ b/addons/web/static/src/js/views/basic/basic_renderer.js @@ -484,15 +484,18 @@ var BasicRenderer = AbstractRenderer.extend({ // Update the modifiers registration by associating the widget and by // giving the modifiers options now (as the potential callback is // associated to new widget) - this._registerModifiers(node, record, widget, _.extend({ - callback: (function (element, modifiers, record) { - element.$el.toggleClass('o_field_empty', !!( - record.data.id - && (modifiers.readonly || this.mode === 'readonly') - && !element.widget.isSet() - )); - }).bind(this), - }, modifiersOptions || {})); + var self = this; + def.then(function () { + self._registerModifiers(node, record, widget, _.extend({ + callback: function (element, modifiers, record) { + element.$el.toggleClass('o_field_empty', !!( + record.data.id + && (modifiers.readonly || self.mode === 'readonly') + && !element.widget.isSet() + )); + }, + }, modifiersOptions || {})); + }); return widget; }, diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js index 5b5cb002412..5fdcb2b1ae3 100644 --- a/addons/web/static/tests/views/form_tests.js +++ b/addons/web/static/tests/views/form_tests.js @@ -4,6 +4,7 @@ odoo.define('web.form_tests', function (require) { var concurrency = require('web.concurrency'); var config = require('web.config'); var core = require('web.core'); +var fieldRegistry = require('web.field_registry'); var FormView = require('web.FormView'); var testUtils = require('web.test_utils'); @@ -305,6 +306,41 @@ QUnit.module('Views', { form.destroy(); }); + QUnit.test('asynchronous fields can be set invisible', function (assert) { + assert.expect(1); + + var def = $.Deferred(); + + // we choose this widget because it is a quite simple widget with a non + // empty qweb template + var PercentPieWidget = fieldRegistry.get('percentpie'); + fieldRegistry.add('asyncwidget', PercentPieWidget.extend({ + willStart: function () { + return def; + }, + })); + + createAsyncView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + '' + + '' + + '' + + '' + + '
', + res_id: 1, + }).then(function (form) { + assert.ok(form.$('.o_field_widget[name="int_field"]').hasClass('o_invisible_modifier'), + 'int_field is invisible'); + form.destroy(); + delete fieldRegistry.map.asyncwidget; + }); + def.resolve(); + }); + + QUnit.test('properly handle modifiers and attributes on notebook tags', function (assert) { assert.expect(2);