typescript - Limitar el campo de entrada a dos decimales - Angular 5
El código es el siguiente
<input type="number" class="form-control" value="" name="cost_price" #name="ngModel" [(ngModel)]="item.cost_price" placeholder="Cost Price" />
El usuario no debería poder escribir más de 2 decimales.
Por ejemplo, si el usuario quiere ingresar 21.256, sólo se le debería permitir ingresar 21.25
¿Cómo lograr esto usando Angular 5?
Respuesta #1
Primero crea una Directiva para limitar a dos decimales en TypeScript así:
import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[appTwoDigitDecimaNumber]'
})
export class TwoDigitDecimaNumberDirective {
private regex: RegExp = new RegExp(/^\d*\.?\d{0,2}$/g);
private specialKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home', '-', 'ArrowLeft', 'ArrowRight', 'Del', 'Delete'];
constructor(private el: ElementRef) {
}
@HostListener('keydown', ['$event'])
onKeyDown(event: KeyboardEvent) {
console.log(this.el.nativeElement.value);
// Allow Backspace, tab, end, and home keys
if (this.specialKeys.indexOf(event.key) !== -1) {
return;
}
let current: string = this.el.nativeElement.value;
const position = this.el.nativeElement.selectionStart;
const next: string = [current.slice(0, position), event.key == 'Decimal' ? '.' : event.key, current.slice(position)].join('');
if (next && !String(next).match(this.regex)) {
event.preventDefault();
}
}
}
Inyecta la directiva en tu app.module.ts. En tu HTML usa esa directiva así:
<input type="textbox" [(ngModel)]="InputValue" appTwoDigitDecimaNumber>
Aquí hay un ejemplo funcional en Angular 4/5/6: Validación de número con dos decimales como máximo
¡Espero que esto te ayude!!!!
Respuesta #2
@Sanoj_v y la solución de user3803848 funciona muy bien, pero hay un error más en IE. Cuando el usuario utiliza el signo de punto del teclado numérico, se emite un evento de tecla 'Decimal' y la directiva no funciona correctamente.
Solución para esto:
const next: string = [current.slice(0, position), event.key === 'Decimal' ? '.' : event.key, current.slice(position)].join('');
Por si acaso, agregué los caracteres '.' y ',' a la expresión regular que verifica la entrada del usuario.
Debajo de toda la directiva
@Directive({
selector: '[appTwoDigitDecimalNumber]',
})
export class TwoDigitDecimaNumberDirective {
private regex: RegExp = new RegExp(/^\d+[.,]?\d{0,2}$/g);// user can put . or , char.
// input also cannot start from , or .
private specialKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home', '-', 'ArrowLeft', 'ArrowRight', 'Del', 'Delete'];
constructor(private el: ElementRef) {
}
@HostListener('keydown', ['$event'])
onKeyDown(event: KeyboardEvent) {
if (this.specialKeys.includes(event.key)) {
return;
}
const current: string = this.el.nativeElement.value;
const position = this.el.nativeElement.selectionStart;
const next: string = [current.slice(0, position), event.key == 'Decimal' ? '.' : event.key, current.slice(position)].join('');
if (next && !String(next).match(this.regex)) {
event.preventDefault();
}
}
}
Debes recordar que todavía es posible pegar algunos datos incorrectos en la entrada. Por eso, probablemente necesites una validación más, tal vez en el evento de entrada para evitar pegar datos incorrectos.
