formio / formio.js

JavaScript powered Forms with JSON Form Builder
https://formio.github.io/formio.js
MIT License
1.89k stars 1.07k forks source link

i18n Number Formatting Inconsistency #5876

Open wescleveland56 opened 3 weeks ago

wescleveland56 commented 3 weeks ago

Describe the bug When a language is specified in the Options JSON, that language's locale seems to be used to format numbers in the number input control or in the currency input control but the utils.formatAsCurrency function doesn't follow the same behavior. Perhaps utils.formatAsCurrency is using the browser's locale? My testing was from the US.

For the currency input control the input number seems to be formatted based on the language locale even though I specify currency is USD.

Version/Branch 5.0.0-rc.91

To Reproduce Steps to reproduce the behavior:

  1. Open up the Formio.js sandbox at https://formio.github.io/formio.js/app/sandbox.html
  2. Insert the following Options JSON:
    {
    "language": "es",
    "i18n": {
    "es": {
      "Number": "Numero",
      "Currency": "Currencio",
      "Formatted Number": "Numero formatico",
      "Formatted Currency": "Currencio formatico"
    }
    }
    }
  3. Insert the following Form JSON:
    {
    "display": "form",
    "settings": {},
    "components": [
    {
      "label": "Number",
      "applyMaskOn": "change",
      "mask": false,
      "tableView": false,
      "delimiter": true,
      "requireDecimal": false,
      "inputFormat": "plain",
      "truncateMultipleSpaces": false,
      "clearOnHide": false,
      "validateWhenHidden": false,
      "key": "number",
      "type": "number",
      "input": true
    },
    {
      "label": "Formatted Number",
      "tag": "div",
      "attrs": [
        {
          "attr": "",
          "value": ""
        }
      ],
      "content": "<label>{{t('Formatted Number')}}</label><p>{{utils.formatAsCurrency(data.number)}}</p>",
      "refreshOnChange": true,
      "key": "formattedNumber",
      "type": "htmlelement",
      "input": false,
      "tableView": false
    },
    {
      "label": "Currency",
      "prefix": "$",
      "suffix": "%",
      "applyMaskOn": "change",
      "mask": false,
      "tableView": false,
      "currency": "USD",
      "inputFormat": "plain",
      "truncateMultipleSpaces": false,
      "validateWhenHidden": false,
      "key": "currency",
      "type": "currency",
      "input": true,
      "delimiter": true
    },
    {
      "label": "Formatted Number",
      "tag": "div",
      "attrs": [
        {
          "attr": "",
          "value": ""
        }
      ],
      "content": "<label>{{t('Formatted Currency')}}</label><p>{{utils.formatAsCurrency(data.currency)}}</p>",
      "refreshOnChange": true,
      "key": "formattedNumber1",
      "type": "htmlelement",
      "input": false,
      "tableView": false
    },
    {
      "type": "button",
      "label": "Submit",
      "key": "submit",
      "disableOnInvalid": true,
      "input": true,
      "tableView": false
    }
    ]
    }
  4. Enter "12345,67" into the Numero field.
  5. You should see that the Numero field contains "12.345,67" and the Numero formatico field contains "12,345.67"
  6. Enter "12345,67" into the Currencio field.
  7. You should see that the Currencio field contains "12.345,67 US$" and the Currencio formatico field contains "12,345.67"

Expected behavior The expectation is that the number input fields, currency input fields, and the utils.formatAsCurrency function would all format numbers the same. Maybe this isn't a reasonable expectation???

Ideally, there would be a way to specify number and currency formatting locale separate from the language used for text display. I'm sure my situation is not unique. All currency on my website will be in USD (and should be entered and formatted as such) but I want to be able to display text in the user's preferred language.

BTW, I think Formio.js is an AWESOME product and hands-down the best Open Source form builder/runner out there. Thanks for this great product.

travist commented 1 week ago

As of right now number formatting uses the browser locale to perform the number internationalization vs. the passed in configuration from the renderer for translations, so this currently works as designed. I understand that your case requires them to be linked, but that is just not how it currently works. If there is a way to "force" the browser internationalization then I would just do that before the form is rendered and it should then show the numbers correctly.

wescleveland56 commented 4 days ago

Thanks for the reply Travis.

Please note that in the example, utils.formatAsCurrency is formatting based on the browser locale while number input is formatting based on the language code passed in the options, NOT the browser locale. This is the inconsistency I am trying to raise.

Regardless of my use case, IMO, number formatting should be consistent - ALWAYS use browser's locale if that is the design approach, but NEVER use a mix of browser locale and options language code. That is, number input should use the same number format as number formatting (utils.formatAsCurrency in this case).

Also, I do have a workaround but it is just that - a workaround - and doesn't solve the root problem.

Thanks. :)

Sidiro23 commented 12 hours ago

For Internal Reference: FIO-9353