diff options
| author | Christophe Simonis <chs@odoo.com> | 2017-06-09 17:11:47 +0200 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2017-06-09 17:11:47 +0200 |
| commit | ab02bf34b0c1d3fa3752ca1f50b098d04dc5b137 (patch) | |
| tree | a29591cae8777390cbeb35d65e23c9f8ae143135 /addons/web/static/src/js/views | |
| parent | b350c29e44b4ed1df0c428308c396771b22d73e8 (diff) | |
| parent | cc38b93ab2a6daf9c5badbc387cff20d1a01ddee (diff) | |
[MERGE] forward port branch saas-16 up to cc38b93ab2a
Diffstat (limited to 'addons/web/static/src/js/views')
7 files changed, 70 insertions, 26 deletions
diff --git a/addons/web/static/src/js/views/basic/basic_controller.js b/addons/web/static/src/js/views/basic/basic_controller.js index 53e5be8ff6e..16a066db495 100644 --- a/addons/web/static/src/js/views/basic/basic_controller.js +++ b/addons/web/static/src/js/views/basic/basic_controller.js @@ -46,6 +46,9 @@ var BasicController = AbstractController.extend(FieldManagerMixin, { * @returns {Deferred} */ start: function () { + // add classname to reflect the (absence of) access rights (used to + // correctly display the nocontent helper) + this.$el.toggleClass('o_cannot_create', !this.activeActions.create); return this._super.apply(this, arguments) .then(this._updateEnv.bind(this)); }, @@ -186,8 +189,12 @@ var BasicController = AbstractController.extend(FieldManagerMixin, { // user if some discarding has to be made). This operation must also be // mutex-protected as commitChanges function of x2m has to be aware of // all final changes made to a row. - this.mutex.exec(this.renderer.commitChanges.bind(this.renderer, recordID || this.handle)); // TODO write a test for this - return this.mutex.exec(this._saveRecord.bind(this, recordID, options)); + var self = this; + return this.mutex + .exec(this.renderer.commitChanges.bind(this.renderer, recordID || this.handle)) + .then(function () { + return self.mutex.exec(self._saveRecord.bind(self, recordID, options)); + }); }, /** * @override diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js index 60abfde4344..61c285d6581 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -1841,7 +1841,6 @@ var BasicModel = AbstractModel.extend({ return d.res_id === res_id; }); m2mList.data.push(dataPoint.id); - m2mList.count++; }); }); }); @@ -2476,7 +2475,10 @@ var BasicModel = AbstractModel.extend({ // REPLACE_WITH x2manyList.res_ids = value[2]; x2manyList.count = x2manyList.res_ids.length; - defs.push(self._readUngroupedList(x2manyList)); + var def = self._readUngroupedList(x2manyList).then(function () { + return self._fetchX2ManysBatched(x2manyList); + }); + defs.push(def); } }); diff --git a/addons/web/static/src/js/views/field_manager_mixin.js b/addons/web/static/src/js/views/field_manager_mixin.js index 9578e568558..422af121d96 100644 --- a/addons/web/static/src/js/views/field_manager_mixin.js +++ b/addons/web/static/src/js/views/field_manager_mixin.js @@ -99,7 +99,9 @@ var FieldManagerMixin = { // subrecord's form view), otherwise it bubbles up to the main form view // but its model doesn't have any data related to the given dataPointID event.stopPropagation(); - this._applyChanges(event.data.dataPointID, event.data.changes, event); + this._applyChanges(event.data.dataPointID, event.data.changes, event) + .done(event.data.onSuccess || function () {}) + .fail(event.data.onFailure || function () {}); }, /** * Some widgets need to trigger a reload of their data. For example, a diff --git a/addons/web/static/src/js/views/form/form_controller.js b/addons/web/static/src/js/views/form/form_controller.js index ce449f2dcc9..8eef70a916c 100644 --- a/addons/web/static/src/js/views/form/form_controller.js +++ b/addons/web/static/src/js/views/form/form_controller.js @@ -39,12 +39,10 @@ var FormController = BasicController.extend({ //-------------------------------------------------------------------------- /** - * This method is supposed to focus the first active control, I think. It - * is currently only called by the FormViewDialog. - * - * @todo To be implemented + * Calls autofocus on the renderer */ autofocus: function () { + this.renderer.autofocus(); }, /** * This method switches the form view in edit mode, with a new record. @@ -93,6 +91,14 @@ var FormController = BasicController.extend({ return dataPoint.data.display_name || _t('New'); }, /** + * Called each time the form view is attached into the DOM + * + * @todo convert to new style + */ + on_attach_callback: function () { + this.autofocus(); + }, + /** * Render buttons for the control panel. The form view can be rendered in * a dialog, and in that case, if we have buttons defined in the footer, we * have to use them instead of the standard buttons. @@ -374,10 +380,8 @@ var FormController = BasicController.extend({ }); } - if (event.data.show_wow) { - def.then(function () { - self.show_wow(); - }); + if (event.data.showWow) { + def.then(this.trigger_up.bind(this, 'show_wow')); } def.always(this._enableButtons.bind(this)); diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js index ddd77ee5dc6..08f28438368 100644 --- a/addons/web/static/src/js/views/form/form_renderer.js +++ b/addons/web/static/src/js/views/form/form_renderer.js @@ -26,6 +26,29 @@ var FormRenderer = BasicRenderer.extend({ //-------------------------------------------------------------------------- /** + * Focuses the field having attribute 'default_focus' set, if any, or the + * first focusable field otherwise. + */ + autofocus: function () { + if (this.mode === 'readonly') { + return; + } + var focusWidget = this.defaultFocusField; + if (!focusWidget || !focusWidget.isFocusable()) { + var widgets = this.allFieldWidgets[this.state.id]; + for (var i = 0; i < (widgets ? widgets.length : 0); i++) { + var widget = widgets[i]; + if (widget.isFocusable()) { + focusWidget = widget; + break; + } + } + } + if (focusWidget) { + focusWidget.activate({noselect: true}); + } + }, + /** * Extend the method so that labels also receive the 'o_field_invalid' class * if necessary. * @@ -183,7 +206,7 @@ var FormRenderer = BasicRenderer.extend({ self.trigger_up('button_clicked', { attrs: node.attrs, record: self.state, - show_wow: self.$el.hasClass('o_wow'), // TODO: implement this (in view) + showWow: $el.hasClass('o_wow'), }); }); }, @@ -709,7 +732,10 @@ var FormRenderer = BasicRenderer.extend({ * @returns {jQueryElement} */ _renderTagSeparator: function (node) { - return $('<div/>').addClass('o_horizontal_separator').text(node.attrs.string); + var $separator = $('<div/>').addClass('o_horizontal_separator').text(node.attrs.string); + this._handleAttributes($separator, node); + this._registerModifiers(node, this.state, $separator); + return $separator; }, /** * @private @@ -769,20 +795,16 @@ var FormRenderer = BasicRenderer.extend({ core.bus.trigger('DOM_updated'); // Attach the tooltips on the fields' label - var focusWidget = this.defaultFocusField; _.each(this.allFieldWidgets[this.state.id], function (widget) { - if (!focusWidget) { - focusWidget = widget; - } if (core.debug || widget.attrs.help || widget.field.help) { var idForLabel = self.idsForLabels[widget.name]; var $label = idForLabel ? self.$('label[for=' + idForLabel + ']') : $(); self._addFieldTooltip(widget, $label); } }); - if (focusWidget) { - focusWidget.activate({noselect: true}); - } + + // Focus the default field (in edit mode) + self.autofocus(); }, /** * Sets id attribute of given widget to idForLabel diff --git a/addons/web/static/src/js/views/list/list_editable_renderer.js b/addons/web/static/src/js/views/list/list_editable_renderer.js index 9364d1ba9fe..08b9e7f1602 100644 --- a/addons/web/static/src/js/views/list/list_editable_renderer.js +++ b/addons/web/static/src/js/views/list/list_editable_renderer.js @@ -155,7 +155,7 @@ ListRenderer.include({ var self = this; var rowIndex = _.findIndex(this.state.data, {id: recordID}); if (rowIndex < 0) { - return; + return $.when(); } var editMode = (mode === 'edit'); var record = this.state.data[rowIndex]; diff --git a/addons/web/static/src/js/views/view_dialogs.js b/addons/web/static/src/js/views/view_dialogs.js index b84d60d5b7c..a19e440913e 100644 --- a/addons/web/static/src/js/views/view_dialogs.js +++ b/addons/web/static/src/js/views/view_dialogs.js @@ -4,6 +4,7 @@ odoo.define('web.view_dialogs', function (require) { var core = require('web.core'); var data = require('web.data'); var Dialog = require('web.Dialog'); +var dom = require('web.dom'); var ListController = require('web.ListController'); var ListView = require('web.ListView'); var pyeval = require('web.pyeval'); @@ -194,8 +195,10 @@ var FormViewDialog = ViewDialog.extend({ if ($buttons.children().length) { self.$footer.empty().append($buttons.contents()); } - _super().$el.append(fragment); - self.form_view.autofocus(); + dom.append(_super().$el, fragment, { + callbacks: [{widget: self.form_view}], + in_DOM: true, + }); }); }); @@ -281,6 +284,7 @@ var SelectCreateDialog = ViewDialog.extend({ if(this.options.initial_view !== "search") { return this.create_edit_record(); } + var self = this; var user_context = this.getSession().user_context; var _super = this._super.bind(this); @@ -298,7 +302,10 @@ var SelectCreateDialog = ViewDialog.extend({ this.loadViews(this.dataset.model, this.dataset.get_context(), [[false, 'list'], [false, 'search']], {}) .then(this.setup.bind(this, search_defaults)) .then(function (fragment) { - _super().$el.append(fragment); + dom.append(_super().$el, fragment, { + callbacks: [{widget: self.list_controller}], + in_DOM: true, + }); }); return this; }, |
