强制具有类型编号的 TextField 将点显示为小数分隔符

Posted

技术标签:

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

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

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

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

【问题讨论】:

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

【讨论】:

以上是关于强制具有类型编号的 TextField 将点显示为小数分隔符的主要内容,如果未能解决你的问题,请参考以下文章

如何强制 git 将点文件添加到存储库

SwiftUI TextField 强制小写

为具有更多限制性默认值的可选参数强制使用更广泛的类型

Swift 如何在另一个 UITextField 突出显示或具有值时禁用 TextField

强制禁用的 MI TextField 可点击

将点从 DWG 模型坐标转换为 Autodesk Forge 查看器坐标