How can I type only a number in this format xx.xxx,xx
(currency). If I type letters, characters and other special characters i would like to be stopped. I attached the code. I would appreciate any help. Thanks!
import { Directive, HostListener, ElementRef, Input } from '@angular/core';
@Directive({
selector: '[currencyNumeric]'
})
export class CurrencyDirective {
regexStr = 'reg exp for xx.xxx,xx';
@Input() currencyNumeric: boolean;
constructor(private el: ElementRef) { }
@HostListener('keypress', ['$event']) onKeyPress(event) {
return new RegExp(this.regexStr).test(event.key);
}
@HostListener('paste', ['$event']) blockPaste(event: KeyboardEvent) {
this.validateFields(event);
}
validateFields(event) {
setTimeout(() => {
this.el.nativeElement.value = this.el.nativeElement.value.replace(/currency reg exp for XX.XXX,XX/g, '').replace(/\s/g, '');
event.preventDefault();
}, 100)
}
}
<input type="text" currencyNumeric >
You can use this code
add this directive
import { Directive, HostListener, ElementRef, OnInit } from '@angular/core';
import {MycurrencyPipe} from './mycurrency.pipe';
@Directive({
selector: '[appMycurrency]',
providers:[MycurrencyPipe]
})
export class MycurrencyDirective implements OnInit{
private el: any;
constructor(
private elementRef:ElementRef,
private formatcurrencypipe:MycurrencyPipe
) {
this.el = this.elementRef.nativeElement;
}
ngOnInit(){
this.el.value = this.formatcurrencypipe.transform(this.el.value);
}
@HostListener("focus",["$event.target.value","$event"])
onFocus(value,event) {
this.el.value = this.formatcurrencypipe.parse(value); // opossite of transform
if(event.which== 9)
{
return false;
}
this.el.select();
}
@HostListener("blur", ["$event.target.value"])
onBlur(value) {
this.el.value = this.formatcurrencypipe.transform(value);
}
@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();
}
}
}
the directive needs this Pipe
import { Pipe, PipeTransform } from '@angular/core';
const padding = "000000";
@Pipe({
name: 'mycurrency'
})
export class MycurrencyPipe implements PipeTransform {
private prefix: string;
private decimal_separator:string;
private thousands_separator:string;
private suffix:string;
constructor(){
this.prefix='$ ';
this.suffix='';
this.decimal_separator='.';
this.thousands_separator = ',';
}
transform(value: string, fractionSize:number = 0 ): string {
if(parseFloat(value) % 1 != 0)
{
fractionSize = 2;
}
let [ integer, fraction = ""] = (parseFloat(value).toString() || "").toString().split(".");
fraction = fractionSize > 0
? this.decimal_separator + (fraction+padding).substring(0, fractionSize) : "";
integer = integer.replace(/\B(?=(\d{3})+(?!\d))/g, this.thousands_separator);
if(isNaN(parseFloat(integer)))
{
integer = "0";
}
return this.prefix + integer + fraction + this.suffix;
}
parse(value: string, fractionSize: number = 2): string {
let [ integer, fraction = "" ] = (value || "").replace(this.prefix, "")
.replace(this.suffix, "")
.split(this.decimal_separator);
integer = integer.replace(new RegExp(this.thousands_separator, "g"), "");
fraction = parseInt(fraction, 10) > 0 && fractionSize > 0
? this.decimal_separator + (fraction + padding).substring(0, fractionSize)
: "";
return integer + fraction;
}
}
and you can use it like <input appMycurrency type="text" />
don't forget to add MycurrencyPipe, MycurrencyDirective in declarations on NgModule
full app is here here
Use capturing groups (by index) in Regular Expressions. like this:
this.el.nativeElement.value = this.el.nativeElement.value.replace(/(\d{2})(\d{3})(\d{2})/, "$1.$2,$3")