diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ad902615..9ff5226c 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -365,10 +365,8 @@ function parseDOMNode(node: Element, ctx: ParsingContext): AST | null { const typeAttr = node.getAttribute("type"); const isInput = tagName === "input"; const isSelect = tagName === "select"; - const isTextarea = tagName === "textarea"; const isCheckboxInput = isInput && typeAttr === "checkbox"; const isRadioInput = isInput && typeAttr === "radio"; - const isOtherInput = isInput && !isCheckboxInput && !isRadioInput; const hasLazyMod = attr.includes(".lazy"); const hasNumberMod = attr.includes(".number"); const hasTrimMod = attr.includes(".trim"); @@ -381,8 +379,8 @@ function parseDOMNode(node: Element, ctx: ParsingContext): AST | null { specialInitTargetAttr: isRadioInput ? "checked" : null, eventType, hasDynamicChildren: false, - shouldTrim: hasTrimMod && (isOtherInput || isTextarea), - shouldNumberize: hasNumberMod && (isOtherInput || isTextarea), + shouldTrim: hasTrimMod, + shouldNumberize: hasNumberMod, }; if (isSelect) { // don't pollute the original ctx diff --git a/tests/compiler/parser.test.ts b/tests/compiler/parser.test.ts index d261f020..1e2740d6 100644 --- a/tests/compiler/parser.test.ts +++ b/tests/compiler/parser.test.ts @@ -1991,8 +1991,8 @@ describe("qweb parser", () => { baseExpr: "state", expr: "'stuff'", eventType: "click", - shouldNumberize: false, - shouldTrim: false, + shouldNumberize: true, + shouldTrim: true, targetAttr: "value", hasDynamicChildren: false, specialInitTargetAttr: "checked", diff --git a/tests/components/__snapshots__/t_model.test.ts.snap b/tests/components/__snapshots__/t_model.test.ts.snap index 861a016f..7b30a6cb 100644 --- a/tests/components/__snapshots__/t_model.test.ts.snap +++ b/tests/components/__snapshots__/t_model.test.ts.snap @@ -468,6 +468,36 @@ exports[`t-model directive t-model on select with static options 1`] = ` }" `; +exports[`t-model directive t-model with dynamic number values on select options in foreach 1`] = ` +"function anonymous(app, bdom, helpers +) { + let { text, createBlock, list, multi, html, toggler, comment } = bdom; + let { toNumber, prepareList, withKey } = helpers; + + let block1 = createBlock(\`\`); + let block3 = createBlock(\`\`); + + return function template(ctx, node, key = \\"\\") { + const bExpr1 = ctx['state']; + const expr1 = 'value'; + const bValue1 = bExpr1[expr1]; + let hdlr1 = [(ev) => { bExpr1[expr1] = toNumber(ev.target.value); }]; + ctx = Object.create(ctx); + const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['state'].options);; + for (let i1 = 0; i1 < l_block2; i1++) { + ctx[\`o\`] = v_block2[i1]; + const key1 = ctx['o'].value; + let attr1 = ctx['o'].value; + let attr2 = bValue1 === ctx['o'].value; + let txt1 = ctx['o'].value; + c_block2[i1] = withKey(block3([attr1, attr2, txt1]), key1); + } + const b2 = list(c_block2); + return block1([hdlr1], [b2]); + } +}" +`; + exports[`t-model directive t-model with dynamic values on select options -- 2 1`] = ` "function anonymous(app, bdom, helpers ) { diff --git a/tests/components/t_model.test.ts b/tests/components/t_model.test.ts index e1a978e3..2d6fd0bc 100644 --- a/tests/components/t_model.test.ts +++ b/tests/components/t_model.test.ts @@ -626,6 +626,39 @@ describe("t-model directive", () => { expect(fixture.querySelector("select")!.value).toEqual("b"); }); + test("t-model with dynamic number values on select options in foreach", async () => { + class Test extends Component { + static template = xml` + + `; + state: any; + setup() { + this.state = useState({ + value: 2, + options: [{ value: 1 }, { value: 2 }, { value: 3 }], + }); + } + } + + const comp = await mount(Test, fixture); + // check that we have a value of 2 selected + expect(fixture.querySelector("select")!.value).toEqual("2"); + expect(comp.state.value).toBe(2); + + // emulate a click on the option=3 element + fixture.querySelectorAll("option")[2].selected = true; + fixture.querySelector("select")!.dispatchEvent(new Event("change")); + + await nextTick(); + // check that we have now selected the number 3 (and not the string) + expect(fixture.querySelector("select")!.value).toEqual("3"); + expect(comp.state.value).toBe(3); + }); + test("t-model is applied before t-on-input", async () => { expect.assertions(3); class SomeComponent extends Component {