From 67747e6fa5f4c1b27eed5dfd7231001e98fb34c1 Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Fri, 2 Jun 2017 15:35:29 +0200 Subject: [FIX] web: FieldOne2Many: re-activate 'Add an item' The 'Add an item' button of one2many editable lists is deactivated once clicked (since rev. f9a1241) to prevent concurrent record creation. It is re-activated when the record has been created. Unfortunately, it might happen that the record is actually not created, so in this case the button is never re-activated. This happens for example on the customer invoice form view, if the user tries to add a line before selecting a partner. --- addons/web/static/src/js/fields/abstract_field.js | 11 ++++++++--- addons/web/static/src/js/fields/relational_fields.js | 5 +++-- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'addons/web/static/src/js/fields') diff --git a/addons/web/static/src/js/fields/abstract_field.js b/addons/web/static/src/js/fields/abstract_field.js index 5908f7f5a8b..137d2954993 100644 --- a/addons/web/static/src/js/fields/abstract_field.js +++ b/addons/web/static/src/js/fields/abstract_field.js @@ -351,12 +351,13 @@ var AbstractField = Widget.extend({ * @param {Object} [options] * @param {boolean} [options.forceChange=false] if true, the change event will be * triggered even if the new value is the same as the old one + * @returns {Deferred} */ _setValue: function (value, options) { // we try to avoid doing useless work, if the value given has not // changed. Note that we compare the unparsed values. if (this.lastSetValue === value || (this.value === false && value === '')) { - return; + return $.when(); } this.lastSetValue = value; try { @@ -364,18 +365,22 @@ var AbstractField = Widget.extend({ this._isValid = true; } catch (e) { this._isValid = false; - return; + return $.Deferred().reject(); } if (!(options && options.forceChange) && this._isSameValue(value)) { - return; + return $.when(); } + var def = $.Deferred(); var changes = {}; changes[this.name] = value; this.trigger_up('field_changed', { dataPointID: this.dataPointID, changes: changes, viewType: this.viewType, + onSuccess: def.resolve.bind(def), + onFailure: def.reject.bind(def), }); + return def; }, //-------------------------------------------------------------------------- diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index e13c3d29004..e9af73c1343 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -964,7 +964,6 @@ var FieldOne2Many = FieldX2Many.extend({ var index = self.editable === 'top' ? 0 : self.value.data.length - 1; var newID = self.value.data[index].id; self.renderer.editRecord(newID); - self.creatingRecord = false; } } }); @@ -1014,6 +1013,7 @@ var FieldOne2Many = FieldX2Many.extend({ * in the kanban view */ _onAddRecord: function (ev) { + var self = this; // we don't want interference with the components upstream. ev.stopPropagation(); @@ -1023,10 +1023,11 @@ var FieldOne2Many = FieldX2Many.extend({ this._setValue({ operation: 'CREATE', position: this.editable, + }).always(function () { + self.creatingRecord = false; }); } } else { - var self = this; this._openFormDialog({ on_saved: function (record) { self._setValue({ operation: 'ADD', id: record.id }); -- cgit v1.2.3 From 25e701465081477a1bd31f448c1c4feb533f4a09 Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Tue, 6 Jun 2017 09:55:56 +0200 Subject: [FIX] web: Form: correctly autofocus fields The autofocus worked fine when switching from 'readonly' to 'edit', but not when clicking on 'Create' from the multi-record view. This was because in this case, we were trying to focus the field while the view wasn't in the DOM yet. This rev. ensures that we wait for the view to be appended to the DOM before trying to set the focus on the default field. Also ensures that the first visible field is correctly focused. Before this rev., if the first field was invisible (or simply not focusable), no field was focused. Credit goes to @msh-odoo for the preliminary work. --- addons/web/static/src/js/fields/abstract_field.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'addons/web/static/src/js/fields') diff --git a/addons/web/static/src/js/fields/abstract_field.js b/addons/web/static/src/js/fields/abstract_field.js index 137d2954993..492d9f26552 100644 --- a/addons/web/static/src/js/fields/abstract_field.js +++ b/addons/web/static/src/js/fields/abstract_field.js @@ -176,8 +176,8 @@ var AbstractField = Widget.extend({ * focusable element was not found or invisible */ activate: function (options) { - var $focusable = this.getFocusableElement(); - if ($focusable.length && $focusable.is(':visible')) { + if (this.isFocusable()) { + var $focusable = this.getFocusableElement(); $focusable.focus(); if ($focusable.is('input[type="text"], textarea')) { $focusable[0].selectionStart = $focusable[0].selectionEnd = $focusable[0].value.length; @@ -211,6 +211,15 @@ var AbstractField = Widget.extend({ getFocusableElement: function () { return $(); }, + /** + * Returns true iff the widget has a visible element that can take the focus + * + * @returns {boolean} + */ + isFocusable: function () { + var $focusable = this.getFocusableElement(); + return $focusable.length && $focusable.is(':visible'); + }, /** * this method is used to determine if the field value is set to a meaningful * value. This is useful to determine if a field should be displayed as empty -- cgit v1.2.3 From 922a04dbd2acbd547c0279b046099647c5f9eb3f Mon Sep 17 00:00:00 2001 From: Harshad Modi Date: Wed, 7 Jun 2017 13:45:04 +0530 Subject: [FIX] project: fix traceback while setting cover image from project task kanban view (PR #17165) --- addons/web/static/src/js/fields/basic_fields.js | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'addons/web/static/src/js/fields') diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index a5ceba50d3f..d4013a8bcdb 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -1281,8 +1281,26 @@ var PriorityWidget = AbstractField.extend({ }, }); -var AttachmentImage = AbstractField.extend({ - template: 'AttachmentImage', +var AttachmentImage = AbstractField.extend({ + className: 'o_attachment_image', + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * Reset cover image when widget value change + * + * @private + */ + _render: function () { + if (this.value) { + this.$el.empty().append($('/', { + src: "/web/image/" + this.value.data.id + "?unique=1", + title: this.value.data.display_name + })); + } + } }); var StateSelectionWidget = AbstractField.extend({ -- cgit v1.2.3 From 99ae418bf24171fbc6bb27584059c27efb857e77 Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Wed, 7 Jun 2017 12:56:21 +0200 Subject: [FIX] web: Many2one: wait for name_create before saving The problem occurred in form views with a many2one field, when the user reproduced the following steps: - type some text in the many2one - click on 'Create ...' in the many2one dropdown to quick create (name_create RPC) the record - before the name_create returns, click on 'Save'. When this happened, the record was saved before the many2one was updated with its new value. So the record was incorrectly saved, and the view was again dirty as soon as the name_create returned, even if it was in 'readonly'. So after saving, a 'Changes will be discarded' dialog opened when the user tried to leave the form. We fix this issue by making the controller wait for the name_create to return, and for the many2one to update its value, before saving. This issue could also occur in list views. --- .../web/static/src/js/fields/relational_fields.js | 25 ++++++++++++---------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'addons/web/static/src/js/fields') diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index e9af73c1343..ae3b06d3a02 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -213,17 +213,20 @@ var FieldMany2One = AbstractField.extend({ var self = this; var slowCreate = this._searchCreatePopup.bind(this, "form", false, this._createContext(name)); if (this.nodeOptions.quick_create) { - return this._rpc({ - model: this.field.relation, - method: 'name_create', - args: [name], - context: this.record.getContext(this.recordParams), - }) - .then(function (result) { - if (self.mode === "edit") { - self.reinitialize({id: result[0], display_name: result[1]}); - } - }, slowCreate); + this.trigger_up('mutexify', { + action: function () { + return self._rpc({ + model: self.field.relation, + method: 'name_create', + args: [name], + context: self.record.getContext(self.recordParams), + }).then(function (result) { + if (self.mode === "edit") { + self.reinitialize({id: result[0], display_name: result[1]}); + } + }, slowCreate); + }, + }); } else { slowCreate(); } -- cgit v1.2.3