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?
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.
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.
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
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
<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 });
}
}
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é.
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.
<TextInput
keyboardType = 'numeric'
onChangeText = {(e)=> this.onTextChanged(e)}
value = {this.state.myNumber}
/>
onTextChanged(e) {
if (/^\d+$/.test(e.toString())) {
this.setState({ myNumber: e });
}
}
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
if (!/^[0-9]+$/.test('123456askm')) {
consol.log('Enter Only Number');
} else {
consol.log('Sucess');
}
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],
});
}
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.
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, '')
});
}
Vous pouvez supprimer des caractères non numériques en utilisant regex
onTextChanged (text) {
this.setState({
myNumber: text.replace(/\D/g, ''),
});
}
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 });
}
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.
J'ai créé un composant qui résout ce problème: