[IMP] web: multi record selector: add keyboard navigation
This commit adds keyboard navigation to the multi record selector. Part of task-id 3433922 Part-of: odoo/odoo#138464
This commit is contained in:
@@ -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]);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="web.MultiRecordSelector" >
|
||||
<div class="o_input d-flex flex-wrap gap-1 o_multi_record_selector">
|
||||
<div class="o_input d-flex flex-wrap gap-1 o_multi_record_selector" t-ref="multiRecordSelector">
|
||||
<TagsList tags="tags"/>
|
||||
<RecordAutocomplete
|
||||
resModel="props.resModel"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { MultiRecordSelector } from "@web/core/record_selectors/multi_record_selector";
|
||||
import { makeTestEnv } from "../../helpers/mock_env";
|
||||
import { getFixture, mount, click } from "../../helpers/utils";
|
||||
import { getFixture, mount, click, triggerEvent, editInput } from "../../helpers/utils";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { hotkeyService } from "@web/core/hotkeys/hotkey_service";
|
||||
|
||||
@@ -187,4 +187,59 @@ QUnit.module("Web Components", (hooks) => {
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user