diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 93c6ea103cc..bb020f8db49 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -3105,6 +3105,7 @@ instance.web.form.One2ManyViewManager = instance.web.ViewManager.extend({ form: 'instance.web.form.One2ManyFormView', kanban: 'instance.web.form.One2ManyKanbanView', }); + this.__ignore_blur = false; }, switch_view: function(mode, unused) { if (mode !== 'form') { @@ -3154,6 +3155,15 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ this._super(parent, dataset, view_id, _.extend(options || {}, { ListType: instance.web.form.One2ManyList })); + this.on('edit:before', this, this.proxy('_beforeEdit')); + this.on('save:before cancel:before', this, this.proxy('_beforeUnEdit')); + }, + start: function () { + var ret = this._super(); + this.$element + .off('mousedown.handleButtons') + .on('mousedown.handleButtons', 'table button', this.proxy('_buttonDown')); + return ret; }, is_valid: function () { var form = this.editor.form; @@ -3227,62 +3237,46 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ readonly: self.o2m.get("effective_readonly") }); }, - /** - * Ensures the o2m is saved and committed to db before returning: executes - * the super-method (saves the current edition to the buffered dataset) - * then saves the parent form. - * - * @returns {jQuery.Deferred} - */ - ensureSaved: function () { + do_button_action: function () { var parent_form = this.o2m.view; - return this._super().pipe(function () { + var self = this, args = arguments; + return this.ensureSaved().pipe(function () { return parent_form.do_save(); - }); - } -}); -instance.web.form.One2ManyList = instance.web.ListView.List.extend({ - KEY_RETURN: 13, - // blurring caused by hitting the [Return] key, should skip the - // autosave-on-blur and let the handler for [Return] do its thing - __return_blur: false, - render_row_as_form: function () { - var self = this; - return this._super.apply(this, arguments).then(function () { - // Replace the "Save Row" button with "Cancel Edition" - self.edition_form.$element - .undelegate('button.oe-edit-row-save', 'click') - .delegate('button.oe-edit-row-save', 'click', function () { - self.cancel_pending_edition(); - }); - - // Overload execute_action on the edition form to perform a simple - // reload_record after the action is done, rather than fully - // reload the parent view (or something) - var _execute_action = self.edition_form.do_execute_action; - self.edition_form.do_execute_action = function (action, dataset, record_id, _callback) { - return _execute_action.call(this, action, dataset, record_id, function () { - self.view.reload_record( - self.view.records.get(record_id)); - }); - }; - - self.edition_form.on('blurred', null, function () { - if (self.__return_blur) { - delete self.__return_blur; - return; - } - if (!self.edition_form.widget_is_stopped) { - self.view.ensureSaved(); - } - }); + }).then(function () { + self.handleButton.apply(self, args); }); }, - on_row_keyup: function (e) { - if (e.which === this.KEY_RETURN) { - this.__return_blur = true; + + _beforeEdit: function () { + this.__ignore_blur = false; + this.editor.form.on('blurred', this, this._onFormBlur); + }, + _beforeUnEdit: function () { + this.editor.form.off('blurred', this, this._onFormBlur); + }, + _buttonDown: function () { + // If a button is clicked (usually some sort of action button), it's + // the button's responsibility to ensure the editable list is in the + // correct state -> ignore form blurring + this.__ignore_blur = true; + }, + /** + * Handles blurring of the nested form (saves the currently edited row), + * unless the flag to ignore the event is set to ``true`` + */ + _onFormBlur: function () { + if (this.__ignore_blur) { + this.__ignore_blur = false; + return; } - this._super(e); + this.saveEdition(); + }, + keyup_ENTER: function () { + // blurring caused by hitting the [Return] key, should skip the + // autosave-on-blur and let the handler for [Return] do its thing (save + // the current row *anyway*, then create a new one/edit the next one) + this.__ignore_blur = true; + this._super.apply(this, arguments); } }); diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index f25164d56e5..7c82d2b173f 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -661,6 +661,19 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi * @param {Function} callback should be called after the action is executed, if non-null */ do_button_action: function (name, id, callback) { + this.handleButton(name, id, callback); + }, + /** + * Base handling of buttons, can be called when overriding do_button_action + * in order to bypass parent overrides. + * + * This method should not be overridden. + * + * @param {String} name action name + * @param {Object} id id of the record the action should be called on + * @param {Function} callback should be called after the action is executed, if non-null + */ + handleButton: function (name, id, callback) { var action = _.detect(this.columns, function (field) { return field.name === name; }); diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js index e66fdc1c917..f759c274287 100644 --- a/addons/web/static/src/js/view_list_editable.js +++ b/addons/web/static/src/js/view_list_editable.js @@ -12,7 +12,7 @@ openerp.web.list_editable = function (instance) { var self = this; this._super.apply(this, arguments); - this.editor = new instance.web.list.Editor(this); + this.editor = this.makeEditor(); $(this.groups).bind({ 'edit': function (e, id, dataset) { @@ -87,7 +87,7 @@ openerp.web.list_editable = function (instance) { if (this.options.editable) { // Editor is not restartable due to formview not being // restartable - this.editor = new instance.web.list.Editor(this); + this.editor = this.makeEditor(); var editor_ready = this.editor.prependTo(this.$element) .then(this.proxy('setupEvents')); @@ -96,10 +96,18 @@ openerp.web.list_editable = function (instance) { return result; }, + /** + * Builds a new editor object + * + * @return {instance.web.list.Editor} + */ + makeEditor: function () { + return new instance.web.list.Editor(this); + }, do_button_action: function () { - var self = this, _super = this._super, args = arguments; + var self = this, args = arguments; this.ensureSaved().then(function () { - _super.apply(self, args); + self.handleButton.apply(self, args); }); }, /**