web-dev-qa-db-fra.com

Réagissez au texte natif en entrée qui n'accepte que les caractères numériques

J'ai besoin d'un composant TextInput de React Native qui permet uniquement la saisie de caractères numériques (0 à 9). Je peux définir keyboardType sur numeric, ce qui me permet presque d’y entrer, sauf pour le point (.). Cependant, cela ne fait rien pour arrêter de coller des caractères non numériques dans le champ.

Ce que j’ai trouvé jusqu’à présent, c’est d’utiliser l’événement OnChangeText pour examiner le texte saisi. Je supprime tous les caractères non numériques du texte. Ensuite, placez le texte dans un champ d'état. Puis mettez à jour le TextInput via sa propriété Value. Extrait de code ci-dessous.

<TextInput 
  style={styles.textInput}
  keyboardType = 'numeric'
  onChangeText = {(text)=> this.onChanged(text)}
  value = {this.state.myNumber}
/> 

onTextChanged(text) {
  // code to remove non-numeric characters from text
  this.setState({myNumber: text})
}

Cela semble fonctionner, mais cela ressemble à un hack. Y a-t-il une autre façon de faire cela?

59
Terry Diederich

C’est la bonne façon de le faire jusqu’à ce qu’un tel composant (ou attribut sur le TextInput) soit spécifiquement développé.

Le Web a le type ‘numéro’ pour l’élément d’entrée, mais c’est basé sur le Web et réagit-native n’utilise pas de vue Web.

Vous pouvez envisager de créer cette entrée en tant que composant de réaction (appelez NumberInput): vous pourrez ainsi la réutiliser ou même l’ouvrir en tant que source, car vous pouvez créer de nombreux TextInputs dotés de différents filtres/vérificateurs de valeur.

L'inconvénient de la correction immédiate est de s'assurer que l'utilisateur reçoit un retour correct afin d'éviter toute confusion quant à ce qui est arrivé à sa valeur.

13
Tjorriemorrie

Vous pouvez le faire comme ça. Il acceptera uniquement les valeurs numériques et limitera à 10 le nombre souhaité.

<TextInput 
   style={styles.textInput}
   keyboardType='numeric'
   onChangeText={(text)=> this.onChanged(text)}
   value={this.state.myNumber}
   maxLength={10}  //setting limit of input
/>

Vous pouvez voir la valeur entrée en écrivant le code suivant sur votre page:

{this.state.myNumber}

Dans la fonction onChanged (), le code ressemble à ceci:

onChanged(text){
    let newText = '';
    let numbers = '0123456789';

    for (var i=0; i < text.length; i++) {
        if(numbers.indexOf(text[i]) > -1 ) {
            newText = newText + text[i];
        }
        else {
            // your call back function
            alert("please enter numbers only");
        }
    }
    this.setState({ myNumber: newText });
}

J'espère que cela est utile aux autres.

59
Venkatesh Somu

Utiliser une RegExp pour remplacer un non-chiffre est plus rapide que d'utiliser une boucle for avec une liste blanche, comme le font les autres réponses.

Utilisez ceci pour votre gestionnaire onTextChange:

onChanged (text) {
    this.setState({
        mobile: text.replace(/[^0-9]/g, ''),
    });
}

Test de performance ici: https://jsperf.com/removing-non-digit-characters-from-a-string

45
Jake Taylor

React Native TextInput fournit aux propriétés keyboardType les valeurs possibles suivantes: pavé numérique par défaut pavé décimal par défaut pavé numérique adresse électronique pavé numérique

ainsi, dans votre cas, vous pouvez utiliser keyboardType = 'pavé numérique' pour n'accepter que des nombres. Cela n'inclut pas '.'

alors,

<TextInput 
  style={styles.textInput}
  keyboardType = 'number-pad'
  onChangeText = {(text)=> this.onChanged(text)}
  value = {this.state.myNumber}
/>

est ce que vous devez utiliser dans votre cas.

pour plus de détails, veuillez vous référer au lien de documentation officiel pour TextInput: https://facebook.github.io/react-native/docs/textinput#keyboardttype

5
Ganesh Krishna
<TextInput autoCapitalize={'none'} maxLength={10} placeholder='Mobile Number'  value={this.state.mobile} onChangeText={(mobile) => this.onChanged(mobile)}/>

et la méthode onChanged:

onChanged(text){
   var newText = '';
   var numbers = '0123456789';
   if(text.length < 1){
     this.setState({ mobile: '' });
   }
   for (var i=0; i < text.length; i++) {
        if(numbers.indexOf(text[i]) > -1 ) {
             newText = newText + text[i];
        }
        this.setState({ mobile: newText });
    }
}
3
Bheru Lal Lohar

J'avais le même problème sous iOS, en utilisant l'événement onChangeText pour mettre à jour la valeur du texte tapé par l'utilisateur. Je ne pouvais pas mettre à jour la valeur de TextInput. L'utilisateur pouvait donc voir les caractères non numériques qu'il avait saisis.

