diff options
| author | Aaron Bohy <aab@odoo.com> | 2018-02-08 11:28:45 +0100 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2018-02-09 15:36:14 +0100 |
| commit | 20e4cd5bcd1816a478aedd441efa90a34cf63334 (patch) | |
| tree | c303c24ee64876e97459c717c94cfe0b0e762133 /addons/web/static/src/js/views/basic/basic_renderer.js | |
| parent | 4b43803dc6724339ea99ed43f0594afda6ea7068 (diff) | |
[FIX] web: field widget with readonly modifier
Rev. dbdd742 introduced the 'baseMode' parameter of field's nodes
in the BasicRenderer. Its purpose is to encode the generic mode
of the field, regardless of its readonly modifier (i.e. in form
views, the baseMode of all fields is the mode of the renderer and
in list views, the baseMode of all fields is 'readonly', except for
fields in the row being edited, whose baseMode is 'edit').
Unfortunately, when the value of the readonly modifier of a field
was 'readonly', its baseMode was changed from 'edit' to 'readonly',
which shouldn't, as the baseMode's value should not be affected by
the modifiers.
This produced a bug when a field had a readonly modifier, as once
its value became true, the field was rendered in 'readonly', and
whatever the value of the modifier afterwards, it always remained
in 'readonly'.
The rev. ensures that the baseMode is no longer impacted by the
value of the readonly modifier.
Closes #22729
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 | 51 |
1 files changed, 35 insertions, 16 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 64b90c33022..f5238a95b33 100644 --- a/addons/web/static/src/js/views/basic/basic_renderer.js +++ b/addons/web/static/src/js/views/basic/basic_renderer.js @@ -254,7 +254,10 @@ var BasicRenderer = AbstractRenderer.extend({ if ('readonly' in modifiers && element.widget) { var mode = modifiers.readonly ? 'readonly' : modifiersData.baseMode; if (mode !== element.widget.mode) { - self._rerenderFieldWidget(element.widget, record, mode); + self._rerenderFieldWidget(element.widget, record, { + keepBaseMode: true, + mode: mode, + }); return; // Rerendering already applied the modifiers, no need to go further } } @@ -406,12 +409,25 @@ var BasicRenderer = AbstractRenderer.extend({ * @param {Object} record * @param {jQuery|AbstractField} [element] * @param {Object} [options] - * @param {Object} [options.callback] - the callback to call on registration - * and on modifiers updates + * @param {Object} [options.callback] the callback to call on registration + * and on modifiers updates + * @param {boolean} [options.keepBaseMode=false] this function registers the + * 'baseMode' of the node; this is a field widget specific settings which + * represents the generic mode of the widget, regardless of its modifiers + * (the interesting case is the list view: all widgets are supposed to be + * in the baseMode 'readonly', except the ones that are in the line that + * is currently being edited). + * With option 'keepBaseMode' set to true, the current baseMode of the + * node isn't overridden (this is particularily useful when a field widget + * is re-rendered because its readonly modifier changed, as in this case, + * we don't want to change its base mode). + * @param {string} [options.mode] the 'baseMode' of the node is set to this + * value (if not given, it is set to this.mode, the mode of the renderer) * @returns {Object} for code efficiency, returns the last evaluated - * modifiers for the given node and record. + * modifiers for the given node and record. */ _registerModifiers: function (node, record, element, options) { + options = options || {}; // Check if we already registered the modifiers for the given node // If yes, this is simply an update of the related element // If not, check the modifiers to see if it needs registration @@ -428,12 +444,11 @@ var BasicRenderer = AbstractRenderer.extend({ this.allModifiersData.push(modifiersData); } } - // we register here the base mode of the node. This is a field widget - // specific settings which represents the generic mode for the widget, - // regardless of its modifiers. The interesting case is the list view: - // all widgets are supposed to be in the baseMode 'readonly', except the - // ones that are in the line that is currently being edited. - modifiersData.baseMode = (options && options.mode) || this.mode; + + // Compute node's base mode if necessary + if (!options.keepBaseMode) { + modifiersData.baseMode = options.mode || this.mode; + } // Evaluate if necessary if (!modifiersData.evaluatedModifiers[record.id]) { @@ -494,13 +509,16 @@ var BasicRenderer = AbstractRenderer.extend({ * @private * @param {Object} node * @param {Object} record - * @param {Object} [options] + * @param {Object} [options] passed to @_registerModifiers + * @param {string} [options.mode] either 'edit' or 'readonly' (defaults to + * this.mode, the mode of the renderer) * @returns {AbstractField} */ _renderFieldWidget: function (node, record, options) { + options = options || {}; var fieldName = node.attrs.name; // Register the node-associated modifiers - var mode = options && options.mode || this.mode; + var mode = options.mode || this.mode; var modifiers = this._registerModifiers(node, record, null, options); // Initialize and register the widget // Readonly status is known as the modifiers have just been registered @@ -537,7 +555,8 @@ var BasicRenderer = AbstractRenderer.extend({ && !element.widget.isSet() )); }, - mode: mode + keepBaseMode: !!options.keepBaseMode, + mode: mode, }); self._postProcessField(widget, node); }); @@ -606,12 +625,12 @@ var BasicRenderer = AbstractRenderer.extend({ * @private * @param {Widget} widget * @param {Object} record - * @param {string} mode either 'readonly' or 'edit' + * @param {Object} [options] options passed to @_renderFieldWidget * @returns {AbstractField} */ - _rerenderFieldWidget: function (widget, record, mode) { + _rerenderFieldWidget: function (widget, record, options) { // Render the new field widget - var newWidget = this._renderFieldWidget(widget.__node, record, {mode: mode}); + var newWidget = this._renderFieldWidget(widget.__node, record, options); widget.$el.replaceWith(newWidget.$el); // Destroy the old widget and position the new one at the old one's |
