只有数字。 React中的输入数字

时间:2017-04-28 19:53:04

标签: javascript regex reactjs

我试图从输入中排除减号和加号,但它出错了:

handleChange(event) {
  const value = event.target.value.replace(/\+|-/ig, '');
  this.setState({financialGoal: value});
}

渲染输入代码:

<input style={{width: '150px'}} type="number" value={this.state.financialGoal} onChange={this.handleChange}/>

17 个答案:

答案 0 :(得分:25)

我试图模仿您的代码并注意到 React react-native-share存在问题。有关解决方法,请查看此示例并自行尝试:https://codepen.io/zvona/pen/WjpKJX?editors=0010

您需要将其定义为普通输入(type ='text'),仅包含数字模式:

<input type='number' />

然后比较输入的有效性:

<input type="text" pattern="[0-9]*" onInput={this.handleChange.bind(this)} value={this.state.financialGoal} />

这种方法最大的一点是当涉及到移动时 - &gt;键盘不是数字键,而是正常的字母格式。

答案 1 :(得分:16)

  • 要停止输入,请使用onKeyPress而不是onChange

  • event.preventDefault()内使用onKeyPress表示停止按下事件。

  • 由于在keyPress之前触发onChange处理程序,您必须检查按下的键(event.keyCode),而不是输入的当前值(event.target.value

    onKeyPress(event) {
      const keyCode = event.keyCode || event.which;
      const keyValue = String.fromCharCode(keyCode);
      if (/\+|-/.test(keyValue))
        event.preventDefault();
    }
    

下面的演示

const {Component} = React; 

class Input extends Component {
  

  onKeyPress(event) {
   const keyCode = event.keyCode || event.which;
   const keyValue = String.fromCharCode(keyCode);
    if (/\+|-/.test(keyValue))
      event.preventDefault();
  }
  render() {
  
   return (
   <input style={{width: '150px'}} type="number" onKeyPress={this.onKeyPress.bind(this)} />

   )
  }
 
}

ReactDOM.render(<Input /> , document.querySelector('#app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<section id="app"></section>

答案 2 :(得分:13)

一行代码

<input value={this.state.financialGoal} onChange={event => this.setState({financialGoal: event.target.value.replace(/\D/,'')})}/>

答案 3 :(得分:8)

如果您想维护输入type='number'(可能是移动设备触发数字键盘),您应该使用onInput代替onChange来捕获事件更改。

使用onInput修复了一个错误,即在数字输入中键入文本会绕过我在onChange中分配给它的验证。一旦我修复了要在onInput中调用的函数,它就会在所有实例中触发。

以下是我正在做的一个例子:

<input
    type='number'
    id={`player${index}Score`}
    className='form-control'
    pattern='[0-9]{0,5}'
    onInput={(event) => this.enterScore(event, index)}
    value={this.props.scoreLabel(this.state.scores[index])}
/>

我希望这有帮助!

编辑 - 08-03-2018:

我想出了一个更好的解决方案。在输入组件本身中使用type ='tel'以及模式正则表达式。

我如何连接它的具体细节在这里:

class Input extends React.Component {
  state = {message: '3'};

  updateNumber = (e) => {
    const val = e.target.value;
    // If the current value passes the validity test then apply that to state
    if (e.target.validity.valid) this.setState({message: e.target.value});
    // If the current val is just the negation sign, or it's been provided an empty string,
    // then apply that value to state - we still have to validate this input before processing
    // it to some other component or data structure, but it frees up our input the way a user
    // would expect to interact with this component
    else if (val === '' || val === '-') this.setState({message: val});
  }

  render() {
    return (
      <input
        type='tel'
        value={this.state.message}
        onChange={this.updateNumber}
        pattern="^-?[0-9]\d*\.?\d*$"
      />
    );
  }
}

ReactDOM.render(<Input />, document.getElementById('main'));

我有一个关于Codepen here

的例子

答案 4 :(得分:5)

解决方案

今天,我发现使用parseInt()也是一种好方法。下面是一个onChange(e)的示例。

代码

onChange(e){
    this.setState({[e.target.id]: parseInt(e.target.value) ? parseInt(e.target.value) : ''})
}

说明

    如果参数不是数字,
  1. parseInt()将返回NaN
  2. parseInt('12a')将返回12。

答案 5 :(得分:2)

 <input
        className="input-Flied2"
        type="TEXT"
        name="userMobileNo"
        placeholder="Moble No"
        value={phonNumber}
        maxLength="10"
        onChange={handleChangeInput}
        required
      />

  const handleChangeInput = (e) => {
const re = /^[0-9\b]+$/; //rules
if (e.target.value === "" || re.test(e.target.value)) {
  setPhoneNumber(e.target.value);
}

};

答案 6 :(得分:1)

2019年回答晚了,但希望对您有所帮助

  

这将确保您不会在空白文本字段上获得空值

  • 文本字段的值始终为0
  • 退格时,您将以0结尾
  • 当value为0并开始输入时,0将替换为实际数字
// This will make sure that value never is null when textfield is empty

const minimum = 0;   

export default (props) => {
    const [count, changeCount] = useState(minimum);

    function validate(count) {
        return parseInt(count) | minimum
    }

    function handleChangeCount(count) {
        changeCount(validate(count))
    }

    return (
        <Form>
            <FormGroup>
                <TextInput
                    type="text"
                    value={validate(count)}
                    onChange={handleChangeCount}
                />
            </FormGroup>
            <ActionGroup>
                <Button type="submit">submit form</Button>
            </ActionGroup>
        </Form>
    );
};

答案 7 :(得分:1)

这是我使用纯Javascript的解决方案

keyup事件附加到您选择的input字段-在此示例中为id
在事件处理函数中,只需使用给定的正则表达式测试event.key的键即可。

在这种情况下,如果不匹配,我们将阻止该元素的默认操作-因此不会在输入框中注册“错误”的按键,因此它将永远不会出现在输入框中。

  let idField = document.getElementById('id');

  idField.addEventListener('keypress', function(event) {
    if (! /([0-9])/g.test(event.key)) {
      event.preventDefault();
    }
  });

此解决方案的好处可能是其灵活的性质,并且通过更改和/或逻辑链接正则表达式可以满足许多要求。 例如。 regex /([a-z0-9-_])/g应该只匹配小写英文字母数字字符,没有空格,并且只能匹配-_

请注意:如果您使用/[a-z]/gi(请注意末尾的 i ),则会忽略 字母大小写,并且仍会接受大写字母。

答案 8 :(得分:0)

我找到的最有效,最简单的解决方案:

<input
    type="number"
    name="phone"
    placeholder="Phone number"
    onKeyDown={e => /[\+\-\.\,]$/.test(e.key) && e.preventDefault()}
/>

答案 9 :(得分:0)

在阅读完所有答案之后,但只有复制和粘贴才能真正解决数字问题,我想到了这个解决方案。

  • parseInt解决方案:由于parseInt("2a")有效,因此失败;
  • onKeyup sulution:复制和粘贴失败,退格;
  • key。哪种解决方案:在复制和粘贴时可能会失败;
  • type =“ number”解决方案:长号失败,因为javascript是53位语言,因此将40817810000000023511转换为40817810000000023500
<input
    name="address.line1"
    value={values.address.line1}
    onChange={(event: any) => {
      if (isFinite(event.target.value)) {
      // UPDATE YOUR STATE (i am using formik)
      setFieldValue("address.line1", event.target.value);
    }
  }}
/>

答案 10 :(得分:0)

使用如下所示的onChange()方法定义输入(在我的情况下,childState包含状态,并传递给此子组件)。

<input
   ...
   value={this.props.childState.volume}
   ...
   onChange={(e) => handleChangeInteger(e, {volume: e.target.value})}
/>

我使用的一种方法是安装validatorJSnpm install validator --save

然后,我定义了一个函数handleChangeInteger,该函数带有一个将用于更改状态的对象,在本例中为{volume: e.target.value}。注意:我需要OR条件,以允许我的输入为空白,否则,如果他们希望字段为空白,则不允许用户退格(删除)最后一个整数。

const handleChangeInteger = (e, obj_to_return) => {
  if (validator.isInt(e.target.value) || e.target.value == '') {
    this.props.childSetState(obj_to_return)
  }
}

现在将不允许用户在输入字段中键入除退格键,0-9或e(这是一个数字..)以外的任何内容。

我引用了这篇文章来创建我的解决方案:https://stackoverflow.com/a/45676912/6169225

答案 11 :(得分:0)

这是onBlur的一种解决方案,它非常有用,因为它还允许您以所需的方式格式化数字,而无需任何黑魔法或外部库。

2020 React Hooks

const toNumber = (value: string | number) => {
    if (typeof value === 'number') return value
    return parseInt(value.replace(/[^\d]+/g, ''))
}

const formatPrice = (price: string | number) => {
  return new Intl.NumberFormat('es-PY').format(toNumber(price))
}
<input
    defaultValue={formatPrice(price)}
    onBlur={e => {
      const numberValue = toNumber(e.target.value)
      setPrice(numberValue)
      e.target.value = formatPrice(numberValue)
    }}
    type='tel'
    required
/>

工作方式:

  • 通过defaultValue设置初始值
  • 允许用户自由输入自己的感受
  • onBlur(一旦输入失去焦点):
    • 用空字符串替换不是数字的任何字符
    • setState()或dispatch()来管理状态
    • 将输入字段的值设置为数值并应用可选格式

请注意: 如果您的值来自异步来源(例如fetch):由于defaultValue仅会在第一个渲染上设置该值,因此您需要确保仅在数据存在后才渲染组件。

答案 12 :(得分:0)

也许对某人会有帮助
最近,我在我的App中使用了此解决方案
我不确定这是否是正确的解决方案,但是效果很好。

this.state = {
    inputValue: "",
    isInputNotValid: false
}

handleInputValue = (evt) => {
    this.validationField(evt, "isInputNotValid", "inputValue");
}

validationField = (evt, isFieldNotValid, fieldValue ) => {
   if (evt.target.value && !isNaN(evt.target.value)) {
        this.setState({ 
            [isFieldNotValid]: false,
            [fieldValue]: evt.target.value,
        });
    } else {
        this.setState({ 
            [isFieldNotValid]: true,
            [fieldValue]: "",
        });
    }
}

<input className={this.state.isInputNotValid ? "error" : null} type="text" onChange="this.handleInputValue" />

主要思想是,直到条件不成立且值将为空时,状态才会更新。
不需要使用onKeyPress,Down等。
如果使用这些方法,它们在触摸设备上也无法使用

答案 13 :(得分:0)

React的简单方式

<input
      onKeyPress={(event) => {
        if (!/[0-9]/.test(event.key)) {
          event.preventDefault();
        }
      }}
    />

答案 14 :(得分:0)

您可以尝试此解决方案,因为onkeypress将直接附加到DOM元素上,并会阻止用户输入无效的数据。

因此反应方面没有副作用。

<input type="text" onKeyPress={onNumberOnlyChange}/>

const onNumberOnlyChange = (event: any) => {
    const keyCode = event.keyCode || event.which;
    const keyValue = String.fromCharCode(keyCode);
    const isValid = new RegExp("[0-9]").test(keyValue);
    if (!isValid) {
       event.preventDefault();
       return;
    }
};

答案 15 :(得分:0)

我使用JS的isNaN函数来验证它是否是数字。

const handleChange2 = (e) => {
    if (isNaN(e.target.value)) {
      return;
    }
    const onlyNums = e.target.value.replace(/[^0-9]/g, "");
    setFormData({
      ...formData,
      [e.target.name]: onlyNums,
    });
  };

  const [formData, setFormData] = useState({
    name: "",
    phone: "",
    email: "",
    address: "",
  });

  <input
    value={phone}
    onChange={(e) => handleChange2(e)}
    placeholder="Phone"
    type="text"
    name="phone"
    required
   />

注意:存储在状态中的值是字符串,如果你希望它是一个数字/整数,只需使用 Number 将其转换为整数。例如:让电话=号码(formData.phone)

答案 16 :(得分:-2)

在输入字段中设置课程:

mod_wsgi (pid=25927): Request data read error when proxying data to daemon process: The timeout specified has expired.
ERROR:root:API_ERROR : Apache/mod_wsgi request data read error: Input is already in error state.
ERROR:root:API_HANDLER_EXCEPTION : local variable 'params' referenced before assignment
mod_wsgi (pid=25923): Exception occurred processing WSGI script '/opt/my_wsgi_app/start_server.wsgi'.

限制粘贴和拖放到您的输入字段:

$(".digitsOnly").on('keypress',function (event) {
    var keynum
    if(window.event) {// IE8 and earlier
       keynum = event.keyCode;
    } else if(event.which) { // IE9/Firefox/Chrome/Opera/Safari
       keynum = event.which;
    } else {
       keynum = 0;
    }

    if(keynum === 8 || keynum === 0 || keynum === 9) {
        return;
    }
    if(keynum < 46 || keynum > 57 || keynum === 47) {
        event.preventDefault();
    } // prevent all special characters except decimal point
}

在页面加载后立即在componentDidMount()中调用这些事件以应用该类。