How to enter only a number like this XX.XXX,XX (cu

2019-09-20 04:16发布

问题:

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 >

回答1:

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



回答2:

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")


标签: regex angular