diff --git a/addons/web/static/src/views/fields/numpad_decimal_hook.js b/addons/web/static/src/views/fields/numpad_decimal_hook.js index 721c164c61d..6177db16efc 100644 --- a/addons/web/static/src/views/fields/numpad_decimal_hook.js +++ b/addons/web/static/src/views/fields/numpad_decimal_hook.js @@ -4,6 +4,23 @@ import { localization } from "@web/core/l10n/localization"; import { useRef, useEffect } from "@odoo/owl"; +function onKeydown(ev) { + const decimalPoint = localization.decimalPoint; + if ( + !([".", ","].includes(ev.key) && ev.code === "NumpadDecimal") || + ev.key === decimalPoint || + ev.target.type === "number" + ) { + return; + } + ev.preventDefault(); + ev.target.setRangeText(decimalPoint, ev.target.selectionStart, ev.target.selectionEnd, "end"); +} + +function onFocus(ev) { + ev.target.select(); +} + /** * This hook replaces the decimal separator of the numpad decimal key * by the decimal separator from the user's language setting when user @@ -16,33 +33,18 @@ import { useRef, useEffect } from "@odoo/owl"; * case, whatever the user types, we let the browser's default behavior. */ export function useNumpadDecimal() { - const decimalPoint = localization.decimalPoint; const ref = useRef("numpadDecimal"); - const handler = (ev) => { - if ( - !([".", ","].includes(ev.key) && ev.code === "NumpadDecimal") || - ev.key === decimalPoint || - ev.target.type === "number" - ) { - return; - } - ev.preventDefault(); - ev.target.setRangeText( - decimalPoint, - ev.target.selectionStart, - ev.target.selectionEnd, - "end" - ); - }; useEffect(() => { let inputs = []; const el = ref.el; if (el) { inputs = el.nodeName === "INPUT" ? [el] : el.querySelectorAll("input"); - inputs.forEach((input) => input.addEventListener("keydown", handler)); + inputs.forEach((input) => input.addEventListener("keydown", onKeydown)); + inputs.forEach((input) => input.addEventListener("focus", onFocus)); } return () => { - inputs.forEach((input) => input.removeEventListener("keydown", handler)); + inputs.forEach((input) => input.removeEventListener("keydown", onKeydown)); + inputs.forEach((input) => input.removeEventListener("focus", onFocus)); }; }); } diff --git a/addons/web/static/tests/views/fields/numeric_fields_tests.js b/addons/web/static/tests/views/fields/numeric_fields_tests.js index ac378acda37..7cc143a6ac0 100644 --- a/addons/web/static/tests/views/fields/numeric_fields_tests.js +++ b/addons/web/static/tests/views/fields/numeric_fields_tests.js @@ -2,7 +2,13 @@ import { makeFakeLocalizationService } from "@web/../tests/helpers/mock_services"; import { registry } from "@web/core/registry"; -import { click, getFixture, nextTick, patchWithCleanup } from "@web/../tests/helpers/utils"; +import { + click, + getFixture, + nextTick, + patchWithCleanup, + triggerEvent, +} from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; import { localization } from "@web/core/l10n/localization"; import { useNumpadDecimal } from "@web/views/fields/numpad_decimal_hook"; @@ -374,4 +380,18 @@ QUnit.module("Fields", (hooks) => { await testInputElements(target.querySelectorAll("main > input")); } ); + + QUnit.test("select all content on focus", async function (assert) { + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: `
`, + }); + + const input = target.querySelector(".o_field_widget[name='monetary'] input"); + await triggerEvent(input, null, "focus"); + assert.strictEqual(input.selectionStart, 0); + assert.strictEqual(input.selectionEnd, 4); + }); });