J'ai un champ de saisie numérique qui définit la nouvelle valeur via l'état lorsque l'utilisateur tape. Cela fonctionne très bien. Si toutefois j'y ajoute des décimales (toFixed), le curseur sautera à la fin de l'entrée après avoir tapé un seul chiffre. Cela se produit lorsque, par exemple, je supprime ce qui est là et que je tape autre chose. Si j'ajoute à la place un chiffre entre le premier et le point décimal, le curseur ne saute pas. Quelqu'un a-t-il déjà fait l'expérience de cela et quelle était la solution?
Fiddle pour montrer le problème: https: // jsfiddle.net/Inverness/k04yvq1u/
constructor() { super() this.state = { number: 1 } this.handleInputChange = this.handleInputChange.bind(this) } handleInputChange(event) { console.log(event.target.value) this.setState({ number: event.target.value }) } render() { return ( <div> <input type="number" value={ parseFloat(this.state.number).toFixed(2) } onChange={ this.handleInputChange } /> </div> ) }
4 Réponses :
Quelque chose de similaire s'est produit. Le principal problème ici est que vous reformatez ce qu'ils saisissent au fur et à mesure de leur saisie. Puisque react utilise javascript pour changer la valeur, le navigateur ne peut pas deviner où le curseur est censé aller, donc il saute juste à la fin. La façon dont j'ai résolu ce problème était de ne mettre à jour que lorsque l'utilisateur entre quelque chose qui correspond au format toFixed. Quelque chose à peu près équivalent qui devrait fonctionner est de définir value = {this.state.number}
sur votre entrée. Ensuite, le changement devrait ressembler à ceci:
handleInputChange = e => { let val = e.target.value if (/^[\d]*\.?[\d]{0,2}$/.test(val)) { this.setState({number: val}) } }
De cette façon, la valeur d'entrée est toujours contrainte d'être un format à virgule flottante à deux décimales, mais l'utilisateur a plus de liberté pour le saisir.
J'ai réussi à utiliser le gestionnaire d'événements onBlur
pour simplement formater le champ de saisie comme vous en avez besoin une fois que l'utilisateur a fini de taper.
Ajout d'un peu d'informations dans le formulaire L'étiquette de champ indiquant que l'entrée sera limitée à 2 espaces décimaux devrait aider à atténuer les problèmes UX liés à la modification d'une valeur fournie par l'utilisateur.
constructor() { super() this.state = { number: 1 } this.handleInputChange = this.handleInputChange.bind(this) this.formatInput = this.formatInput.bind(this) } handleInputChange(event) { console.log(event.target.value) this.setState({ number: event.target.value }) } formatInput() { const num = this.state.number this.setState({ number: parseFloat(num).toFixed(2) }) } render() { return ( <div> <input type="number" value={ this.state.number } onChange={ this.handleInputChange } onBlur={ this.formatInput } /> </div> ) }
Votre fonction toFixed change la valeur d'entrée, donc votre entrée perd son curseur, comme mentionné dans l'autre réponse que je suggérerais pour éviter de changer vos valeurs d'entrée, vous pouvez également essayer d'utiliser un attribut step pour avoir plus de contrôle sur votre entrée .
<input type="number" step="0.01" value={ this.state.number } onChange={ this.handleInputChange } defaultValue={ parseFloat(this.state.number).toFixed(2) } />
La réponse de @ ryan28561 est juste mais la solution ne l'est pas.
Comme il le dit, javascript ne saura pas où le curseur devrait être, donc ce que je recommande est le suivant:
Quitter l'entrée sans analyse et à la place, mettre un style ou un avertissement à l'entrée afin que l'utilisateur se rende compte que son entrée n'est pas correcte. De plus, avant d'utiliser le numéro pour une tâche, vous pouvez le formater.
class TodoApp extends React.Component { constructor() { super() this.state = { number: '1', wrongInput: false, } this.handleInputChange = this.handleInputChange.bind(this) } handleInputChange(event) { let val = event.target.value if (/^[\d]*\.?[\d]{0,2}$/.test(val)) { this.setState({number: val, wrongInput: false}) } else { this.setState({number: val, wrongInput: true}) } } render() { return ( <div> <input //type="number" style={this.state.wrongInput ? { border: `solid 1px red`, outline: 'none'} : {}} value={this.state.number} onChange={ this.handleInputChange } /> </div> ) } }
La
ne doit contenir que ce qui est dans l'état, de sorte que toute modification de la valeur saisie par l'utilisateur serait plus facile à faire dans le
valeur
dans l'élémentonChange
fonction.