From 3adfa84cd60e289407c956661591b0d172e8012b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Sat, 20 May 2017 22:15:48 +0200 Subject: [PATCH] [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. --- .../static/src/js/fields/relational_fields.js | 1 + .../tests/fields/relational_fields_tests.js | 54 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index e89fb563f21..fcc720b4ff7 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -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); }, /** diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index f1eb12d8516..fc558bd45a1 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -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: '', + 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');