[FIX] web: AutoComplete: don't show previous results

... when re-opening the dropdown.

Before this commit, in an autocomplete component with an async
source, when:
 - clicking on the input to open the dropdown,
 - then typing something to filter the results
 - then selecting one of them (which closes the dropdown)
 - and finally re-opening the dropdown:
the previously displayed (and filtered) results were briefly
displayed, while the source was being fetched again. It thus
produced a weird and annoying flickering.

This commit fixes the issue by reseting the source before fetching
it.

closes odoo/odoo#105539

X-original-commit: 83769b00837f4eea29586f53709d65d3078ddce3
Signed-off-by: Michaël Mattiello <mcm@odoo.com>
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Aaron Bohy
2022-11-10 13:15:56 +01:00
parent 355def0bbc
commit 98095e082f
2 changed files with 61 additions and 3 deletions
@@ -69,11 +69,11 @@ export class AutoComplete extends Component {
}
loadSources(useInput) {
const sources = [];
this.sources = [];
const proms = [];
for (const pSource of this.props.sources) {
const source = this.makeSource(pSource);
sources.push(source);
this.sources.push(source);
const options = this.loadOptions(
pSource.options,
@@ -93,7 +93,6 @@ export class AutoComplete extends Component {
}
Promise.all(proms).then(() => {
this.sources = sources;
this.navigate(0);
});
}
@@ -8,7 +8,9 @@ import { makeTestEnv } from "../helpers/mock_env";
import {
click,
getFixture,
makeDeferred,
mount,
nextTick,
patchWithCleanup,
triggerEvent,
triggerEvents,
@@ -201,4 +203,61 @@ QUnit.module("Components", (hooks) => {
await triggerEvent(target, ".o-autocomplete--input", "blur");
assert.containsNone(target, ".o-autocomplete--dropdown-menu");
});
QUnit.test("open twice should not display previous results", async (assert) => {
let def = makeDeferred();
class Parent extends Component {
get sources() {
return [
{
async options(search) {
await def;
if (search === "A") {
return [{ label: "AB" }, { label: "AC" }];
}
return [{ label: "AB" }, { label: "AC" }, { label: "BC" }];
},
},
];
}
}
Parent.components = { AutoComplete };
Parent.template = xml`
<AutoComplete value="''" sources="sources" onSelect="() => {}"/>
`;
await mount(Parent, target, { env });
assert.containsNone(target, ".o-autocomplete--dropdown-menu");
await triggerEvent(target, ".o-autocomplete--input", "click");
assert.containsOnce(target, ".o-autocomplete--dropdown-menu");
assert.containsOnce(target, ".o-autocomplete--dropdown-item");
assert.containsOnce(target, ".o-autocomplete--dropdown-item .fa-spin"); // loading
def.resolve();
await nextTick();
assert.containsN(target, ".o-autocomplete--dropdown-item", 3);
assert.containsNone(target, ".fa-spin");
def = makeDeferred();
target.querySelector(".o-autocomplete--input").value = "A";
await triggerEvent(target, ".o-autocomplete--input", "input");
assert.containsOnce(target, ".o-autocomplete--dropdown-item");
assert.containsOnce(target, ".o-autocomplete--dropdown-item .fa-spin"); // loading
def.resolve();
await nextTick();
assert.containsN(target, ".o-autocomplete--dropdown-item", 2);
assert.containsNone(target, ".fa-spin");
await click(target.querySelector(".o-autocomplete--dropdown-item"));
assert.containsNone(target, ".o-autocomplete--dropdown-menu");
// re-open the dropdown -> should not display the previous results
def = makeDeferred();
await triggerEvent(target, ".o-autocomplete--input", "click");
assert.containsOnce(target, ".o-autocomplete--dropdown-menu");
assert.containsOnce(target, ".o-autocomplete--dropdown-item");
assert.containsOnce(target, ".o-autocomplete--dropdown-item .fa-spin"); // loading
});
});