[FIX] web: improve navigation in field many2one

Before this commit, when the user write some text in a many2one, then
press ENTER, the key event will trigger a navigation move, which will
validate the field, and move the focus to the next line.  The same issue
happens when pressing TAB.

With this commit, we simply stop the propagation, and preventdefault the
event that cause the selection.
This commit is contained in:
Géry Debongnie
2017-05-22 10:07:31 +02:00
parent 5e913677a5
commit 28eadb3d6e
2 changed files with 85 additions and 1 deletions
@@ -88,6 +88,7 @@ var FieldMany2One = AbstractField.extend({
'click .o_external_button': '_onExternalButtonClick',
'click': '_onClick',
}),
AUTOCOMPLETE_DELAY: 200,
init: function () {
this._super.apply(this, arguments);
@@ -147,6 +148,11 @@ var FieldMany2One = AbstractField.extend({
});
},
select: function (event, ui) {
// we do not want the select event to trigger any additional
// effect, such as navigating to another field.
event.stopImmediatePropagation();
event.preventDefault();
var item = ui.item;
self.floating = false;
if (item.id) {
@@ -162,7 +168,7 @@ var FieldMany2One = AbstractField.extend({
autoFocus: true,
html: true,
minLength: 0,
delay: 200,
delay: this.AUTOCOMPLETE_DELAY,
});
this.$input.autocomplete("option", "position", { my : "left top", at: "left bottom" });
this.autocomplete_bound = true;
@@ -1,8 +1,10 @@
odoo.define('web.relational_fields_tests', function (require) {
"use strict";
var concurrency = require('web.concurrency');
var FormView = require('web.FormView');
var ListView = require('web.ListView');
var relationalFields = require('web.relational_fields');
var testUtils = require('web.test_utils');
var createView = testUtils.createView;
@@ -629,6 +631,82 @@ QUnit.module('relational_fields', {
form.destroy();
});
QUnit.test('pressing enter in a m2o in an editable list', function (assert) {
assert.expect(9);
var done = assert.async();
var M2O_DELAY = relationalFields.FieldMany2One.prototype.AUTOCOMPLETE_DELAY;
relationalFields.FieldMany2One.prototype.AUTOCOMPLETE_DELAY = 0;
var list = createView({
View: ListView,
model: 'partner',
data: this.data,
arch: '<tree editable="bottom"><field name="product_id"/></tree>',
});
list.$('td.o_data_cell:first').click();
assert.strictEqual(list.$('.o_selected_row').length, 1,
"should have a row in edit mode");
// we now write 'a' and press enter to check that the selection is
// working, and prevent the navigation
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');
var $dropdown = $input.autocomplete('widget');
assert.ok($dropdown.is(':visible'), "autocomplete dropdown should be visible");
// we now trigger ENTER to select first choice
$input.trigger($.Event('keydown', {
which: $.ui.keyCode.ENTER,
keyCode: $.ui.keyCode.ENTER,
}));
assert.strictEqual($input[0], document.activeElement,
"input should still be focused");
// we now trigger again ENTER to make sure we can move to next line
$input.trigger($.Event('keydown', {
which: $.ui.keyCode.ENTER,
keyCode: $.ui.keyCode.ENTER,
}));
assert.notOk(document.contains($input[0]),
"input should no longer be in dom");
assert.ok(list.$('tr.o_data_row:eq(1)').hasClass('o_selected_row'),
"second row should now be selected");
// we now write again 'a' in the cell to select xpad. We will now
// test with the tab key
list.$('td.o_data_cell input:first').val('a').trigger('input');
return concurrency.delay(0);
}).then(function () {
var $input = list.$('td.o_data_cell input:first');
var $dropdown = $input.autocomplete('widget');
assert.ok($dropdown.is(':visible'), "autocomplete dropdown should be visible");
$input.trigger($.Event('keydown', {
which: $.ui.keyCode.TAB,
keyCode: $.ui.keyCode.TAB,
}));
assert.strictEqual($input[0], document.activeElement,
"input should still be focused");
// we now trigger again ENTER to make sure we can move to next line
$input.trigger($.Event('keydown', {
which: $.ui.keyCode.TAB,
keyCode: $.ui.keyCode.TAB,
}));
assert.notOk(document.contains($input[0]),
"input should no longer be in dom");
assert.ok(list.$('tr.o_data_row:eq(2)').hasClass('o_selected_row'),
"third row should now be selected");
list.destroy();
relationalFields.FieldMany2One.prototype.AUTOCOMPLETE_DELAY = M2O_DELAY;
done();
});
});
QUnit.module('FieldOne2Many');
QUnit.test('one2many basic properties', function (assert) {