Только цифры. Входной номер в реале

Я пытаюсь исключить минус и плюс из входных данных, но это не так:

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

Ответы

Ответ 1

Я попытался подражать вашему коду и заметил, что существует проблема с React с <input type='number'/>. Чтобы обходной путь, проверьте этот пример и попробуйте сами: https://codepen.io/zvona/pen/WjpKJX?editors=0010

Вы должны определить его как обычный ввод (type = 'text') с шаблоном только для чисел:

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

А затем сравнить действительность ввода:

const financialGoal = (evt.target.validity.valid)? evt.target.value: this.state.financialGoal;

Самое большое предостережение в этом подходе - когда речь идет о мобильных устройствах → где клавиатура не в цифровом, а в нормальном алфавитном формате.

Ответ 2

  • Чтобы прекратить печатать, используйте onKeyPress не onChange.

  • Использование event.preventDefault() внутри onKeyPress означает STOP событие прессования.

  • Поскольку обработчик 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>

Ответ 3

одна строка кода

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

Ответ 4

Если вы хотите сохранить type='number' ввода type='number' (возможно, для мобильных устройств для запуска цифровой клавиатуры), вы должны использовать onInput вместо onChange для захвата изменений вашего события.

Использование onInput исправило ошибку, из-за которой ввод текста в числовой ввод обходил проверку, назначенную ему в onChange. Как только я исправил эту функцию для onInput в 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 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 здесь

Ответ 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.

Ответ 6

Может быть, это будет полезно для кого-то
Недавно я использовал это решение для своего приложения
Я не уверен, что это правильное решение, но оно отлично работает.

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 и т.д.
также, если вы используете эти методы, они не работают на сенсорных устройствах

Ответ 7

Определите ввод с помощью onChange() как onChange() ниже (в моем случае childState содержит состояние, переданное этому дочернему компоненту).

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

Один из подходов, который я использовал, - установить validatorJS (npm install validator --save)

Затем я определил функцию handleChangeInteger, которая принимает объект, который будет использоваться для изменения вашего состояния, в этом случае {volume: e.target.value}. Примечание. Мне нужно условие ИЛИ, чтобы мой ввод был пустым, иначе он не позволит пользователю перекрыть (удалить) последнее целое число, если они хотят, чтобы поле было пустым.

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

Теперь пользователю не будет разрешено вводить в поле ввода ничего, кроме backspace, 0-9 или e (это число..).

Я ссылался на это сообщение, чтобы создать свое решение: fooobar.com/questions/6783918/...

Ответ 8

Самое эффективное и простое решение, которое я нашел:

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