0xC0DED00D
0xC0DED00D

Reputation: 20368

Force TextField with type number to display dot as decimal separator

I am using material-ui to render a TextField component in my react app. It's somehow forcing all the <TextField type="number /> to have decimal separator as comma (,) instead of dot (.) which is confusing for the targeted users.

Is there any way to force it to always show dot as the decimal separator, regardless of locale?

I have created a small example here. just try to enter a number with decimals and click outside and it'll convert it into comma. This is probably because of my current device locale, but still I want to force a dot for everyone.

Upvotes: 9

Views: 25016

Answers (3)

Viljami
Viljami

Reputation: 791

I came out with solution that accepts both , and . separators using regex validator.

In addition of controlling input label, I control external numeric state <number | null>.

In my solution user can only input decimals separated . or , The input label and numeric state only changes if user input is convertable to float, In case of empty "" input, numeric state is set to null.

    const [inputValue, setInputValue] = useState<string>("")
    const [numericValue, setNumericValue] = useState<number | null>(null)

         return (<TextField
                    inputMode={"numeric"}
                    onChange={(e) => {
                        e.preventDefault();
                        // if new value is valid float
                        if (/^([\d]*[,.]?[\d]{0,2})$/.test(e.target.value)) {
                            setInputValue(e.target.value);
                            const parsed = parseFloat(
                                e.target.value.replaceAll(",", ".")
                            );
                            setNumericValue(isNaN(parsed) ? null : parsed)
                        }
                    }}
                    value={inputValue}
                />);

Upvotes: 0

goova
goova

Reputation: 39

For me, setting the language attribute to "en-US" in the inputProps worked:

<TextField
    type="number"
    inputProps={{step: "0.1", lang:"en-US"}}
 />

Upvotes: 3

minus.273
minus.273

Reputation: 777

As per my suggestion of using a third-party library to be integrated in the Textfield component; You could use the react-number-format library as an inputProp for the Textfield. It works because the number formatter offered by the aforementioned library has a decimalSeparator prop which defaults to the one character string "."

The custom number formatter would go like this:

import NumberFormat from 'react-number-format';

interface NumberFormatCustomProps {
  inputRef: (instance: NumberFormat | null) => void;
  onChange: (event: { target: { value: string } }) => void;
}

function NumberFormatCustom(props: NumberFormatCustomProps) {
  const { inputRef, onChange, ...other } = props;

  return (
    <NumberFormat
      {...other}
      getInputRef={inputRef}
      onValueChange={values => {
        onChange({
          target: {
            value: values.value
          }
        });
      }}
      isNumericString
    />
  );
}

And it could be used in a number Textfield like this:

<TextField
      label="react-number-format"
      value={values.numberformat}
      onChange={handleChange("numberformat")}
      id="formatted-numberformat-input"
      InputProps={{
        inputComponent: NumberFormatCustom as any
      }}
      type="number"
/>

For a fully functioning example, check out this sandbox.

Upvotes: 0

Related Questions