diff --git a/addons/web/static/src/core/record_selectors/multi_record_selector.js b/addons/web/static/src/core/record_selectors/multi_record_selector.js index 5fc318bfd0a..4dd28ac0121 100644 --- a/addons/web/static/src/core/record_selectors/multi_record_selector.js +++ b/addons/web/static/src/core/record_selectors/multi_record_selector.js @@ -5,6 +5,7 @@ import { TagsList } from "@web/core/tags_list/tags_list"; import { useService } from "@web/core/utils/hooks"; import { RecordAutocomplete } from "./record_autocomplete"; import { _t } from "@web/core/l10n/translation"; +import { useTagNavigation } from "./tag_navigation_hook"; export class MultiRecordSelector extends Component { static props = { @@ -21,6 +22,7 @@ export class MultiRecordSelector extends Component { setup() { this.nameService = useService("name"); + this.onTagKeydown = useTagNavigation("multiRecordSelector", this.deleteTag.bind(this)); onWillStart(() => this.computeDerivedParams()); onWillUpdateProps((nextProps) => this.computeDerivedParams(nextProps)); } @@ -57,15 +59,20 @@ export class MultiRecordSelector extends Component { return { text, onDelete: () => { - this.props.update([ - ...this.props.resIds.slice(0, index), - ...this.props.resIds.slice(index + 1), - ]); + this.deleteTag(index); }, + onKeydown: this.onTagKeydown, }; }); } + deleteTag(index) { + this.props.update([ + ...this.props.resIds.slice(0, index), + ...this.props.resIds.slice(index + 1), + ]); + } + update(resIds) { this.props.update([...this.props.resIds, ...resIds]); } diff --git a/addons/web/static/src/core/record_selectors/multi_record_selector.xml b/addons/web/static/src/core/record_selectors/multi_record_selector.xml index 17bd4170773..dbc355b1ee2 100644 --- a/addons/web/static/src/core/record_selectors/multi_record_selector.xml +++ b/addons/web/static/src/core/record_selectors/multi_record_selector.xml @@ -2,7 +2,7 @@ -
+
{ const input = target.querySelector(".o_multi_record_selector input"); assert.strictEqual(input.placeholder, ""); }); + + QUnit.test("Can delete a tag with Backspace", async (assert) => { + await makeMultiRecordSelector({ + resModel: "partner", + resIds: [1, 2], + }); + await triggerEvent(target, ".o-autocomplete input", "keydown", { key: "Backspace" }); + assert.strictEqual(target.querySelectorAll(".o_tag").length, 1); + assert.strictEqual(target.querySelector(".o_tag").textContent, "Alice"); + }); + + QUnit.test("Can focus tags with arrow right and left", async (assert) => { + await makeMultiRecordSelector({ + resModel: "partner", + resIds: [1, 2], + }); + target.querySelector(".o-autocomplete input").focus(); + await triggerEvent(document.activeElement, "", "keydown", { key: "arrowleft" }); + assert.strictEqual(document.activeElement.textContent, "Bob"); + await triggerEvent(document.activeElement, "", "keydown", { key: "arrowleft" }); + assert.strictEqual(document.activeElement.textContent, "Alice"); + await triggerEvent(document.activeElement, "", "keydown", { key: "arrowleft" }); + assert.hasClass(document.activeElement, "o-autocomplete--input"); + await triggerEvent(document.activeElement, "", "keydown", { key: "arrowright" }); + assert.strictEqual(document.activeElement.textContent, "Alice"); + await triggerEvent(document.activeElement, "", "keydown", { key: "arrowright" }); + assert.strictEqual(document.activeElement.textContent, "Bob"); + await triggerEvent(document.activeElement, "", "keydown", { key: "arrowright" }); + assert.hasClass(document.activeElement, "o-autocomplete--input"); + }); + + QUnit.test("Delete the focused element", async (assert) => { + await makeMultiRecordSelector({ + resModel: "partner", + resIds: [1, 2], + }); + target.querySelector(".o-autocomplete input").focus(); + await triggerEvent(document.activeElement, "", "keydown", { key: "arrowright" }); + assert.strictEqual(document.activeElement.textContent, "Alice"); + await triggerEvent(document.activeElement, "", "keydown", { key: "Backspace" }); + assert.strictEqual(target.querySelectorAll(".o_tag").length, 1); + assert.strictEqual(target.querySelector(".o_tag").textContent, "Bob"); + }); + + QUnit.test("Backspace do nothing when the input is currently edited", async (assert) => { + await makeMultiRecordSelector({ + resModel: "partner", + resIds: [1, 2], + }); + target.querySelector(".o-autocomplete input").focus(); + await editInput(target, ".o-autocomplete input", "a"); + assert.strictEqual(document.activeElement.value, "a"); + await triggerEvent(document.activeElement, "", "keydown", { key: "Backspace" }); + assert.strictEqual(target.querySelectorAll(".o_tag").length, 2); + }); });