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

时间:2018-06-06 14:01:06

标签: angular angular-forms

代码如下

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

用户不应该输入更多2位小数。

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

如何使用角度5实现此目的?

8 个答案:

答案 0 :(得分:12)

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

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', '-'];
  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;
    let next: string = current.concat(event.key);
    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

希望这会对你有所帮助!!!!

答案 1 :(得分:2)

@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的这一指令,我花了一整天的时间试图弄清楚如何处理货币输入。

答案 2 :(得分:1)

实现这一目标的最简单方法是绑定&#34;按键&#34;事件并使用正则表达式验证是否有效输入。

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

答案 3 :(得分:1)

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

解决此问题:

    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事件上进行验证,以防止粘贴错误的数据。

答案 4 :(得分:0)

也许您还应该查看Angular guide中的表单验证。根据您的表单类型,它可能很有用。

答案 5 :(得分:0)

我正在使用ng2-currency-mask,这非常有用。它会帮助你。

答案 6 :(得分:0)

下面的编码是使文本框允许数字字段具有两个小数位(两个小数位以上将给出警告),而无需使用正则表达式:

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;

}

答案 7 :(得分:0)

利用 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) - 然后您需要逃避'.'否则将被视为“任何字符”。