html - pattern - solo numeros angularjs
Angular2-Campo de entrada para aceptar solo nĂºmeros (12)
En Angular2, ¿cómo puedo enmascarar un campo de entrada (cuadro de texto) de modo que solo acepte números y no alfabetos?
Tengo la siguiente entrada de HTML:
<input type="text" *ngSwitchDefault class="form-control" (change)="onInputChange()" [(ngModel)]="config.Value" focus)="handleFocus($event)" (blur)="handleBlur($event)"/>
La entrada anterior es una entrada de texto genérica que puede usarse como un campo de texto simple o como un campo numérico (por ejemplo, para mostrar el año).
Usando angular2, ¿cómo puedo usar el mismo control de entrada y aplicar algún tipo de filtro / máscara en este campo, de modo que solo acepte números? ¿Cuáles son las diferentes formas en que puedo lograr esto?
Nota: Necesito lograr esto usando solo el cuadro de texto y no usando el tipo de número de entrada.
Necesita usar type = "number" en lugar de texto. También puede especificar números máximos y mínimos
<input type="number" name="quantity" min="1" max="5">
puedes lograrlo así
<input type="text" pInputText (keypress)="onlyNumberKey($event)" maxlength="3">
onlyNumberKey(event) {
return (event.charCode == 8 || event.charCode == 0) ? null : event.charCode >= 48 && event.charCode <= 57;
}
//for Decimal you can use this as
onlyDecimalNumberKey(event) {
let charCode = (event.which) ? event.which : event.keyCode;
if (charCode != 46 && charCode > 31
&& (charCode < 48 || charCode > 57))
return false;
return true;
}
Espero que esto te ayudará.
de la respuesta de @omeralper. Cambio un poco que no aceptará el período ascii (código clave 110,190). y use let ch = (e.key); para comparar con la expresión regular cuando cambia el idioma (como el tailandés o el japonés) no aceptará el carácter de ese idioma
export class OnlyNumber {
regexStr = ''^[0-9]*$'';
constructor(private el: ElementRef) { }
@Input() OnlyNumber: boolean;
@HostListener(''keydown'', [''$event'']) onKeyDown(event) {
let e = <KeyboardEvent> event;
if (this.OnlyNumber) {
// console.log(event, this.OnlyNumber);
if ([46, 8, 9, 27, 13].indexOf(e.keyCode) !== -1) {
return;
}
let ch = (e.key);
let regEx = new RegExp(this.regexStr);
if(regEx.test(ch))
return;
else
e.preventDefault();
}
}
}
espero que esto ayude :)
Me gustaría basarme en la respuesta dada por @omeralper, que en mi opinión proporcionó una buena base para una solución sólida.
Lo que propongo es una versión simplificada y actualizada con los últimos estándares web. Es importante tener en cuenta que event.keycode se elimina de los estándares web, y las futuras actualizaciones del navegador podrían no ser compatibles. Ver https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
Además, el método
String.fromCharCode(e.keyCode);
no garantiza que el código de clave perteneciente a la tecla presionada por el usuario se correlacione con la letra esperada tal como se identifica en el teclado del usuario, ya que las diferentes configuraciones de teclado darán como resultado un código clave diferente para cada carácter. El uso de esto introducirá errores que son difíciles de identificar y puede romper fácilmente la funcionalidad para ciertos usuarios. Más bien estoy proponiendo el uso de event.key, vea los documentos aquí https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key
Además, solo queremos que la salida resultante sea un decimal válido. Esto significa que deben aceptarse los números 1, 11.2, 5000.2341234, pero no se debe aceptar el valor 1.1.2.
Tenga en cuenta que en mi solución excluyo la funcionalidad de cortar, copiar y pegar, ya que abre ventanas para errores, especialmente cuando las personas pegan texto no deseado en los campos asociados. Eso requeriría un proceso de limpieza en un controlador de keyup; que no es el alcance de este hilo.
Aquí está la solución que estoy proponiendo.
import { Directive, ElementRef, HostListener } from ''@angular/core'';
@Directive({
selector: ''[myNumberOnly]''
})
export class NumberOnlyDirective {
// Allow decimal numbers. The /. is only allowed once to occur
private regex: RegExp = new RegExp(/^[0-9]+(/.[0-9]*){0,1}$/g);
// Allow key codes for special events. Reflect :
// Backspace, tab, end, home
private specialKeys: Array<string> = [ ''Backspace'', ''Tab'', ''End'', ''Home'' ];
constructor(private el: ElementRef) {
}
@HostListener(''keydown'', [ ''$event'' ])
onKeyDown(event: KeyboardEvent) {
// Allow Backspace, tab, end, and home keys
if (this.specialKeys.indexOf(event.key) !== -1) {
return;
}
// Do not use event.keycode this is deprecated.
// See: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
let current: string = this.el.nativeElement.value;
// We need this because the current value on the DOM element
// is not yet updated with the value from this event
let next: string = current.concat(event.key);
if (next && !String(next).match(this.regex)) {
event.preventDefault();
}
}
}
Puede crear este Validador e importarlo en su componente.
Básicamente valida la cadena de entrada del formulario:
- verificar que no haya punto
- convierte cadena en número
- el cheque es un número entero
- el control es mayor que cero
Para implementarlo en su proyecto:
- ruta sugerida en la carpeta de la aplicación: src / app / validators / number.validator.ts
importar en tu componente
import { NumberValidator } from ''../../validators/number.validator'';
- agréguelo al control de formulario
inputNumber: ['''', [NumberValidator.isInteger]],
- si no desea mostrar el carácter inválido, enlace un
(change)="deleteCharIfInvalid()"
a la entrada, siform.get(''inputNumber'').hasError(''isInteger'')
estrue
, elimine el último carácter insertado.
// FILE: src/app/validators/number.validator.ts
import { FormControl } from ''@angular/forms'';
export interface ValidationResult {
[key: string]: boolean;
}
export class NumberValidator {
public static isInteger(control: FormControl): ValidationResult {
// check if string has a dot
let hasDot:boolean = control.value.indexOf(''.'') >= 0 ? true : false;
// convert string to number
let number:number = Math.floor(control.value);
// get result of isInteger()
let integer:boolean = Number.isInteger(number);
// validate conditions
let valid:boolean = !hasDot && integer && number>0;
console.log(''isInteger > valid'', hasDot, number, valid);
if (!valid) {
return { isInteger: true };
}
return null;
}
}
Simplemente crea una directiva y agrega debajo hostlistener:
@HostListener(''input'', [''$event''])
onInput(event: Event) {
this.elementRef.nativeElement.value = (<HTMLInputElement>event.currentTarget).value.replace(/[^0-9]/g, '''');
}
Reemplace el texto inválido con el vacío. Todas las teclas y combinaciones de teclas ahora funcionarán en todos los navegadores hasta IE9.
fromCharCode devuelve ''a'' al presionar en el teclado numérico ''1'', por lo que debe evitarse este metodo
(admin: no pude comentar como de costumbre)
Puede usar directivas angulares2. Plunkr
import { Directive, ElementRef, HostListener, Input } from ''@angular/core'';
@Directive({
selector: ''[OnlyNumber]''
})
export class OnlyNumber {
constructor(private el: ElementRef) { }
@Input() OnlyNumber: boolean;
@HostListener(''keydown'', [''$event'']) onKeyDown(event) {
let e = <KeyboardEvent> event;
if (this.OnlyNumber) {
if ([46, 8, 9, 27, 13, 110, 190].indexOf(e.keyCode) !== -1 ||
// Allow: Ctrl+A
(e.keyCode === 65 && (e.ctrlKey || e.metaKey)) ||
// Allow: Ctrl+C
(e.keyCode === 67 && (e.ctrlKey || e.metaKey)) ||
// Allow: Ctrl+V
(e.keyCode === 86 && (e.ctrlKey || e.metaKey)) ||
// Allow: Ctrl+X
(e.keyCode === 88 && (e.ctrlKey || e.metaKey)) ||
// Allow: home, end, left, right
(e.keyCode >= 35 && e.keyCode <= 39)) {
// let it happen, don''t do anything
return;
}
// Ensure that it is a number and stop the keypress
if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
e.preventDefault();
}
}
}
}
y necesita escribir el nombre de la directiva en su entrada como un atributo
<input OnlyNumber="true" />
no olvides escribir tu directiva en el conjunto de declaraciones de tu módulo.
Al usar expresiones regulares, aún necesitaría teclas funcionales
export class OnlyNumber {
regexStr = ''^[0-9]*$'';
constructor(private el: ElementRef) { }
@Input() OnlyNumber: boolean;
@HostListener(''keydown'', [''$event'']) onKeyDown(event) {
let e = <KeyboardEvent> event;
if (this.OnlyNumber) {
if ([46, 8, 9, 27, 13, 110, 190].indexOf(e.keyCode) !== -1 ||
// Allow: Ctrl+A
(e.keyCode == 65 && e.ctrlKey === true) ||
// Allow: Ctrl+C
(e.keyCode == 67 && e.ctrlKey === true) ||
// Allow: Ctrl+V
(e.keyCode == 86 && e.ctrlKey === true) ||
// Allow: Ctrl+X
(e.keyCode == 88 && e.ctrlKey === true) ||
// Allow: home, end, left, right
(e.keyCode >= 35 && e.keyCode <= 39)) {
// let it happen, don''t do anything
return;
}
let ch = String.fromCharCode(e.keyCode);
let regEx = new RegExp(this.regexStr);
if(regEx.test(ch))
return;
else
e.preventDefault();
}
}
}
Para lograr esto, até una función al método onInput de esta manera:
(input)="stripText(infoForm.get(''uin''))
Aquí está el ejemplo dentro de mi formulario:
<form [formGroup]="infoForm" (submit)="next()" class="ui form">
<input type="text" formControlName="uin" name="uin" id="uin" (input)="stripText(infoForm.get(''uin''))" required/>
</form>
Luego agregué la siguiente función a mi componente:
stripText(control: FormControl) {
control.setValue(control.value.replace(/[^0-9]/g, ''''));
}
Este regex /[^0-9]/g
busca cualquier cosa que no sea un número y usando .replace
I set it para ser reemplazado por nothing. Por lo tanto, cuando un usuario intenta escribir un carácter que no es un número (en este caso, un carácter que no es cero hasta nueve), parece que no sucede nada en el cuadro de texto.
<input type="text" (keypress)="keyPress($event)">
keyPress(event: any) {
const pattern = /[0-9/+/-/ ]/;
let inputChar = String.fromCharCode(event.charCode);
if (event.keyCode != 8 && !pattern.test(inputChar)) {
event.preventDefault();
}
}
Utilice el atributo de pattern
para la entrada como a continuación:
<input type="text" pattern="[0-9]+" >
Con soporte para desinfectar contenido pegado:
import { Directive, ElementRef, HostListener, Input } from ''@angular/core'';
@Directive({
selector: ''[NumbersOnly]''
})
export class NumbersOnlyDirective {
DIGITS_REGEXP = new RegExp(//D/g);
constructor(private el: ElementRef) {
// Sanatize clipboard by removing any non-numeric input after pasting
this.el.nativeElement.onpaste = (e:any) => {
e.preventDefault();
let text;
let clp = (e.originalEvent || e).clipboardData;
if (clp === undefined || clp === null) {
text = (<any>window).clipboardData.getData(''text'') || '''';
if (text !== '''') {
text = text.replace(this.DIGITS_REGEXP, '''');
if (window.getSelection) {
let newNode = document.createElement(''span'');
newNode.innerHTML = text;
window.getSelection().getRangeAt(0).insertNode(newNode);
} else {
(<any>window).selection.createRange().pasteHTML(text);
}
}
} else {
text = clp.getData(''text/plain'') || '''';
if (text !== '''') {
text = text.replace(this.DIGITS_REGEXP, '''');
document.execCommand(''insertText'', false, text);
}
}
};
}
@HostListener(''keydown'', [''$event'']) onKeyDown(event) {
let e = <KeyboardEvent> event;
if ([46, 8, 9, 27, 13, 110, 190].indexOf(e.keyCode) !== -1 ||
// Allow: Ctrl+A
(e.keyCode === 65 && (e.ctrlKey || e.metaKey)) ||
// Allow: Ctrl+C
(e.keyCode === 67 && (e.ctrlKey || e.metaKey)) ||
// Allow: Ctrl+V
(e.keyCode === 86 && (e.ctrlKey || e.metaKey)) ||
// Allow: Ctrl+X
(e.keyCode === 88 && (e.ctrlKey || e.metaKey)) ||
// Allow: home, end, left, right
(e.keyCode >= 35 && e.keyCode <= 39)) {
// let it happen, don''t do anything
return;
}
// Ensure that it is a number and stop the keypress
if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
e.preventDefault();
}
}
}