From 7ff8aa73e17b281b3e2bc4c7275d020eab0204e7 Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Tue, 18 Apr 2017 10:43:10 +0200 Subject: [REF] web, *: implement modifiers behaviors * account, mail, sale Since the views refactoring, modifiers were not properly handled anymore (readonly/required not recomputed, use of readonly/required of "python field" instead of "view field", ...). This commit tries to implement a system which allows to handle the modifiers (re)computation the same way for all the basic views. For this to work, many specialized renderers behaviors have been moved to the basic renderer so that more mechanisms are shared (especially by the form renderer and the list editable renderer). The list editable renderer is hugely impacted by this commit. Here is a list of key changes: - The basic renderer now has a `_renderFieldWidget` function which is used without modification by the form and the list renderers. - Modifiers have to be registered thanks to the basic renderer `_registerModifiersData` function (this is done automatically for fields by the `_renderFieldWidget` function for example). - All instantiated widgets are accessible, organized by record, and ordered in a special basic renderer variable. - The code which resets the widgets of the form view and the code which updates the row of a list editable view is now shared in the basic renderer and now also automatically updates the DOM according to the reevaluated modifiers. - The last point has an huge impact on list editable renderer: all the widgets have to be instantiated when editing a row (even readonly and invisible ones) as they can be switched to editable/visible during edition (after a modifiers update). - `replace_element` and `readonly` options of `AbstractField` are useless: widgets are now always replacing the list editable cells in edition and the `readonly` widget mechanism is replaced by the notion of 'focusable' widgets. (see `AbstractField.getFocusableElement`) - The 'tab' navigation mechanism is impacted by the previous point, some code sharing have been done in basic renderer for this too. - `AbstractField` does not care anymore of the 'required' status, this is the view responsability to check that a required field has a set value on save. - Some list editable bug fixing (e.g. it was possible to edit multiple rows at the same time, it was not possible to navigate towards the previous field, crash on o2m add an item click, ...) - The mockserver now properly simulates server modifiers computation. - ... Note: list editable style may be worse than before this commit but a CSS update is coming in a few days. --- addons/web/static/src/js/fields/basic_fields.js | 38 +++++++------------------ 1 file changed, 10 insertions(+), 28 deletions(-) (limited to 'addons/web/static/src/js/fields/basic_fields.js') diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index d2649195111..9f37240e0cc 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -122,13 +122,12 @@ var InputField = DebouncedField.extend({ //-------------------------------------------------------------------------- /** - * Automatically selects the content of the field. + * Returns the associated element. * * @override */ - activate: function () { - this.$input.focus(); - setTimeout(this.$input.select.bind(this.$input), 0); + getFocusableElement: function () { + return this.$input || $(); }, /** * Do not re-render this field if it was the origin of the onchange call. @@ -171,7 +170,6 @@ var InputField = DebouncedField.extend({ this.$input.addClass('o_form_input'); this.$input.attr({ type: 'text', - id: this.idForLabel, placeholder: this.attrs.placeholder || "", }); // Save cursor position to restore it after updating value @@ -253,7 +251,6 @@ var FieldChar = InputField.extend({ var FieldDate = InputField.extend({ className: "o_form_field_date", tagName: "span", - replace_element: true, supportedFieldTypes: ['date'], /** @@ -274,8 +271,7 @@ var FieldDate = InputField.extend({ }); def = this.datewidget.appendTo('
').done(function () { self.datewidget.$el.addClass(self.$el.attr('class')); - self.datewidget.$input.addClass('o_form_input'); - self.datewidget.$input.attr('id', self.idForLabel); + self._prepareInput(self.datewidget.$input); self.replaceElement(self.datewidget.$el); }); } @@ -371,7 +367,6 @@ var FieldDateTime = FieldDate.extend({ var FieldMonetary = InputField.extend({ className: 'o_form_field_monetary o_list_number', - replace_element: true, supportedFieldTypes: ['float', 'monetary'], resetOnAnyFieldChange: true, // Have to listen to currency changes @@ -484,7 +479,6 @@ var FieldBoolean = AbstractField.extend({ events: _.extend({}, AbstractField.prototype.events, { change: '_onChange', }), - replace_element: true, supportedFieldTypes: ['boolean'], //-------------------------------------------------------------------------- @@ -492,15 +486,12 @@ var FieldBoolean = AbstractField.extend({ //-------------------------------------------------------------------------- /** - * Automatically selects the field. - * * @override + * @returns {jQuery} the focusable checkbox input */ - activate: function () { - this.$input.focus(); - setTimeout(this.$input.select.bind(this.$input), 0); + getFocusableElement: function () { + return this.$input || $(); }, - /** * A boolean field is always set since false is a valid value. * @@ -686,7 +677,6 @@ var FieldText = DebouncedField.extend({ */ start: function () { this.$el.addClass('o_list_text o_form_textarea'); - this.$el.attr('id', this.idForLabel); if (this.mode === 'edit') { this.$textarea = $('