Better

Ethan的博客,欢迎访问交流

NumericInput Component

浏览器原生的 input 标签支持传入 type 为 number 来限制只能输入数值,但这很多时候往往不是我们想要的,比如原始的 ui 中丑陋且在不同浏览器表现不一致的上下加减操作等,因此我们会有通过普通 input 创建数值型输入框的需求。

需求

自行书写数值型输入框的话,总担心自己会不会考虑不周,导致不满足需求,偶然间看到一个不错的例子。总结需要考虑的点有

  • 只有在用户输入空格或负号以及正确的数值时,才响应用户的输入,否则不响应,这样就限制了用户的非法输入
  • 失去焦点时,进行错误修正
    • 如果以 . 结尾,或只有一个 -,则移除
    • 去除首部多余的 0

示例

具体代码如下

/**
 * @description 格式化成标准数字字符串(整数部分每三个进行分割)
 * @param {*} value
 */
function formatNumber(value) {
  value += "";
  const list = value.split(".");
  // 针对负数进行前缀提取
  const prefix = list[0].charAt(0) === "-" ? "-" : "";
  // 提取整数部分,没三位添加分隔符
  let num = prefix ? list[0].slice(1) : list[0];
  let result = "";
  while (num.length > 3) {
    result = `,${num.slice(-3)}${result}`;
    num = num.slice(0, num.length - 3);
  }
  if (num) {
    result = num + result;
  }
  return `${prefix}${result}${list[1] ? `.${list[1]}` : ""}`;
}

class NumericInput extends React.Component {
  onChange = (e) => {
    const { value } = e.target;
    const reg = /^-?\d*(\.\d*)?$/;
    // 如果是一个数,或者为空串或仅有一个 -,则触发事件
    if ((!isNaN(value) && reg.test(value)) || value === "" || value === "-") {
      this.props.onChange(value);
    }
  };

  // '.' at the end or only '-' in the input box.
  onBlur = () => {
    const { value, onBlur, onChange } = this.props;
    let valueTemp = value;
    // 如果以 . 结尾,或只有一个 -,则在失焦时移除
    if (value.charAt(value.length - 1) === "." || value === "-") {
      valueTemp = value.slice(0, -1);
    }
    // 去除首部多余的 0
    onChange(valueTemp.replace(/0*(\d+)/, "$1"));
    if (onBlur) {
      onBlur();
    }
  };

  render() {
    const { value } = this.props;
    const title = value ? (
      <span className="numeric-input-title">
        {value !== "-" ? formatNumber(value) : "-"}
      </span>
    ) : (
      "Input a number"
    );
    return (
      <Tooltip
        trigger={["focus"]}
        title={title}
        placement="topLeft"
        overlayClassName="numeric-input"
      >
        <Input
          {...this.props}
          suffix="m"
          onChange={this.onChange}
          onBlur={this.onBlur}
          placeholder="Input a number"
          maxLength={25}
        />
      </Tooltip>
    );
  }
}


留言