react native - react - Reaccionar entrada de texto nativo que solo acepta caracteres numéricos
textinput example react native (17)
Solo permite números usando una expresión regular
<TextInput
style={styles.textInput}
keyboardType = ''number-pad''
onChangeText = {(text)=> this.onChanged(text)}
value = {this.state.myNumber}
/>
Es posible que desee tener más de una validación
<TextInput
keyboardType = ''numeric''
onChangeText = {(e)=> this.onTextChanged(e)}
value = {this.state.myNumber}
/>
onTextChanged(e) {
if (/^/d+$/.test(e.toString())) {
this.setState({ myNumber: e });
}
}
Necesito tener un componente React Native
TextInput
que solo permita ingresar caracteres numéricos (0 - 9).
Puedo configurar el
keyboardType
en
numeric
que casi me lleva allí para la entrada, excepto por el punto (.).
Sin embargo, esto no hace nada para dejar de pegar caracteres no numéricos en el campo.
Lo que se me ocurrió hasta ahora es usar el evento
OnChangeText
para ver el texto ingresado.
Elimino los caracteres no numéricos del texto.
Luego ponga el texto en un campo de estado.
Luego actualice
TextInput
través de su propiedad
Value
.
Fragmento de código a continuación.
<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})
}
Esto parece funcionar pero parece un truco. Hay otra manera de hacer esto?
Aquí está mi otra respuesta simple para aceptar solo números en el cuadro de texto usando Expresiones regulares.
onChanged(text){
this.setState({
myNumber: text.replace(/[^0-9]/g, '''')
});
}
Esa es la forma correcta de hacerlo hasta que dicho componente (o atributo en TextInput) se desarrolle específicamente.
La web tiene el tipo ''número'' para el elemento de entrada, pero está basado en la web y react-native no utiliza una vista web.
Podría considerar crear esa entrada como un componente de reacción por sí mismo (tal vez llame a NumberInput): eso le permitirá reutilizarlo o incluso abrir el código fuente ya que puede crear muchas TextInputs que tienen diferentes filtros / verificadores de valor.
La desventaja de la corrección inmediata es garantizar que el usuario reciba comentarios correctos para evitar confusiones sobre lo que sucedió con su valor.
Escribí esta función que encontré útil para evitar que el usuario pueda ingresar cualquier otra cosa que no esté dispuesto a aceptar.
También utilicé
keyboardType="decimal-pad"
y mi
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}) } }
El primer bloque
if
es el manejo de errores para el evento, el usuario elimina todo el texto, o usa un punto decimal como primer carácter, o si intenta poner más de un decimal, el segundo bloque
if
se asegura de que pueda escribir en tantos números como deseen antes del lugar decimal, pero solo hasta dos lugares decimales después del punto.
Esto no funciona en IOS, setState -> render -> no cambia el texto, pero puede cambiar otro. El textinput no puede cambiar su valor cuando textOnChange.
Por cierto, esto funciona bien en Android.
Función para validar la entrada:
<TextInput
keyboardType = ''numeric''
onChangeText = {(e)=> this.validations(e)}
value = {this.state.myNumber}
/>
numbersOnly(e) {
return /^/d+$/.test(e.toString()) ? true : false
}
notZero(e) {
return /0/.test(parseInt(e)) ? false : true
}
validations(e) {
return this.notZero(e) && this.numbersOnly(e)
? this.setState({ numColumns: parseInt(e) })
: false
}
Espero que esto sea útil.
He creado un componente que resuelve este problema:
Puede eliminar caracteres no numéricos usando regex
onTextChanged (text) {
this.setState({
myNumber: text.replace(//D/g, ''''),
});
}
Puedes hacerlo así. Solo aceptará valores numéricos y se limitará a 10 números como desee.
<TextInput
style={styles.textInput}
keyboardType=''numeric''
onChangeText={(text)=> this.onChanged(text)}
value={this.state.myNumber}
maxLength={10} //setting limit of input
/>
Puede ver el valor ingresado escribiendo el siguiente código en su página:
{this.state.myNumber}
En la función onChanged (), el código se ve así:
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 });
}
Espero que esto sea útil para otros.
React Native TextInput proporciona accesorios de tipo teclado con los siguientes valores posibles: teclado numérico predeterminado teclado decimal dirección de correo electrónico teclado numérico
entonces, para su caso, puede usar keyboardType = ''number-pad'' para aceptar solo números. Esto no incluye ''.''
entonces,
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'')}
/>
es lo que tienes que usar en tu caso.
Para obtener más detalles, consulte el enlace de documentación oficial de TextInput: https://facebook.github.io/react-native/docs/textinput#keyboardtype
Tuve el mismo problema en iOS, al usar el evento onChangeText para actualizar el valor del texto escrito por el usuario, no podía actualizar el valor de TextInput, por lo que el usuario aún vería los caracteres no numéricos que escribió.
Esto se debía a que, cuando se presionaba un carácter no numérico, el estado no cambiaba ya que this.setState usaría el mismo número (el número que quedaba después de eliminar los caracteres no numéricos) y luego TextInput no se volvería a procesar.
La única forma que encontré para resolver esto fue usar el evento keyPress que ocurre antes del evento onChangeText, y en él, usar setState para cambiar el valor del estado a otro, completamente diferente, forzando el renderizado cuando se llamó al evento onChangeText . No estoy muy contento con esto, pero funcionó.
Un amable recordatorio para aquellos que encontraron el problema de que "onChangeText" no puede cambiar el valor de TextInput como se esperaba en iOS: eso es en realidad un error en ReactNative y se ha solucionado en la versión 0.57.1. Consulte: github.com/facebook/react-native/issues/18874
Usando un RegExp para reemplazar cualquier no dígito. Tenga cuidado, el siguiente código le dará el primer dígito que encontró, por lo que si el usuario pega un párrafo con más de un número (xx.xx), el código le dará el primer número. Esto ayudará si desea algo como el precio, no un teléfono móvil.
Use esto para su controlador onTextChange:
if (!/^[0-9]+$/.test(''123456askm'')) {
consol.log(''Enter Only Number'');
} else {
consol.log(''Sucess'');
}
Usar un RegExp para reemplazar cualquier no dígito es más rápido que usar un bucle for con una lista blanca, como hacen otras respuestas.
Use esto para su controlador onTextChange:
onChanged (text) {
this.setState({
mobile: text.replace(/[^0-9]/g, ''''),
});
}
Prueba de rendimiento aquí: https://jsperf.com/removing-non-digit-characters-from-a-string
Para el número decimal / coma flotante solo intente esto
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 });
}
<TextInput autoCapitalize={''none''} maxLength={10} placeholder=''Mobile Number'' value={this.state.mobile} onChangeText={(mobile) => this.onChanged(mobile)}/>
y método 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 });
}
}
onChanged (text) {
this.setState({
number: text.replace(/[^(((/d)+(/.)/d)|((/d)+))]/g,''_'').split("_"))[0],
});
}