angular - numeros - Forma correcta de restringir los valores de entrada de texto(por ejemplo, solo números)
solo numeros angularjs (12)
Algunas de las respuestas no funcionaron para mí, así que tomé las mejores notas de algunas de las respuestas (gracias a todos) y creé una Directiva Angular 5 que debería hacer el trabajo (y más) por usted. Tal vez no sea perfecto pero ofrece flexibilidad.
import { Directive, HostListener, ElementRef, Input, Renderer2 } from ''@angular/core'';
@Directive({
selector: ''[appInputMask]''
})
export class InputMaskDirective {
@Input(''appInputMask'') inputType: string;
showMsg = false;
pattern: RegExp;
private regexMap = { // add your own
integer: /^[0-9 ]*$/g,
float: /^[+-]?([0-9]*[.])?[0-9]+$/g,
words: /([A-z]*//s)*/g,
point25: /^/-?[0-9]*(?://.25|//.50|//.75|)$/g,
badBoys: /^[^{}*+£$%//^-_]+$/g
};
constructor(public el: ElementRef, public renderer: Renderer2) { };
@HostListener(''keypress'', [''$event'']) onInput(e) {
this.pattern = this.regexMap[this.inputType]
const inputChar = e.key;
this.pattern.lastIndex = 0; // dont know why but had to add this
if (this.pattern.test(inputChar)) {
// success
this.renderer.setStyle(this.el.nativeElement, ''color'', ''green'');
this.badBoyAlert(''black'');
} else {
this.badBoyAlert(''black'');
//do something her to indicate invalid character
this.renderer.setStyle(this.el.nativeElement, ''color'', ''red'');
e.preventDefault();
}
}
badBoyAlert(color: string) {
setTimeout(() => {
this.showMsg = true;
this.renderer.setStyle(this.el.nativeElement, ''color'', color);
}, 2000)
}
}
HTML <input class="form-control" appInputMask="badBoys">
¿Es posible implementar una input
que permita escribir solo números dentro sin el manejo manual de event.target.value
?
En React, es posible definir la propiedad de value
y luego el cambio de entrada estará básicamente vinculado al valor (no es posible modificarlo sin cambio de value
). Ver example Y funciona bien sin ningún esfuerzo.
En Angular 2 es posible definir [value]
, pero solo establecerá el valor inicialmente, y luego la input
no se impedirá de las modificaciones.
Estaba jugando con ngModel
y [value] / (input)
, ver example .
Pero en ambas implementaciones hay un problema esencial:
- cuando escribe 10 (el valor del modelo es 10; el valor de entrada es 10) - correcto
- cuando escribe 10d después (el valor del modelo es 10 - no modificado, todos los que no son dígitos se han eliminado; el valor de entrada es 10d) - incorrecto, porque el valor del modelo es el mismo que antes
- cuando escribe 10d3 - (el valor del modelo es 103; el valor de entrada es 103) - correcto
¿Cómo hacer ese componente simple (desde el primer vistazo), sin manejar manualmente event.target.value
? ...
ACTUALIZACIÓN No estoy buscando el elemento input[number]
HTML5 nativo aquí. El ingreso de números aquí es solo para el ejemplo: podría haber muchas más tareas cuando necesito restringir el texto de entrada.
Además, la input[number]
es 1) no me 10ddd
escribir 10ddd
y 2) (menos importante) contiene flechas que no necesito.
Y el problema aquí es evitar que el usuario escriba algo más allá de los valores restringidos, en lugar de permitir que ingrese algo y lo valide después
Creo que esto resolverá tu problema. Creé una directiva que filtra las entradas del usuario y restringe el número o el texto que desea.
Esta solución es para usuarios de Ionic-3 y Angular-4.
import { Directive, HostListener, Input } from ''@angular/core'';
import { Platform } from ''ionic-angular'';
/**
* Generated class for the AlphabateInputDirective directive.
*
* See https://angular.io/api/core/Directive for more info on Angular
* Directives.
*/
@Directive({
selector: ''[keyboard-input-handler]'' // Attribute selector
})
export class IonicKeyboardInputHandler {
@Input("type") inputType: string;
isNumeric: boolean = true;
str: string = "";
arr: any = [];
constructor(
public platForm: Platform
) {
console.log(''Hello IonicKeyboardInputHandler Directive'');
}
@HostListener(''keyup'', [''$event'']) onInputStart(e) {
this.str = e.target.value + '''';
this.arr = this.str.split('''');
this.isNumeric = this.inputType == "number" ? true : false;
if(e.target.value.split(''.'').length === 2){
return false;
}
if(this.isNumeric){
e.target.value = parseInt(this.arr.filter( c => isFinite(c)).join(''''));
}
else
e.target.value = this.arr.filter( c => !isFinite(c)).join('''');
return true;
}
}
Creo que un ControlValueAccessor personalizado es la mejor opción.
No probado, pero por lo que recuerdo, esto debería funcionar:
<input [(ngModel)]="value" pattern="[0-9]">
Después de mucha investigación, finalmente creé una función que llenaba el requisito. La función que creé restringe todos los caracteres especiales y solo permite alfabetos y números ... y esa función funciona bien tanto para copiar como para pegar y escribir ambos. Espero que funcione :)
public inputValidator(event: any) {
//console.log(event.target.value);
const pattern = /^[a-zA-Z0-9]*$/;
//let inputChar = String.fromCharCode(event.charCode)
if (!pattern.test(event.target.value)) {
event.target.value = event.target.value.replace(/[^a-zA-Z0-9]/g, "");
// invalid character, prevent input
}
}
<input type="text" [(ngModel)]="abc.abc" (input)="inputValidator($event)" />
¿Cómo se usa?
1) Agregue el método anterior en su componente de clase del archivo ts.
2) Método de llamada inputValidator ($ event) en el evento de entrada.
En HTML en el campo de entrada escriba: (pulsación de tecla) = "onlyNumberKey ($ event)"
y en el archivo ts escriba: onlyNumberKey (event) {return (event.charCode == 8 || event.charCode == 0)? null: event.charCode> = 48 && event.charCode <= 57; }
En component.ts añadir esta función.
_keyPress(event: any) {
const pattern = /[0-9/+/-/ ]/;
let inputChar = String.fromCharCode(event.charCode);
if (!pattern.test(inputChar)) {
// invalid character, prevent input
event.preventDefault();
}
}
En tu plantilla usa lo siguiente
<input(keypress)="_keyPress($event)">
Esto capturará la entrada antes de que angular2 capture el evento.
En html:
<input (keypress)="onlyNumber(event)"/>
En Componente:
onlyNumber(evt) {
evt = (evt) ? evt : window.event;
var charCode = (evt.which) ? evt.which : evt.keyCode;
if (charCode > 31 && (charCode < 48 || charCode > 57)) {
return false;
}
return true;
}
Puede utilizar la entrada HTML5 de número de tipo
No acepta ningún carácter en su declaración.
<input type="number" [(model)]=''myvar'' min=0 max=100 step=5 />
Aquí hay un ejemplo de su uso con angular 2 [(model)]
Respuesta probada por mí:
form.html
<input type="text" (keypress)="restrictNumeric($event)">
form.ponent.ts:
public restrictNumeric(e) {
let input;
if (e.metaKey || e.ctrlKey) {
return true;
}
if (e.which === 32) {
return false;
}
if (e.which === 0) {
return true;
}
if (e.which < 33) {
return true;
}
input = String.fromCharCode(e.which);
return !!/[/d/s]/.test(input);
}
Uno más
<form [formGroup]="myForm" novalidate>
<input type="text" class="form-control" id="data" name="data" formControlName="input3" #item (input)="change(item.value)">
</form>
{{myForm.value |json}}
change(value:string)
{
let lastchar = value.substr(value.length - 1);
if (!(new RegExp(''[0-9]'').test(lastchar)))
{
value=value.substr(0,value.length-1);
this.myForm.controls["input3"].setValue(value);
}
}
si usas desde una plantilla accionada
<input type="text" class="form-control" id="data" name="data" [(ngModel)]="data" #item (input)="change(item)">
{{data}}
change(item:any)
{
let value=item.value;
let lastchar = value.substr(value.length - 1);
if (!(new RegExp(''[0-9]'').test(lastchar)))
{
value=value.substr(0,value.length-1);
item.value=this.data=value;
}
}
El plugin inputmask hace el mejor trabajo de esto . Es extremadamente flexible, ya que puede suministrar cualquier expresión regular que desee para restringir la entrada. Tampoco requiere JQuery.
Paso 1: Instala el plugin:
npm install --save inputmask
Paso 2: crea una directiva para envolver la máscara de entrada:
import {Directive, ElementRef, Input} from ''@angular/core'';
import * as Inputmask from ''inputmask'';
@Directive({
selector: ''[app-restrict-input]'',
})
export class RestrictInputDirective {
// map of some of the regex strings I''m using (TODO: add your own)
private regexMap = {
integer: ''^[0-9]*$'',
float: ''^[+-]?([0-9]*[.])?[0-9]+$'',
words: ''([A-z]*//s)*'',
point25: ''^/-?[0-9]*(?://.25|//.50|//.75|)$''
};
constructor(private el: ElementRef) {}
@Input(''app-restrict-input'')
public set defineInputType(type: string) {
Inputmask({regex: this.regexMap[type], placeholder: ''''})
.mask(this.el.nativeElement);
}
}
Paso 3:
<input type="text" app-restrict-input="integer">
Echa un vistazo a sus documentos github para más información.
<input type="number" onkeypress="return event.charCode >= 48 && event.charCode <= 57" ondragstart="return false;" ondrop="return false;">
Los datos ingresados solo aceptan números, pero solo es una solución temporal.