将输入字段限制为两位小数 - Angular 5

Limit input field to two decimal places - Angular 5

代码如下

<input type="number" class="form-control" value="" name="cost_price" #name="ngModel" [(ngModel)]="item.cost_price" placeholder="Cost Price"  />

用户不能输入多于 2 位小数的内容。

例如,如果用户要输入 21.256。应该只允许他进入21.25

如何使用 angular 5 实现此目的?

我在用ng2-currency-mask,挺好用的。它会帮助你。

最简单的实现方式是绑定到 "keypress" 事件并使用正则表达式验证输入是否有效。

<input type="number" ... placeholder="Cost Price"  (keypress)="validateNumber($event)" />

然后 validateNumber 会是这样的:

validateNumber(e: any) {
    let input = String.fromCharCode(e.charCode);
    const reg = /^\d*(?:[.,]\d{1,2})?$/;

    if (!reg.test(input)) {
      e.preventDefault();
    }
}

首先创建指令来限制打字稿中的两位小数,如下所示:

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();
    }
  }
}

在您的 app.module.ts 中注入指令。 在你的 html 中使用这样的指令:

<input type="textbox" [(ngModel)]="InputValue" appTwoDigitDecimaNumber>

这是 Angular 4/5/6 中的工作示例:Limit Two decimal places number validation

希望对您有所帮助!!!

@Sanoj_V的回答可以改进:

1) 不能使用箭头键编辑号码,只能在末尾添加数字,或者必须单击要更改号码的位置。

2) 插入两位小数后,您只能使用退格键,因此要么删除最后一位小数,要么单击其他地方并删除数字,但您不能添加任何内容,因此您不能通过替换数字来更改数字。

要解决这个问题,只需更换:private specialKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home', '-'];

作者:private specialKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home', '-', 'ArrowLeft', 'ArrowRight'];

然后替换:let next: string = current.concat(event.key);

作者:const next: string = [current.slice(0, position), event.key, current.slice(position)].join('');

然后在上面添加这一行:const position = this.el.nativeElement.selectionStart;

感谢@Sanoj_V 这个指令,我花了一整天的时间试图弄清楚如何处理货币输入。

@Sanoj_v 和 user3803848 解决方案效果很好,但 IE 中还有一个错误。当用户使用数字键盘上的点符号时,会发出 'Decimal' 键事件和指令无法正常工作。

解决此问题:

    const next: string = [current.slice(0, position), event.key === 'Decimal' ? '.' : event.key, current.slice(position)].join('');

为了以防万一,我添加了“.”和 ',' 字符到正则表达式,检查用户输入。

低于整个指令

@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();
    }
  }
}

你应该记住,仍然有可能将一些错误的数据粘贴到输入中。这就是为什么,您可能需要再进行一次验证,也许是在 Input 事件上,以防止粘贴错误数据。

下面的代码是让文本框允许有两位小数的数字字段(超过两位小数会给出警告),而不使用正则表达式:

abc.component.html:

<div >
                                <input class="" type="text" [(ngModel)]="" value="" (keyup)="" [disabled]="" (keypress)="numberOnly($event)">
                                <span class="d-block ml-2">NumericBox(two decimal places)</span>
                            </div>

abc.component.ts:

public dotCount:number=0;

numberOnly(event): boolean {          
    const charCode = (event.which) ? event.which : event.keyCode;      
    if (charCode == 46) {
        this.dotCount += 1;
        this.checkNumberOnly = (event.target.value);
        var numericCheck = (event.target.value).toString();
        if (numericCheck.includes('.')) {
            this.dotCount += 1;
        }
        if (this.dotCount > 1) {   
            this.dotCount = 0;
            return false;
        }
    }
    if (charCode > 31 && (charCode < 45 || charCode > 57 || charCode==47)) {
        return false;
    }
    this.checkNumberOnly = (event.target.value);
    if (this.checkNumberOnly != null) {
        var numeric = (event.target.value).toString();
        if (numeric.includes('.')) {
            var checkNumeric = numeric.split('.');
            if (checkNumeric.length > 2) {
                return false;
            }
            this.checkString = checkNumeric[1].split('');
            if (this.checkString.length > 1) {
                this.toastrService.warning("Invalid value", "Warning");
                return false;
            }
        }

    }
    this.dotCount = 0;
    this.cdr.detectChanges();
    return true;

}

利用 pau 的回答, 这个解决方案可以正常工作:

在你的HTML中:

<input type="text" (keypress)="decimalFilter($event)" />

在您的代码中:

decimalFilter(event: any) {
   const reg = /^-?\d*(\.\d{0,2})?$/;
   let input = event.target.value + String.fromCharCode(event.charCode);

   if (!reg.test(input)) {
       event.preventDefault();
   }
}

主要区别在于您附加当前文本值 ...并允许 0-2 小数点后的小数值 (从 1-2) - 那么你需要转义 '.'否则它被视为 'any character'.

如果特别需要 2 位十进制数字,请使用 RegExp(/^\d*.?\d{0,1}$/g); 它从 0 索引开始直到 1 ,因此只允许 2 个十进制数字

解决方案 1:

我发现使用 type=number 最简单的方法是:

html

<input type="number" [(ngModel)]="price" (keypress)="currencyCheck($event)"></input>

ts

currencyCheck(event): boolean
  {
    let pattern = /^\d+\.?\d{0,2}$/;
    let result = pattern.test(event.key);
    if (this.price == null)
      return result;
    else
      return pattern.test(this.price.toString() + event.key);
  }

但如果用户在号码中间加数字,则不一定总是有效。

解决方案 2:

以下解决方案将始终有效,但如果输入不符合模式,它将在修复之前显示新输入一秒钟:

html

<input type="number" [(ngModel)]="price" (keyup)="currencyCheck()"></input>

ts

  currencyCheck(): boolean
  {
    let pattern = /^\d+\.?\d{0,2}$/;
    let result = pattern.test(this.price);
    if (!result) 
      this.price = this.old_price;
    else 
      this.old_price = this.price;
    return result;
  }