[FIX] web: autofocus conditional element
Before this commit, useAutofocus hook used the effect dependency to check if the target is in dom but this dependency is computed in onWillPatch and can be outdated when checking it in onPatched. Now, the target isn't a dependency anymore and is computed just before the check. Part-of: odoo/odoo#76472
This commit is contained in:
@@ -42,7 +42,8 @@ export function useAutofocus(params = {}) {
|
||||
const selector = params.selector || "[autofocus]";
|
||||
let forceFocusCount = 0;
|
||||
useEffect(
|
||||
function autofocus(target) {
|
||||
function autofocus() {
|
||||
const target = comp.el.querySelector(selector);
|
||||
if (target) {
|
||||
target.focus();
|
||||
if (["INPUT", "TEXTAREA"].includes(target.tagName)) {
|
||||
@@ -51,7 +52,7 @@ export function useAutofocus(params = {}) {
|
||||
}
|
||||
}
|
||||
},
|
||||
() => [comp.el.querySelector(selector), forceFocusCount]
|
||||
() => [forceFocusCount]
|
||||
);
|
||||
|
||||
return function focusOnUpdate() {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { useBus, useEffect, useListener, useService } from "@web/core/utils/hooks";
|
||||
import { uiService } from "@web/core/ui/ui_service";
|
||||
import { useAutofocus, useBus, useEffect, useListener, useService } from "@web/core/utils/hooks";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { makeTestEnv } from "../../helpers/mock_env";
|
||||
import { click, getFixture, nextTick } from "../../helpers/utils";
|
||||
@@ -11,6 +12,73 @@ const serviceRegistry = registry.category("services");
|
||||
|
||||
QUnit.module("utils", () => {
|
||||
QUnit.module("Hooks", () => {
|
||||
QUnit.module("useAutofocus");
|
||||
|
||||
QUnit.test("useAutofocus: simple usecase", async function (assert) {
|
||||
class MyComponent extends Component {
|
||||
setup() {
|
||||
useAutofocus();
|
||||
}
|
||||
}
|
||||
MyComponent.template = tags.xml`
|
||||
<span>
|
||||
<input type="text" autofocus="" />
|
||||
</span>
|
||||
`;
|
||||
|
||||
registry.category("services").add("ui", uiService);
|
||||
|
||||
const env = await makeTestEnv();
|
||||
const target = getFixture();
|
||||
const comp = await mount(MyComponent, { env, target });
|
||||
await nextTick();
|
||||
|
||||
assert.strictEqual(document.activeElement, comp.el.querySelector("input"));
|
||||
|
||||
comp.render();
|
||||
await nextTick();
|
||||
assert.strictEqual(document.activeElement, comp.el.querySelector("input"));
|
||||
|
||||
comp.destroy();
|
||||
});
|
||||
|
||||
QUnit.test("useAutofocus: conditional autofocus", async function (assert) {
|
||||
class MyComponent extends Component {
|
||||
setup() {
|
||||
this.forceFocus = useAutofocus();
|
||||
this.showInput = true;
|
||||
}
|
||||
}
|
||||
MyComponent.template = tags.xml`
|
||||
<span>
|
||||
<input t-if="showInput" type="text" autofocus="" />
|
||||
</span>
|
||||
`;
|
||||
|
||||
registry.category("services").add("ui", uiService);
|
||||
|
||||
const env = await makeTestEnv();
|
||||
const target = getFixture();
|
||||
const comp = await mount(MyComponent, { env, target });
|
||||
await nextTick();
|
||||
|
||||
assert.strictEqual(document.activeElement, comp.el.querySelector("input"));
|
||||
|
||||
comp.showInput = false;
|
||||
comp.forceFocus();
|
||||
comp.render();
|
||||
await nextTick();
|
||||
assert.notStrictEqual(document.activeElement, comp.el.querySelector("input"));
|
||||
|
||||
comp.showInput = true;
|
||||
comp.forceFocus();
|
||||
comp.render();
|
||||
await nextTick();
|
||||
assert.strictEqual(document.activeElement, comp.el.querySelector("input"));
|
||||
|
||||
comp.destroy();
|
||||
});
|
||||
|
||||
QUnit.module("useBus");
|
||||
|
||||
QUnit.test("useBus hook: simple usecase", async function (assert) {
|
||||
|
||||
Reference in New Issue
Block a user