[FIX] web: improve many2one edition with onchanges

When a many2one (in an editable list) with an onchange was edited, it
could happen that a modal window asking for confirmation of the creation
of a record was opened when it should not.  Here is what actually could
happen:

* user focus a many2one
* user type something
* user press ENTER (keydown + keyup)
* the onchange comes back
* user press ENTER again
* modal window is open

Because of the onchange, the _reset method was called after the
_onInputKeyup method.  So, the m2o_value was not equal to the $input.val() and
the 'floating' flag was set to true, which means that the _onInputFocusout
method (called indirectly by the listeditablerenderer when unselecting the row)
was forced to open a confirm dialog.

We simply fix the problem by setting the floating flag back to false in the
reset method.
This commit is contained in:
Géry Debongnie
2017-05-22 10:07:32 +02:00
parent 28eadb3d6e
commit 3adfa84cd6
2 changed files with 55 additions and 0 deletions
@@ -256,6 +256,7 @@ var FieldMany2One = AbstractField.extend({
*/
_reset: function () {
this._super.apply(this, arguments);
this.floating = false;
this.m2o_value = field_utils.format.many2one(this.value);
},
/**
@@ -706,6 +706,60 @@ QUnit.module('relational_fields', {
});
});
QUnit.test('many2one in editable list + onchange, with enter [REQUIRE FOCUS]', function (assert) {
assert.expect(6);
var done = assert.async();
var M2O_DELAY = relationalFields.FieldMany2One.prototype.AUTOCOMPLETE_DELAY;
relationalFields.FieldMany2One.prototype.AUTOCOMPLETE_DELAY = 0;
this.data.partner.onchanges.product_id = function (obj) {
obj.int_field = obj.product_id || 0;
};
var def = $.Deferred();
var list = createView({
View: ListView,
model: 'partner',
data: this.data,
arch: '<tree editable="bottom"><field name="product_id"/><field name="int_field"/></tree>',
mockRPC: function (route, args) {
if (args.method) {
assert.step(args.method);
}
var result = this._super.apply(this, arguments);
if (args.method === 'onchange') {
return def.then(_.constant(result));
}
return result;
},
});
list.$('td.o_data_cell:first').click();
list.$('td.o_data_cell input:first').val('a').trigger('input');
concurrency.delay(0).then(function () {
var $input = list.$('td.o_data_cell input:first');
$input.trigger($.Event('keydown', {
which: $.ui.keyCode.ENTER,
keyCode: $.ui.keyCode.ENTER,
}));
$input.trigger($.Event('keyup', {
which: $.ui.keyCode.ENTER,
keyCode: $.ui.keyCode.ENTER,
}));
def.resolve();
$input.trigger($.Event('keydown', {
which: $.ui.keyCode.ENTER,
keyCode: $.ui.keyCode.ENTER,
}));
assert.strictEqual($('div.modal').length, 0, "should not have any modal in DOM");
assert.verifySteps(['name_search', 'onchange', 'write', 'read']);
list.destroy();
relationalFields.FieldMany2One.prototype.AUTOCOMPLETE_DELAY = M2O_DELAY;
done();
});
});
QUnit.module('FieldOne2Many');