Только цифры. Входной номер в реале
Я пытаюсь исключить минус и плюс из входных данных, но это не так:
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) : ''})
}
объяснение
-
parseInt()
возвращает NaN
если параметр не является числом. -
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()}
/>