Skip to content

fix: read grouped numbers in PWA entry fields by account locale - #321

Open
Minhal128 wants to merge 1 commit into
nextcloud:mainfrom
Minhal128:fix/pwa-locale-number-grouping
Open

Minhal128 wants to merge 1 commit into
nextcloud:mainfrom
Minhal128:fix/pwa-locale-number-grouping

Conversation

@Minhal128

Copy link
Copy Markdown

Fixes #320

Problem

A grouped numeric entry in the PWA is stored 1000x too small in German locale, silently. Typing 12.000 steps stores 12; typing 1.234,5 stores 1.2345.

<input type="number"> sanitises its value before the app reads it, so the grouped text is already rewritten by the time parseLocaleNumber() runs -- the intended value cannot be recovered in JavaScript. parseLocaleNumber() also never stripped the group separator.

Change

  • numericInput() builds a text input with inputMode, so parseLocaleNumber() receives exactly what the user typed. The numeric keypad on touch devices is unchanged (inputMode already set it).
  • parseLocaleNumber() removes group separators before canonicalising the decimal separator, and samples formatToParts(11111.1) so a group part exists. Whitespace is dropped because several locales group with a no-break space a keyboard does not produce.
  • An entry carrying no digits returns NaN instead of 0, so it is rejected rather than stored as a zero measurement.

Why min/max were removed

min/max are inert on a text input, and isValidNumericValue() already enforces the same range on submit, plus Number.isInteger for counters. Keeping the attributes would have been dead code. No caller read valueAsNumber, stepUp, or stepDown.

Verification

End-to-end in real Chrome per locale, typing with keystrokes and passing input.value through the real parseLocaleNumber():

locale typed before after correct
de-DE 12.000 12 12000 12000
de-DE 1.234,5 1.2345 1234.5 1234.5
de-DE 2140,5 2140.5 2140.5 2140.5
en-US 12,000 12000 12000 12000
en-US 1,234.5 1234.5 1234.5 1234.5
en-US 2140.5 2140.5 2140.5 2140.5
  • TypeScript: PASS (npm run typecheck)
  • ESLint: PASS (npm run lint)
  • Frontend tests: PASS (30/30, was 28/28; 2 added)
  • Production build: PASS (npm run build)
  • git diff --check: PASS

Not run: PHP CS, Psalm, PHP unit tests, OpenAPI generation -- no PHP or API surface is touched by this change and I have no Nextcloud container here. Stylelint reports 13 pre-existing rule-empty-line-before errors in StatisticsChart.vue / StatisticsMeasurements.vue, untouched by this PR.

A number input sanitises its value before the app can read it, so a grouped
entry is rewritten and the intended value cannot be recovered in JavaScript.
In German Chrome, typing 12.000 steps stored 12 and typing 1.234,5 stored
1.2345 -- both silently off by a factor of 1000.

Use a text input with inputMode so parseLocaleNumber receives what the user
typed, and strip group separators there before canonicalising the decimal
separator. The numeric range was already enforced by isValidNumericValue on
submit, so the number input's min/max attributes were redundant.

An entry carrying no digits now returns NaN rather than 0, so it is rejected
instead of being stored as a zero measurement.

Signed-off-by: minhal128 <rizvi4600779@cloud.neduet.edu.pk>
Copilot AI balanced review requested due to automatic review settings October 8, 2026 09:44

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PWA stores a grouped number entry 1000x too small in German locale

2 participants