【问题标题】:Force TextField with type number to display dot as decimal separator强制具有类型编号的 TextField 将点显示为小数分隔符
【发布时间】:2020-03-01 21:31:00
【问题描述】:

我正在使用material-ui 在我的react 应用程序中呈现TextField 组件。它以某种方式强制所有 <TextField type="number /> 将小数分隔符作为逗号 (,) 而不是点 (.),这让目标用户感到困惑。

有什么方法可以强制它始终将点显示为小数点分隔符,而不管语言环境如何?

我创建了一个small example here。只需尝试输入一个带小数的数字,然后单击外部,它就会将其转换为逗号。这可能是因为我当前的设备语言环境,但我仍然想为每个人强制一个点。

【问题讨论】:

  • 你见过this吗?也许会对您有所帮助
  • @RicardoGonzalez 我看到了,但他们使用 type="text" 我也使用没有这些插件。我需要数字类型,以便用户只能输入数字,他们也可以使用递增-递减按钮。
  • @noob 一个解决方案是使用第三方库,你对这个决定持何立场?
  • @minus.273 如果可能,我会尽量避免它,但是,如果这是唯一的解决方案,我可以这样做。唯一的事情是我想将类型保持为数字,否则,即使没有任何库,我也会得到带有文本类型的点。

标签: javascript reactjs typescript material-ui html-input


【解决方案1】:

根据我的建议,使用第三方库集成到 Textfield 组件中;您可以使用 react-number-format 库作为 Textfield 的 inputProp。它之所以有效,是因为上述库提供的数字格式化程序有一个 decimalSeparator 属性,默认为一个字符串 "."

自定义数字格式化程序如下所示:

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
    />
  );
}

它可以用在这样的数字文本字段中:

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

如需完整功能示例,请查看此sandbox

【讨论】:

  • 我仍然可以在沙箱中看到逗号作为小数分隔符。此外,我无法在 TextField 中输入十进制值,当我按下点键时它会被重置。我不得不粘贴一个十进制值来检查哪个也不起作用。
  • @noob 你的意思是如果你输入一个逗号,Textfield 会让你输入那个?
  • 不,我正在尝试输入一个浮点值,例如 23.20,但是一旦我在 23 之后输入点,它就会清除。我粘贴了相同的值,但是当我失去对 TextField 的关注时,它显示为 23,20。
  • 这是图书馆的一个有趣反应......这意味着它不会发生在我的语言环境中?稍后将对其进行更多研究:)
  • 我可以确认...我的语言环境是法语(fr-fr 或其他),并且演示的行为方式与@noob 描述的相同。
【解决方案2】:

对我来说,在inputProps 中将语言属性设置为"en-US" 有效:

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

【讨论】:

  • 我刚刚检查过,不幸的是,它不起作用。您可以尝试将语言环境更改为 fr-fr(或任何欧洲语言环境),看看它是否会为您将小数点分隔符更改为逗号而不是点。
【解决方案3】:

我提出了同时接受 , 和 .使用正则表达式验证器的分隔符。

除了控制输入标签,我还控制外部数字状态

在我的解决方案中,用户只能输入小数分隔。或 , 输入标签和数值状态仅在用户输入可转换为浮点数时发生变化,如果输入为空 "" 输入,数值状态设置为 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}
                />);

【讨论】:

    猜你喜欢
    • 2011-07-11
    • 2015-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    相关资源
    最近更新 更多