En effet, lorsqu'un caractère non numérique était enfoncé, l'état ne changerait pas car this.setState utiliserait le même nombre (le nombre restant après la suppression des caractères non numériques) et le TextInput ne serait pas rendu.

Le seul moyen que j’ai trouvé pour résoudre ce problème était d’utiliser l’événement keyPress qui se produit avant l’événement onChangeText et dans celui-ci, utilisez setState pour modifier la valeur de l’état en un autre, complètement différent, forçant le rendu lors du rappel de l'événement onChangeText . Pas très content avec ça mais ça a marché.

2
Gustavo Franco

Fonction pour valider la saisie:

validateInputs(text, type) {
let numreg = /^[0-9]+$/;
  if (type == 'username') {
    if (numreg.test(text)) {
      //test ok
    } else {
      //test not ok
    } 
  }
}



<TextInput
   onChangeText={text => this.validateInputs(text, 'username')}
/>

J'espère que ceci est utile.

2
Abdul Karim Khan

Autoriser uniquement les nombres utilisant une expression régulière

<TextInput 
  keyboardType = 'numeric'
  onChangeText = {(e)=> this.onTextChanged(e)}
  value = {this.state.myNumber}
/> 

onTextChanged(e) {
  if (/^\d+$/.test(e.toString())) { 
    this.setState({ myNumber: e });
  }
}
2
jasonleonhard

Rappel aimable à ceux qui ont rencontré le problème que "onChangeText" ne peut pas modifier la valeur TextInput comme prévu sur iOS: il s'agit en fait d'un bogue dans ReactNative qui avait été corrigé dans la version 0.57.1. Voir: https://github.com/facebook/react-native/issues/18874

2
Wing
if (!/^[0-9]+$/.test('123456askm')) {
  consol.log('Enter Only Number');
} else {
    consol.log('Sucess');
}
1
ANKIT-DETROJA

Utiliser un RegExp pour remplacer un non-chiffre. Attention, le code suivant vous donnera le premier chiffre trouvé. Ainsi, si vous collez un paragraphe avec plus d’un chiffre (xx.xx), le code vous donnera le premier chiffre. Cela vous aidera si vous voulez quelque chose comme le prix, pas un téléphone portable. 

Utilisez ceci pour votre gestionnaire onTextChange:

onChanged (text) {
    this.setState({
        number: text.replace(/[^(((\d)+(\.)\d)|((\d)+))]/g,'_').split("_"))[0],
    });
}
1

J'ai écrit cette fonction que j'ai trouvée utile pour empêcher l'utilisateur de pouvoir entrer autre chose que ce que j'étais disposé à accepter. J'ai aussi utilisé keyboardType="decimal-pad" et mon onChangeText={this.decimalTextChange}

decimalTextChange = (distance) => { let decimalRegEx = new RegExp(/^\d*\.?\d*$/) if (distance.length === 0 || distance === "." || distance[distance.length - 1] === "." && decimalRegEx.test(distance)){ this.setState({distance}) } else { const distanceRegEx = new RegExp(/^\s*-?(\d+(\.\d{1,2})?|\.\d{1,2})\s*$/) if ( distanceRegEx.test(distance)) this.setState({distance}) } }

Le premier bloc if correspond au traitement des erreurs pour l'événement dans lequel l'utilisateur supprime tout le texte ou utilise un point décimal comme premier caractère. S'il tente de placer plusieurs décimales, le second bloc if permet de taper en autant de nombres qu'ils le souhaitent avant la décimale, mais uniquement jusqu'à deux décimales après le point.

1
Andrew M Yasso

Voici mon autre réponse simple, qui consiste à n'accepter que les nombres dans la zone de texte à l'aide d'expressions régulières.

onChanged(text){
    this.setState({ 
         myNumber: text.replace(/[^0-9]/g, '') 
    });
}
0
Venkatesh Somu

Vous pouvez supprimer des caractères non numériques en utilisant regex

onTextChanged (text) {
    this.setState({
        myNumber: text.replace(/\D/g, ''),
    });
}
0
Anoop

Pour le nombre décimal/à virgule flottante, essayez uniquement ceci

    onChangeMyFloatNumber(text){
let newText = '';
let numbers = '0123456789.';

for (var i=0; i < text.length; i++) {
    if(numbers.indexOf(text[i]) > -1 ) {
        newText = newText + text[i];
        if(text[i]=="."){
          numbers = '0123456789'
        }
    }
    else {
        // your call back function
        alert("please enter numbers only");
    }
}
this.setState({ MyFloatNumber: newText });

}

0
abinthomas12914

Cela ne fonctionne pas sur IOS, setState -> render -> ne modifie pas le texte, mais peut changer les autres . Le textinput ne peut pas changer lui-même la valeur lorsque textOnChange.

au fait, cela fonctionne bien sur Android.

0
wv1124

J'ai créé un composant qui résout ce problème:

https://github.com/amirfl/react-native-num-textinput

0
amirfl