diff --git a/addons/web/static/src/core/select_menu/select_menu.js b/addons/web/static/src/core/select_menu/select_menu.js index 7312c264247..e549c8a4059 100644 --- a/addons/web/static/src/core/select_menu/select_menu.js +++ b/addons/web/static/src/core/select_menu/select_menu.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import { Component, useState, useRef, onWillUpdateProps } from "@odoo/owl"; +import { Component, useState, useRef, onWillUpdateProps, useEffect } from "@odoo/owl"; import { Dropdown } from "@web/core/dropdown/dropdown"; import { DropdownItem } from "@web/core/dropdown/dropdown_item"; import { _lt } from "@web/core/l10n/translation"; @@ -94,14 +94,14 @@ export class SelectMenu extends Component { if (this.props.value !== nextProps.value) { this.selectedChoice = this.getSelectedChoice(nextProps); } - if ( - this.props.choices.length !== nextProps.choices.length || - this.props.groups.length !== nextProps.groups.length - ) { - const groups = [{ choices: nextProps.choices }, ...nextProps.groups]; - this.filterOptions(this.state.searchValue, groups); - } }); + useEffect( + () => { + const groups = [{ choices: this.props.choices }, ...this.props.groups]; + this.filterOptions(this.state.searchValue, groups); + }, + () => [this.props.choices, this.props.groups] + ); } get displayValue() { diff --git a/addons/web/static/tests/core/select_menu_tests.js b/addons/web/static/tests/core/select_menu_tests.js index 275c5b61124..e1344e90682 100644 --- a/addons/web/static/tests/core/select_menu_tests.js +++ b/addons/web/static/tests/core/select_menu_tests.js @@ -912,6 +912,7 @@ QUnit.module("Web Components", (hooks) => { ); await editInput(target, "input.o_select_menu_sticky", "cou"); + await nextTick(); assert.strictEqual( target.querySelector(".o_select_menu_menu").textContent, "Coucou", @@ -929,4 +930,64 @@ QUnit.module("Web Components", (hooks) => { "SelectMenu has two choices available" ); }); + + QUnit.test("Choices are updated and filtered when props change", async (assert) => { + class Parent extends Component { + setup() { + this.state = useState({ + choices: [ + { label: "Hello", value: "hello" }, + { label: "Coucou", value: "hello2" }, + ], + value: "hello", + }); + } + + onInput() { + this.state.choices = [ + { label: "Coucou", value: "hello2" }, + { label: "Good afternoon", value: "hello3" }, + ]; + } + + onSelect(value) { + assert.step(value); + this.state.value = value; + } + } + Parent.components = { SelectMenu }; + Parent.template = xml` + + `; + + await mount(Parent, target, { env }); + assert.strictEqual(getValue(), "Hello"); + + await open(); + assert.strictEqual( + target.querySelector(".o_select_menu_menu").textContent, + "CoucouHello", + "SelectMenu has two choices available" + ); + + // edit the input, to trigger onInput and update the props + await editInput(target, "input.o_select_menu_sticky", "aft"); + await nextTick(); + + await click(target.querySelectorAll(".o_select_menu_item_label")[0]); + assert.verifySteps(["hello3"], "added item can be selected"); + assert.strictEqual(getValue(), "Good afternoon"); + + await open(); + assert.strictEqual( + target.querySelector(".o_select_menu_menu").textContent, + "CoucouGood afternoon", + "SelectMenu has two updated choices available" + ); + }); });