web-dev-qa-db-fra.com

Seulement les chiffres. Entrez le nombre dans React

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

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.

28
zvona
  • 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();
    }
    

Démo ci-dessous ????????

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>
15
Abdennour TOUMI

une ligne de code

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

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!

EDIT - 08-03-2018:

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

10
Jimmay

Solution

Aujourd'hui, je trouve que l'utilisation de parseInt() est également une bonne et propre pratique. Un exemple de onChange(e) est ci-dessous.

Code

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

Explication

  1. parseInt() renverrait NaN si le paramètre n'est pas un nombre.
  2. parseInt('12a') renverrait 12.
4
Zhijian

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

0
Marquistador

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()}
/>
0
zishe

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.

  • La valeur du champ de texte est toujours 0
  • Quand le backspacing, vous finirez avec 0
  • Lorsque la valeur est 0 et que vous commencez à taper, 0 sera remplacé par le nombre actuel
// 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>
    );
};
0
Skid Kadda