[FIX] conflicts between save-on-blur and action buttons in o2m

bzr revid: xmo@openerp.com-20120710073928-riswpz7f9mddqjgf
This commit is contained in:
Xavier Morel 2012-07-10 09:39:28 +02:00
parent 46e511d1f2
commit 9568c463b3
3 changed files with 70 additions and 55 deletions

View File

@ -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);
}
});

View File

@ -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;
});

View File

@ -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);
});
},
/**