[FIX] web: SelectMenu: fix onInput props usage
This commit fixes an issue caused by the way we use onInput props in Knowledge to fetch articles depending the current search value. Since we start from an empty string in the input again, it make no sense to display the choices previously fetched with a search value no longer displayed in the UI. The only way to display the correct items is to update the input value, then put an empty search to fetch accordingly. This is clearly an issue, when the onInput props is used to fetch the content of the SelectMenu, depending of the search value. The UI obviously display an empty search, and filter accordingly, but without fetching the items corresponding to the empty search value. A test was added as well to assert SelectMenu can be used for this purpose without forgetting to call onInput again when clearing the search value in beforeOpen. closes odoo/odoo#153072 X-original-commit: ca417f171b1bd2dd567beed7bc0e1fcaba6c8a4c Signed-off-by: Bastien Fafchamps (bafa) <bafa@odoo.com> Signed-off-by: Luca Vitali (luvi) <luvi@odoo.com>
This commit is contained in:
@@ -138,17 +138,25 @@ export class SelectMenu extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
async onBeforeOpen() {
|
||||
if (this.state.searchValue.length) {
|
||||
this.state.searchValue = "";
|
||||
if (this.props.onInput) {
|
||||
// This props can be used by the parent to fetch items dynamically depending
|
||||
// the search value. It must be called with the empty search value.
|
||||
await this.executeOnInput("");
|
||||
}
|
||||
}
|
||||
this.filterOptions();
|
||||
}
|
||||
|
||||
onStateChanged({ open }) {
|
||||
this.isOpen = open;
|
||||
|
||||
if (!open) {
|
||||
this.state.searchValue = "";
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedElement = document.querySelector(".o_select_active");
|
||||
if (selectedElement) {
|
||||
scrollTo(selectedElement);
|
||||
if (open) {
|
||||
const selectedElement = document.querySelector(".o_select_active");
|
||||
if (selectedElement) {
|
||||
scrollTo(selectedElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
togglerClass="`o_select_menu_toggler btn w-100 bg-light ${props.togglerClass || ''} ${canDeselect ? 'o_can_deselect' : ''}`"
|
||||
menuClass="`o_select_menu_menu${props.searchable ? ' py-0' : ''}${props.multiSelect ? ' o_select_menu_multi_select' : ''} border`"
|
||||
position="'bottom-fit'"
|
||||
beforeOpen.bind="filterOptions"
|
||||
beforeOpen.bind="onBeforeOpen"
|
||||
onScroll.bind="onScroll"
|
||||
onStateChanged.bind="onStateChanged"
|
||||
>
|
||||
|
||||
@@ -1202,4 +1202,42 @@ QUnit.module("Web Components", (hooks) => {
|
||||
"options have been filtered since the choices changed"
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test("search value is cleared when reopening the menu", async (assert) => {
|
||||
class Parent extends Component {
|
||||
setup() {
|
||||
this.state = useState({
|
||||
choices: [
|
||||
{ label: "Option A", value: "optionA" },
|
||||
],
|
||||
value: "hello",
|
||||
});
|
||||
}
|
||||
|
||||
onInput(searchValue) {
|
||||
assert.step("search=" + searchValue);
|
||||
}
|
||||
}
|
||||
Parent.components = { SelectMenu };
|
||||
Parent.template = xml`
|
||||
<SelectMenu
|
||||
choices="state.choices"
|
||||
groups="state.groups"
|
||||
value="state.value"
|
||||
onInput.bind="onInput"
|
||||
/>
|
||||
`;
|
||||
|
||||
await mount(Parent, target, { env });
|
||||
await open();
|
||||
assert.verifySteps([], "onInput props has not been called initially");
|
||||
await editInput(target, "input.o_select_menu_sticky", "a");
|
||||
assert.verifySteps(["search=a"], "onInput props has been called with the right search string");
|
||||
|
||||
// opening the menu should clear the search string, trigger onInput and update the props
|
||||
await triggerEvent(target, ".o_select_menu_toggler", "keydown", { key: "Escape" });
|
||||
await open();
|
||||
assert.verifySteps(["search="], "onInput props has been called with the empty search string");
|
||||
assert.strictEqual(target.querySelector(".o_select_menu_sticky").value, "", "search input is empty");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user