J'essaie d'exclure le moins et le plus de l'entrée, mais ça ne va pas:
handleChange(event) {
const value = event.target.value.replace(/\+|-/ig, '');
this.setState({financialGoal: value});
}
Rendre le code d'entrée:
<input style={{width: '150px'}} type="number" value={this.state.financialGoal} onChange={this.handleChange}/>
J'ai essayé d'imiter votre code et j'ai remarqué que il y a un problème avec React avec <input type='number' />
. Pour résoudre ce problème, consultez cet exemple et essayez-le vous-même: https://codepen.io/zvona/pen/WjpKJX?editors=001
Vous devez le définir comme une entrée normale (type = 'text') avec un motif pour les nombres uniquement:
<input type="text" pattern="[0-9]*" onInput={this.handleChange.bind(this)} value={this.state.financialGoal} />
Et puis pour comparer la validité des entrées:
const financialGoal = (evt.target.validity.valid) ? evt.target.value : this.state.financialGoal;
Le plus gros inconvénient de cette approche concerne le mobile -> où le clavier n'est pas numérique mais au format alphabétique normal.
Pour arrêter de taper, utilisez onKeyPress
pas onChange
.
Utiliser event.preventDefault()
à l'intérieur de onKeyPress
signifie ARRÊTER l'événement en cours.
Puisque keyPress
gestionnaire est déclenché avant onChange
, vous devez vérifier la touche enfoncée (event.keyCode
), PAS la valeur actuelle de l’entrée (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>
une ligne de code
<input value={this.state.financialGoal} onChange={event => this.setState({financialGoal: event.target.value.replace(/\D/,'')})}/>
Si vous voulez conserver l'entrée type='number'
(probablement pour les appareils mobiles qui déclenchent le clavier numérique), vous devez utiliser onInput
au lieu de onChange
pour capturer vos modifications d’événement.
Utiliser onInput
corrigeait un bug où taper du texte dans une entrée numérique contournait la validation que je lui avais assignée dans onChange
. Une fois que j'ai corrigé cette fonction à appeler dans onInput
, elle s'est déclenchée dans tous les cas.
Voici un exemple de ce que je fais:
<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])}
/>
J'espère que ça aide!
Je suis venu avec une meilleure solution. Utilisez type = 'tel' avec un motif regex dans le composant d'entrée lui-même.
Les détails de la façon dont j'ai câblé ceci sont ici:
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'));
J'ai un exemple de ce travail sur Codepen here
Aujourd'hui, je trouve que l'utilisation de parseInt()
est également une bonne et propre pratique. Un exemple de onChange(e)
est ci-dessous.
onChange(e){
this.setState({[e.target.id]: parseInt(e.target.value) ? parseInt(e.target.value) : ''})
}
parseInt()
renverrait NaN
si le paramètre n'est pas un nombre.parseInt('12a')
renverrait 12.Définissez une entrée avec une méthode onChange()
comme ci-dessous (dans mon cas, childState contient l'état transmis à ce composant enfant).
<input
...
value={this.props.childState.volume}
...
onChange={(e) => handleChangeInteger(e, {volume: e.target.value})}
/>
L’une des méthodes que j’ai utilisées était d’installer validatorJS (npm install validator --save
)
J'ai ensuite défini une fonction handleChangeInteger
, qui prend un objet qui sera utilisé pour changer votre état, dans ce cas, {volume: e.target.value}
. Remarque: j'avais besoin de la condition OR pour que mes entrées soient vides. Sinon, l'utilisateur ne pourrait pas effacer le dernier entier s'il voulait que le champ soit vide.
const handleChangeInteger = (e, obj_to_return) => {
if (validator.isInt(e.target.value) || e.target.value == '') {
this.props.childSetState(obj_to_return)
}
}
L'utilisateur ne sera plus autorisé à taper quoi que ce soit autre que retour arrière, 0-9 ou e (c'est un nombre ..) dans le champ de saisie.
J'ai référencé ce post pour créer ma solution: https://stackoverflow.com/a/45676912/6169225
La solution la plus simple et efficace que j'ai trouvée:
<input
type="number"
name="phone"
placeholder="Phone number"
onKeyDown={e => /[\+\-\.\,]$/.test(e.key) && e.preventDefault()}
/>
Réponse tardive en 2019, mais espérons que cela aidera quelqu'un
Cela garantira que vous n'obtiendrez pas la valeur NULL dans un champ de texte vide.
// 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>
);
};