[FIX] web, partner_autocomplete: onChange interference with selection
This commit fixes an issue regarding unwanted interaction between the regular autocomplete option click selection and the onChange handler from the input field hook used in the PartnerAutoCompleteCharField component. This became an issue starting from https://github.com/odoo/odoo/pull/154203 because of the disappearance of the t-on-mousedown.prevent handler placed on the autocomplete options list which would prevent the onChange event from being triggered when clicking on an option. The issue would be that the onChange handler from the input field hook would take precedence over the option click handler of the autocomplete which would most of the time be ignored afterwards. The solution found for This problem is to prevent the immediate propagation of the change event in the autocomplete handler when an option has been clicked on so that it will never be propagated to the input field hook handler in this case. Steps to reproduce: - Go to contacts and open a company contact - Type in the name field a few characters (at least 3) - Click on any autocomplete option Most of the time, the option will not be applied and the name won't change closes odoo/odoo#160561 X-original-commit: aa1e5eabb67800fbf4155c9cae12b90d97bb75db Signed-off-by: Aaron Bohy (aab) <aab@odoo.com> Signed-off-by: Julien Carion (juca) <juca@odoo.com> Signed-off-by: Louis Baudoux (lba) <lba@odoo.com>
This commit is contained in:
@@ -163,9 +163,9 @@ QUnit.module('partner_autocomplete', {
|
||||
}
|
||||
else if (route === "/web/dataset/call_kw/res.partner/enrich_company") {
|
||||
return Promise.resolve({
|
||||
"partner_gid": 1,
|
||||
"website": "firstcompany.com",
|
||||
"name": "First company",
|
||||
"partner_gid": args.args[1],
|
||||
"website": args.args[0],
|
||||
"name": args.args[1] === 1 ? "First company" : "Second company",
|
||||
'logo': false,
|
||||
"ignored": false,
|
||||
"vat": "Some VAT number",
|
||||
@@ -400,4 +400,53 @@ QUnit.module('partner_autocomplete', {
|
||||
"Clearbit and Odoo autocomplete options should be shown"
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test("Partner autocomplete : onChange should not disturb option selection", async function (assert) {
|
||||
await makeView(makeViewParams);
|
||||
|
||||
// Set company type to Company
|
||||
await editSelect(target, "[name='company_type'] > select", '"company"');
|
||||
|
||||
const input = target.querySelector("[name='name'] .dropdown input");
|
||||
const autocompleteContainer = input.parentElement;
|
||||
|
||||
await click(input, null);
|
||||
await editInputNoChangeEvent(input, "company");
|
||||
assert.containsN(
|
||||
autocompleteContainer,
|
||||
".o-autocomplete--dropdown-item",
|
||||
6,
|
||||
"Clearbit and Odoo autocomplete options should be shown"
|
||||
);
|
||||
// Click on the second option (include realistic events) - "Second company"
|
||||
await triggerEvent(
|
||||
target.querySelectorAll(".o-autocomplete--dropdown-item")[1],
|
||||
"",
|
||||
"pointerdown"
|
||||
);
|
||||
await triggerEvent(
|
||||
target.querySelectorAll(".o-autocomplete--dropdown-item")[1],
|
||||
"",
|
||||
"mousedown"
|
||||
);
|
||||
await triggerEvent(input, "", "change");
|
||||
await triggerEvent(input, "", "blur");
|
||||
await click(target.querySelectorAll(".o-autocomplete--dropdown-item")[1], "");
|
||||
|
||||
// Check that the fields have been filled
|
||||
const expectedValues = {
|
||||
"website": "secondcompany.com",
|
||||
"name": "Second company",
|
||||
"vat": "Some VAT number",
|
||||
"street": "Some street",
|
||||
"city": "Some city",
|
||||
"zip": "1234",
|
||||
"phone": "+0123456789",
|
||||
"country_id": "United States",
|
||||
"state_id": "California (US)",
|
||||
};
|
||||
for (const [fieldName, expectedValue] of Object.entries(expectedValues)) {
|
||||
assert.strictEqual(target.querySelector(`[name=${fieldName}] input`).value, expectedValue, `${fieldName} should be filled`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -260,7 +260,10 @@ export class AutoComplete extends Component {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
onInputChange() {
|
||||
onInputChange(ev) {
|
||||
if (this.ignoreBlur) {
|
||||
ev.stopImmediatePropagation();
|
||||
}
|
||||
this.props.onChange({
|
||||
inputValue: this.inputRef.el.value,
|
||||
});
|
||||
|
||||
@@ -540,7 +540,11 @@ QUnit.module("Components", (hooks) => {
|
||||
assert.strictEqual(mousedownEvent.defaultPrevented, false);
|
||||
await triggerEvent(input, "", "change");
|
||||
await triggerEvent(input, "", "blur");
|
||||
await click(target.querySelectorAll(".o-autocomplete--dropdown-item")[1], "");
|
||||
await triggerEvent(
|
||||
target.querySelectorAll(".o-autocomplete--dropdown-item")[1],
|
||||
"",
|
||||
"click"
|
||||
);
|
||||
assert.verifySteps(["change", "select Hello"]);
|
||||
assert.strictEqual(input, document.activeElement);
|
||||
|
||||
@@ -550,8 +554,8 @@ QUnit.module("Components", (hooks) => {
|
||||
await triggerEvent(input, "", "input");
|
||||
await triggerEvent(target, "", "pointerdown");
|
||||
await triggerEvent(input, "", "change");
|
||||
input.blur();
|
||||
await click(target, "");
|
||||
await triggerEvent(input, "", "blur");
|
||||
await triggerEvent(target, "", "click");
|
||||
assert.verifySteps(["change", "blur"]);
|
||||
});
|
||||
|
||||
|
||||
@@ -445,7 +445,7 @@ QUnit.module("Fields", (hooks) => {
|
||||
);
|
||||
assert.strictEqual(
|
||||
o_kanban_record.querySelector("img.o_m2m_avatar").dataset.src,
|
||||
"/web/image/partner/4/avatar_128",
|
||||
"/web/image/partner/5/avatar_128",
|
||||
"should have correct avatar image"
|
||||
);
|
||||
await click(
|
||||
|
||||
@@ -3145,6 +3145,7 @@ QUnit.module("Fields", (hooks) => {
|
||||
// select a new value then cancel the creation of the new one --> restore the previous
|
||||
await click(target, ".o_field_widget[name=product_id] input");
|
||||
await click(target.querySelector(".ui-menu-item"));
|
||||
await triggerEvent(target, ".o_field_many2one input", "blur");
|
||||
assert.strictEqual(
|
||||
target.querySelector(".o_field_many2one input").value,
|
||||
"xphone",
|
||||
|
||||
Reference in New Issue
Block a user