[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.
This commit is contained in:
Aaron Bohy
2017-06-07 08:08:49 +02:00
parent e9de309511
commit 67747e6fa5
4 changed files with 68 additions and 6 deletions
@@ -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;
},
//--------------------------------------------------------------------------
@@ -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 });
@@ -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
@@ -3907,6 +3907,60 @@ QUnit.module('relational_fields', {
form.destroy();
});
QUnit.test('editable list: onchange that returns a warning', function (assert) {
assert.expect(5);
this.data.turtle.onchanges = {
display_name: function () {},
};
var form = createView({
View: FormView,
model: 'partner',
data: this.data,
arch: '<form string="Partners">' +
'<field name="turtles">' +
'<tree editable="bottom">' +
'<field name="display_name"/>' +
'</tree>' +
'</field>' +
'</form>',
res_id: 1,
mockRPC: function (route, args) {
if (args.method === 'onchange') {
assert.step(args.method);
return $.when({
value: {},
warning: {
title: "Warning",
message: "You must first select a partner"
},
});
}
return this._super.apply(this, arguments);
},
viewOptions: {
mode: 'edit',
},
intercepts: {
warning: function () {
assert.step('warning');
},
},
});
// add a line (this should trigger an onchange and a warning)
form.$('.o_field_x2many_list_row_add a').click();
// check if 'Add an item' still works (this should trigger an onchange
// and a warning again)
form.$('.o_field_x2many_list_row_add a').click();
assert.verifySteps(['onchange', 'warning', 'onchange', 'warning']);
form.destroy();
});
QUnit.module('FieldMany2Many');
QUnit.test('many2many kanban: edition', function (assert) {