将输入字段限制为两位小数 - 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;
}
代码如下
<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;
}