繁体   English   中英

我如何在 React 中制作一个只允许数字或空值的文本框,这会触发移动设备上的数字键盘?

[英]How can I make a text box in React which allows only numbers or an empty value, which triggers the number keypad on mobile?

StackOverflow 上有很多这样的问题,但没有一个能在同一个解决方案中捕获我的所有需求。 任何帮助表示赞赏。

问题

在我的 React 应用程序中,我需要一个具有以下特征的文本框:

  1. 它只允许输入数字 - 除了数字 0-9 之外,不允许输入减号、小数位、字母或任何其他内容。
  2. 它会自动调出 iOS 和 Android 上的数字键盘
  3. 我可以进一步限制应该输入的数字,例如只允许 4 位数字
  4. 前导零会自动修剪,例如,如果用户键入 02,它应该更正为 2
  5. 它允许一个空的文本框,并且可以区分空值和 0 值

当前代码

https://codepen.io/micahrl/pen/RwGeLmo

此代码允许键入非数字,并且只会将值解释为 NaN。 例如,用户可以键入2fasdf ,页面将显示You typed: NaN

此外,虽然页面最初加载时带有一个空文本框,但用户无法键入内容然后将其删除回空。 尝试删除输入框中的所有文本会在框中放置一个0

最后,这段代码不能可靠地修剪前导零,这给我带来了特殊的问题,因为我想将数字限制为四位。 输入01不会截断前导零; 在某些浏览器上,键入01111将得到1111 ,这已经足够了,而在其他浏览器上,键入01111将得到0111 ,这是一个问题。

我试过的

因为我在输入元素上设置了type="number" ,所以如果文本框中添加了一个非数字, setNumWrapper中的event.target.value将是一个空字符串。 这意味着我无法区分真正的空字符串(用户已删除所有文本)和无效输入(用户键入了非数字,如asdf )。

我可以在输入元素上设置type="text" ,但我认为我需要将其设置为number才能在 iOS 和 Android 等移动操作系统上获得数字键盘。

通过进一步的实验,以及@Keith 在评论中的一些帮助,我几乎解决了所有问题。

我在我的问题中分叉了 codepen,并在分叉中做了这些更改: https://codepen.io/micahrl/pen/GRjwqdO

检查输入有效性

@Keith 向我指出了validity.badInput ( https://developer.mozilla.org/en-US/docs/Web/API/ValidityState/badInput )。 有了这个,我可以区分空输入(用户键入内容然后将其删除)和错误输入(用户尝试添加非数字字符)。

这意味着我将其添加到setNumWrapper()的开头:

    if (event.target.value === "") {
      if (event.target.validity.badInput) {
        // Set the text box and number to the old value - ignore the bad input
        inputRef.current.value = String(num);
        setNum(num);
      } else {
        // The data in the text box was deleted - set everything to empty
        inputRef.current.value = "";
        setNum(NaN);
      }
      return;
    }

我还必须使用useRef()创建一个inputRef ,并将其设置在<input>元素上。

这解决了#1 中的#5 大部分问题(但请参阅下面的剩余小问题)。

修剪前导零

为此,我所要做的就是使用inputRefsetNumWrapper()末尾的<input>元素中设置值:

inputRef.current.value = String(newNum);

<input>元素的值无论如何始终是一个字符串,并且将数字强制转换为一个删除前导零的字符串(如果有的话)。

遗留问题:如果文本框为空,则允许无效输入

当文本框为空时,用户可以在其中键入非数字字符,而setNumWrapper()甚至不会触发。 如果将console.log()放在setNumWrapper()的顶部,如果用户键入字母,它不会在日志中打印任何内容,但如果用户键入数字,它会在日志中打印。

这意味着我不能使用setNumWrapper()来解决这个问题。

但是,它也相对较小。 在手机上,数字键盘出现,防止非数字输入。 在桌面上,没有什么可以阻止用户使用键盘输入字母,但对于我的应用程序,很明显只允许使用数字,所以现在这已经足够了。

不过,如果有办法解决这个问题,我很想听听。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM