在Angular2中,如何屏蔽输入字段(文本框),使其仅接受数字而不接受字母?
我有以下HTML输入:
<input type="text" *ngSwitchDefault class="form-control" (change)="onInputChange()" [(ngModel)]="config.Value" focus)="handleFocus($event)" (blur)="handleBlur($event)"/>
以上输入是通用文本输入,可以用作简单文本字段或数字字段(例如显示年份)。
使用angular2,我如何使用相同的输入控件并在此字段上应用某种过滤器/蒙版,这样它只接受数字? 我可以通过哪些不同方式实现这一目标?
注意:我需要仅使用文本框而不使用输入数字类型来实现此目的。
答案 0 :(得分:84)
您可以使用angular2指令。 Plunkr
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[OnlyNumber]'
})
export class OnlyNumber {
constructor(private el: ElementRef) { }
@Input() OnlyNumber: boolean;
@HostListener('keydown', ['$event']) onKeyDown(event) {
let e = <KeyboardEvent> event;
if (this.OnlyNumber) {
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();
}
}
}
}
您需要在输入中将指令名称作为属性
编写<input OnlyNumber="true" />
不要忘记在模块的声明数组中编写指令。
通过使用正则表达式,您仍然需要功能键
export class OnlyNumber {
regexStr = '^[0-9]*$';
constructor(private el: ElementRef) { }
@Input() OnlyNumber: boolean;
@HostListener('keydown', ['$event']) onKeyDown(event) {
let e = <KeyboardEvent> event;
if (this.OnlyNumber) {
if ([46, 8, 9, 27, 13, 110, 190].indexOf(e.keyCode) !== -1 ||
// Allow: Ctrl+A
(e.keyCode == 65 && e.ctrlKey === true) ||
// Allow: Ctrl+C
(e.keyCode == 67 && e.ctrlKey === true) ||
// Allow: Ctrl+V
(e.keyCode == 86 && e.ctrlKey === true) ||
// Allow: Ctrl+X
(e.keyCode == 88 && e.ctrlKey === true) ||
// Allow: home, end, left, right
(e.keyCode >= 35 && e.keyCode <= 39)) {
// let it happen, don't do anything
return;
}
let ch = String.fromCharCode(e.keyCode);
let regEx = new RegExp(this.regexStr);
if(regEx.test(ch))
return;
else
e.preventDefault();
}
}
}
答案 1 :(得分:39)
如果您不想要指令
https://stackblitz.com/edit/numeric-only
component.html中的
<input (keypress)="numberOnly($event)" type="text">
component.ts中的
export class AppComponent {
numberOnly(event): boolean {
const charCode = (event.which) ? event.which : event.keyCode;
if (charCode > 31 && (charCode < 48 || charCode > 57)) {
return false;
}
return true;
}
}
答案 2 :(得分:26)
我想建立@omeralper给出的答案,我认为这为一个可靠的解决方案提供了良好的基础。
我建议的是一个简化的最新版本,其中包含最新的网络标准。请务必注意,event.keycode已从Web标准中删除,未来的浏览器更新可能不再支持它。见https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
此外,方法
String.fromCharCode(e.keyCode);
不保证与用户按下的键有关的keyCode映射到用户键盘上标识的预期字母,因为不同的键盘配置将导致特定键码不同的字符。使用它会引入难以识别的错误,并且很容易破坏某些用户的功能。相反,我建议使用event.key,请参阅此处的文档https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key
此外,我们只希望结果输出是有效的小数。这意味着应接受数字1,11.2,5000.2341234,但不应接受值1.1.2。
请注意,在我的解决方案中,我不包括剪切,复制和粘贴功能,因为它会打开窗口中的错误,尤其是当人们在相关字段中粘贴不需要的文本时。这需要在keyup处理程序上进行清理过程;这不是该线程的范围。
这是我提出的解决方案。
import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[myNumberOnly]'
})
export class NumberOnlyDirective {
// Allow decimal numbers. The \. is only allowed once to occur
private regex: RegExp = new RegExp(/^[0-9]+(\.[0-9]*){0,1}$/g);
// Allow key codes for special events. Reflect :
// Backspace, tab, end, home
private specialKeys: Array<string> = [ 'Backspace', 'Tab', 'End', 'Home' ];
constructor(private el: ElementRef) {
}
@HostListener('keydown', [ '$event' ])
onKeyDown(event: KeyboardEvent) {
// Allow Backspace, tab, end, and home keys
if (this.specialKeys.indexOf(event.key) !== -1) {
return;
}
// Do not use event.keycode this is deprecated.
// See: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
let current: string = this.el.nativeElement.value;
// We need this because the current value on the DOM element
// is not yet updated with the value from this event
let next: string = current.concat(event.key);
if (next && !String(next).match(this.regex)) {
event.preventDefault();
}
}
}
答案 3 :(得分:16)
我知道这是一个古老的问题,但是由于这是常见的功能,因此我想分享我所做的修改:
替换字符串,例如“ .33”和“ 33”。正确的版本:0.33和33.0
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({ selector: '[NumbersOnly]' })
export class NumbersOnly {
@Input() allowDecimals: boolean = true;
@Input() allowSign: boolean = false;
@Input() decimalSeparator: string = '.';
previousValue: string = '';
// --------------------------------------
// Regular expressions
integerUnsigned: string = '^[0-9]*$';
integerSigned: string = '^-?[0-9]+$';
decimalUnsigned: string = '^[0-9]+(.[0-9]+)?$';
decimalSigned: string = '^-?[0-9]+(.[0-9]+)?$';
/**
* Class constructor
* @param hostElement
*/
constructor(private hostElement: ElementRef) { }
/**
* Event handler for host's change event
* @param e
*/
@HostListener('change', ['$event']) onChange(e) {
this.validateValue(this.hostElement.nativeElement.value);
}
/**
* Event handler for host's paste event
* @param e
*/
@HostListener('paste', ['$event']) onPaste(e) {
// get and validate data from clipboard
let value = e.clipboardData.getData('text/plain');
this.validateValue(value);
e.preventDefault();
}
/**
* Event handler for host's keydown event
* @param event
*/
@HostListener('keydown', ['$event']) onKeyDown(e: KeyboardEvent) {
let cursorPosition: number = e.target['selectionStart'];
let originalValue: string = e.target['value'];
let key: string = this.getName(e);
let controlOrCommand = (e.ctrlKey === true || e.metaKey === true);
let signExists = originalValue.includes('-');
let separatorExists = originalValue.includes(this.decimalSeparator);
// allowed keys apart from numeric characters
let allowedKeys = [
'Backspace', 'ArrowLeft', 'ArrowRight', 'Escape', 'Tab'
];
// when decimals are allowed, add
// decimal separator to allowed codes when
// its position is not close to the the sign (-. and .-)
let separatorIsCloseToSign = (signExists && cursorPosition <= 1);
if (this.allowDecimals && !separatorIsCloseToSign && !separatorExists) {
if (this.decimalSeparator == '.')
allowedKeys.push('.');
else
allowedKeys.push(',');
}
// when minus sign is allowed, add its
// key to allowed key only when the
// cursor is in the first position, and
// first character is different from
// decimal separator
let firstCharacterIsSeparator = (originalValue.charAt(0) != this.decimalSeparator);
if (this.allowSign && !signExists &&
firstCharacterIsSeparator && cursorPosition == 0) {
allowedKeys.push('-');
}
// allow some non-numeric characters
if (allowedKeys.indexOf(key) != -1 ||
// Allow: Ctrl+A and Command+A
(key == 'a' && controlOrCommand) ||
// Allow: Ctrl+C and Command+C
(key == 'c' && controlOrCommand) ||
// Allow: Ctrl+V and Command+V
(key == 'v' && controlOrCommand) ||
// Allow: Ctrl+X and Command+X
(key == 'x' && controlOrCommand)) {
// let it happen, don't do anything
return;
}
// save value before keydown event
this.previousValue = originalValue;
// allow number characters only
let isNumber = (new RegExp(this.integerUnsigned)).test(key);
if (isNumber) return; else e.preventDefault();
}
/**
* Test whether value is a valid number or not
* @param value
*/
validateValue(value: string): void {
// choose the appropiate regular expression
let regex: string;
if (!this.allowDecimals && !this.allowSign) regex = this.integerUnsigned;
if (!this.allowDecimals && this.allowSign) regex = this.integerSigned;
if (this.allowDecimals && !this.allowSign) regex = this.decimalUnsigned;
if (this.allowDecimals && this.allowSign) regex = this.decimalSigned;
// when a numbers begins with a decimal separator,
// fix it adding a zero in the beginning
let firstCharacter = value.charAt(0);
if (firstCharacter == this.decimalSeparator)
value = 0 + value;
// when a numbers ends with a decimal separator,
// fix it adding a zero in the end
let lastCharacter = value.charAt(value.length-1);
if (lastCharacter == this.decimalSeparator)
value = value + 0;
// test number with regular expression, when
// number is invalid, replace it with a zero
let valid: boolean = (new RegExp(regex)).test(value);
this.hostElement.nativeElement['value'] = valid ? value : 0;
}
/**
* Get key's name
* @param e
*/
getName(e): string {
if (e.key) {
return e.key;
} else {
// for old browsers
if (e.keyCode && String.fromCharCode) {
switch (e.keyCode) {
case 8: return 'Backspace';
case 9: return 'Tab';
case 27: return 'Escape';
case 37: return 'ArrowLeft';
case 39: return 'ArrowRight';
case 188: return ',';
case 190: return '.';
case 109: return '-'; // minus in numbpad
case 173: return '-'; // minus in alphabet keyboard in firefox
case 189: return '-'; // minus in alphabet keyboard in chrome
default: return String.fromCharCode(e.keyCode);
}
}
}
}
用法:
<input NumbersOnly
[allowDecimals]="true"
[allowSign]="true"
type="text">
答案 4 :(得分:12)
<input type="text" (keypress)="keyPress($event)">
keyPress(event: any) {
const pattern = /[0-9\+\-\ ]/;
let inputChar = String.fromCharCode(event.charCode);
if (event.keyCode != 8 && !pattern.test(inputChar)) {
event.preventDefault();
}
}
答案 5 :(得分:9)
你需要使用type =&#34; number&#34;而是文字。您还可以指定最大和最小数字
<input type="number" name="quantity" min="1" max="5">
答案 6 :(得分:8)
你可以像这样实现它
<input type="text" pInputText (keypress)="onlyNumberKey($event)" maxlength="3">
onlyNumberKey(event) {
return (event.charCode == 8 || event.charCode == 0) ? null : event.charCode >= 48 && event.charCode <= 57;
}
//for Decimal you can use this as
onlyDecimalNumberKey(event) {
let charCode = (event.which) ? event.which : event.keyCode;
if (charCode != 46 && charCode > 31
&& (charCode < 48 || charCode > 57))
return false;
return true;
}
希望这会对你有所帮助。
答案 7 :(得分:6)
更简洁的解决方案。试试这个指令。
如果你正在使用ReactiveForms,也可以使用。
export class NumberOnlyDirective {
private el: NgControl;
constructor(private ngControl: NgControl) {
this.el = ngControl;
}
// Listen for the input event to also handle copy and paste.
@HostListener('input', ['$event.target.value'])
onInput(value: string) {
// Use NgControl patchValue to prevent the issue on validation
this.el.control.patchValue(value.replace(/[^0-9]/g, ''));
}
}
在输入上使用它如下:
<input matInput formControlName="aNumberField" numberOnly>
答案 8 :(得分:5)
使用pattern
属性进行输入,如下所示:
<input type="text" pattern="[0-9]+" >
答案 9 :(得分:4)
为了实现这一点,我将一个函数绑定到onInput方法,如下所示:
(input)="stripText(infoForm.get('uin'))
以下是我的表单中的示例:
<form [formGroup]="infoForm" (submit)="next()" class="ui form">
<input type="text" formControlName="uin" name="uin" id="uin" (input)="stripText(infoForm.get('uin'))" required/>
</form>
然后我将以下函数添加到我的组件中:
stripText(control: FormControl) {
control.setValue(control.value.replace(/[^0-9]/g, ''));
}
此正则表达式/[^0-9]/g
搜索任何非数字的内容并使用.replace
我将其设置为无任何替换。因此,当用户尝试输入不是数字的字符(在这种情况下,字符不是0到9)时,文本框中似乎没有任何反应。
答案 10 :(得分:4)
这里很小的directive使用任意正则表达式并阻止用户键入无效值
import {Directive, HostListener, Input} from '@angular/core';
@Directive({selector: '[allowedRegExp]'})
export class AllowedRegExpDirective {
@Input() allowedRegExp: string;
@HostListener('keydown', ['$event']) onKeyDown(event: any) {
// case: selected text (by mouse) - replace it
let s= event.target.selectionStart;
let e= event.target.selectionEnd;
let k= event.target.value + event.key;
if(s!=e) {
k= event.target.value
k= k.slice(0,s) + event.key + k.slice(e,k.length);
}
// case: special characters (ignore)
if(['ArrowLeft','ArrowRight','ArrowUp','ArroDown','Backspace','Tab','Alt'
'Shift','Control','Enter','Delete','Meta'].includes(event.key)) return;
// case: normal situation - chceck regexp
let re = new RegExp(this.allowedRegExp);
if(!re.test(k)) event.preventDefault();
}
}
要仅屏蔽数字,请使用
<input [allowedRegExp]="'^[0-9]*$'" type="text" ... >
答案 11 :(得分:3)
您可以使用掩码轻松完成此操作:
<input type='text' mask="99" formControlName="percentage" placeholder="0">
99 - 可选的 2 位数字
不要忘记在你的模块中导入 NgxMaskModule:
imports: [
NgxMaskModule.forRoot(),
]
答案 12 :(得分:3)
<input oninput="this.value=this.value.replace(/[^0-9]/g,'')"
或: 2.在HTML文件中:
<input [(ngModel)]="data" (keypress)="stripText($event)"
class="form-control">
ts文件中的:
stripText(event) {
const seperator = '^([0-9])';
const maskSeperator = new RegExp(seperator , 'g');
let result =maskSeperator.test(event.key); return result; }
这2种解决方案有效
答案 13 :(得分:2)
铸造,因为它也可以工作 前导0,如00345
@Directive({
selector: '[appOnlyDigits]'
})
export class AppOnlyDigitsDirective {
@HostListener('input', ['$event'])
onKeyDown(ev: KeyboardEvent) {
const input = ev.target as HTMLInputElement;
input.value = String(input.value.replace(/\D+/g, ''));
}
}
答案 14 :(得分:2)
获得最佳答案的现代方法(不推荐使用e.keyCode):
library(dplyr)
library(data.table)
df %>%
group_by(sample) %>%
filter( !(any(diff(measurement) < 0)| any(tabulate(rleid(measurement)) >=3)))
# A tibble: 5 x 2
# Groups: sample [1]
# sample measurement
# <chr> <dbl>
#1 b 0.155
#2 b 0.278
#3 b 0.388
#4 b 1.22
#5 b 1.81
答案 15 :(得分:2)
我在上面的指令中进行了一些修改并实现了min,max,maxlength。
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[numberOnly]'
})
export class NumbersOnlyDirective {
private regex: RegExp = new RegExp(/[0-9]/g);
// Allow key codes for special events. Reflect :
private specialKeys: Array<number> = [46, 8, 9, 27, 13, 110, 190, 35, 36, 37, 39];
// Backspace, tab, end, home
@Input() maxlength: number;
@Input() min: number;
@Input() max: number;
constructor(private el: ElementRef) {
}
@HostListener('keydown', ['$event'])
onKeyDown(event: KeyboardEvent) {
e = <KeyboardEvent>event;
if ((
(this.specialKeys.indexOf(event.which) > -1) ||
// to allow backspace, enter, escape, arrows
(e.which == 65 && e.ctrlKey == true) ||
// Allow: Ctrl+C
(e.which == 67 && e.ctrlKey == true) ||
// Allow: Ctrl+X
(e.which == 88 && e.ctrlKey == true))) {
return;
} else if (// to allow numbers
(e.which >= 48 && e.which <= 57) ||
// to allow numpad number
(event.which >= 96 && event.which <= 105)) { }
else {
event.preventDefault();
}
let current: string = this.el.nativeElement.value;
let next: string = current.concat(event.key);
if ((next && !String(next).match(this.regex)) ||
(this.maxlength && next.length > this.maxlength) ||
(this.min && +next < this.min) ||
(this.max && +next >= this.max)) {
event.preventDefault();
}
}
}
答案 16 :(得分:2)
有效手机号码的模式 图案( '^((\ + 91 - )|?0)[0-9] {10} $')
从文本框中仅接受号码的模式 图案( '[0-9] *')
用于仅接受具有特定数字的数字的模式,例如:Pincode。 模式('^ [0-9] {5} $')
答案 17 :(得分:2)
只需创建一个指令并添加到hostlistener下面:
@HostListener('input', ['$event'])
onInput(event: Event) {
this.elementRef.nativeElement.value = (<HTMLInputElement>event.currentTarget).value.replace(/[^0-9]/g, '');
}
将无效文字替换为空。所有按键和按键组合现在可以在所有浏览器中使用,直到IE9。
答案 18 :(得分:1)
非常感谢JeanPaul A.和rdanielmurphy。我已经制定了自己的Custom指令,用于将输入字段限制为仅数字。还添加了最大和最小输入属性。也会在角度7中工作。
角度
import { Directive, ElementRef, Input, HostListener } from '@angular/core';
@Directive({
selector: '[appNumberOnly]'
})
export class NumberOnlyDirective {
// Allow decimal numbers. The \. is only allowed once to occur
private regex: RegExp = new RegExp(/^[0-9]+(\.[0-9]*){0,1}$/g);
// Allow key codes for special events. Reflect :
// Backspace, tab, end, home
private specialKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home'];
constructor(private el: ElementRef) { }
@Input() maxlength: number;
@Input() min: number;
@Input() max: number;
@HostListener('keydown', ['$event'])
onKeyDown(event: KeyboardEvent) {
// Allow Backspace, tab, end, and home keys
if (this.specialKeys.indexOf(event.key) !== -1) {
return;
}
// Do not use event.keycode this is deprecated.
// See: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
const current: string = this.el.nativeElement.value;
// We need this because the current value on the DOM element
// is not yet updated with the value from this event
const next: string = current.concat(event.key);
if (next && !String(next).match(this.regex) || (this.maxlength && next.length > this.maxlength) ||
(this.min && +next < this.min) ||
(this.max && +next >= this.max)) {
event.preventDefault();
}
}
@HostListener('paste', ['$event']) onPaste(event) {
// Don't allow pasted text that contains non-numerics
const pastedText = (event.originalEvent || event).clipboardData.getData('text/plain');
if (pastedText) {
const regEx = new RegExp('^[0-9]*$');
if (!regEx.test(pastedText) || (this.maxlength && pastedText.length > this.maxlength) ||
(this.min && +pastedText < this.min) ||
(this.max && +pastedText >= this.max)) {
event.preventDefault();
}
}
}
}
HTML
<input type="text" class="text-area" [(ngModel)]="itemName" maxlength="3" appNumberOnly />
答案 19 :(得分:1)
您可以创建此验证器并将其导入组件中 基本上验证表单输入字符串:
在项目中实施它:
导入您的组件
import { NumberValidator } from '../../validators/number.validator';
inputNumber: ['', [NumberValidator.isInteger]],
(change)="deleteCharIfInvalid()"
绑定到输入,如果form.get('inputNumber').hasError('isInteger')
为true
,则删除最后插入的字符。// FILE: src/app/validators/number.validator.ts
import { FormControl } from '@angular/forms';
export interface ValidationResult {
[key: string]: boolean;
}
export class NumberValidator {
public static isInteger(control: FormControl): ValidationResult {
// check if string has a dot
let hasDot:boolean = control.value.indexOf('.') >= 0 ? true : false;
// convert string to number
let number:number = Math.floor(control.value);
// get result of isInteger()
let integer:boolean = Number.isInteger(number);
// validate conditions
let valid:boolean = !hasDot && integer && number>0;
console.log('isInteger > valid', hasDot, number, valid);
if (!valid) {
return { isInteger: true };
}
return null;
}
}
答案 20 :(得分:1)
下面是我的角度代码,该代码只允许输入数字,并且只能粘贴数字,而不是文本。
<input id="pId" maxlength="8" minlength="8" type="text" [(ngModel)]="no" formControlName="prefmeno" name="no" class="form-control">
在ngOnIt中添加的ts文件中。
ngOnInit() {
setTimeout(() => {
jQuery('#pId').on('paste keyup', function(e){
jQuery(this).val(document.getElementById('pId').value.replace(/[^\d]/g, ''));
});
}, 2000);
}
我使用setTimeout来等待加载DOM的时间。并使用带有JavaScript的jquery来执行此任务。 “粘贴”和“键”用于触发粘贴并在字段中输入。
答案 21 :(得分:1)
来自@omeralper的回答。 我改变了一点不接受句号ascii(键代码110,190)。 并使用let ch =(e.key);要在更改语言(例如泰语或日语)时与正则表达式进行比较,它将不接受这些语言的字符
export class OnlyNumber {
regexStr = '^[0-9]*$';
constructor(private el: ElementRef) { }
@Input() OnlyNumber: boolean;
@HostListener('keydown', ['$event']) onKeyDown(event) {
let e = <KeyboardEvent> event;
if (this.OnlyNumber) {
// console.log(event, this.OnlyNumber);
if ([46, 8, 9, 27, 13].indexOf(e.keyCode) !== -1) {
return;
}
let ch = (e.key);
let regEx = new RegExp(this.regexStr);
if(regEx.test(ch))
return;
else
e.preventDefault();
}
}
}
希望这有帮助:)
答案 22 :(得分:1)
这很简单:简单指令
在keydown事件中,它检查密钥的长度是1,密钥不是preventDefault()
的数字,它不会呈现该字符。
import {Directive, ElementRef, HostListener} from '@angular/core';
@Directive({
selector: '[numbersOnly]'
})
export class NumbersOnlyDirective {
@HostListener('keydown', ['$event'])
keyDownEvent(event: KeyboardEvent) {
if (event.key.length === 1 && (event.which < 48 || event.which > 57)) {
event.preventDefault();
}
}
}
HTML:
<input type="text" [(ngModel)]="numModel" numbersOnly />
限制:它允许使用鼠标粘贴,这种方式将接受其他字符。为避免这种情况,您可以将模型作为输入传递给指令,并将ngOnChage
传递给该模型,将值更改为仅数字:
如下所示:
编辑:添加代码以检测模型中的更改并更新输入值
import {Directive, ElementRef, HostListener, Input, OnChanges} from '@angular/core';
@Directive({
selector: '[numbersOnly]'
})
export class NumbersOnlyDirective implements OnChanges {
@Input() numbersOnly: any;
constructor(private el: ElementRef) {}
@HostListener('keydown', ['$event'])
keyDownEvent(event: KeyboardEvent) {
// Add other conditions if need to allow ctr+c || ctr+v
if (event.key.length === 1 && (event.which < 48 || event.which > 57)) {
event.preventDefault();
}
}
ngOnChanges(changes) {
if (changes.numbersOnly) {
this.el.nativeElement.value = this.el.nativeElement.value.replace(/[^0-9]/g, '');
}
}
}
HTML:
<input type="text" [(ngModel)]="numModel" [numbersOnly]="numModel" />
答案 23 :(得分:1)
您可以使用正则表达式:
<input type="text" (keypress)="numericOnly($event)">
numericOnly(event): boolean {
let patt = /^([0-9])$/;
let result = patt.test(event.key);
return result;
}
答案 24 :(得分:0)
我知道这有很多答案,但是我需要处理以下问题(所有答案似乎都没有完全支持):
该解决方案允许我这样定义文本区域:
<textarea class="form-control" [(ngModel)]="this.myModelVariable"
appOnlyNumbers [allowNegative]="true" [allowMultiLine]="true"
[allowDecimal]="true" [maxLength]="10"
placeholder="Enter values (one per line)"></textarea>
或者如果我只想要正整数
<textarea class="form-control" [(ngModel)]="this.myModelVariable"
appOnlyNumbers [allowMultiLine]="true" [maxLength]="9"
placeholder="Enter values (one per line)"></textarea>
这是我的指令:
import { Directive, HostListener, Input, ElementRef } from '@angular/core';
@Directive({
selector: '[appOnlyNumbers]'
})
export class OnlyNumbersDirective {
constructor(private el: ElementRef) { }
@Input() allowMultiLine: boolean = false;
@Input() allowNegative: boolean = false;
@Input() allowDecimal: boolean = false;
@Input() maxLength: number = 0;
regex: RegExp;
@HostListener('keypress', ['$event'])
onKeyPress(event: KeyboardEvent) {
this.validate(event, event.key === 'Enter' ? '\n' : event.key);
}
@HostListener('paste', ['$event'])
onPaste(event: Event) {
const pastedText = (<any>window).clipboardData && (<any>window).clipboardData.getData('Text') // If IE, use window
|| <ClipboardEvent>event && (<ClipboardEvent>event).clipboardData.getData('text/plain'); // Non-IE browsers
this.validate(event, pastedText);
}
@HostListener('cut', ['$event'])
onCut(event: Event) {
this.validate(event, '');
}
validate(event: Event, text: string) {
const txtInput = this.el.nativeElement;
const newValue = (txtInput.value.substring(0, txtInput.selectionStart)
+ text + txtInput.value.substring(txtInput.selectionEnd));
if (!this.regex) {
this.regex = <RegExp>eval('/^'
+ (this.allowNegative ? '-?' : '')
+ (this.allowDecimal ? '((\\d+\\.?)|(\\.?))\\d*' : '\\d*')
+ '$/g');
}
var lines = this.allowMultiLine ? newValue.split('\n') : [newValue];
for (let line of lines) {
let lineText = line.replace('\r', '');
if (this.maxLength && lineText.length > this.maxLength || !lineText.match(this.regex)) {
event.preventDefault();
return;
}
}
}
}
答案 25 :(得分:0)
虽然有很多答案,但没有一个是简单的 npm 包
基于 Elvis Fernandez's 答案,在我添加了几个边缘情况的处理后,我创建了一个 NG 模块,您可以使用 npm 轻松安装:
<块引用>npm i ngx-numbers-only-directive
如何使用:
在您的 appModule 中导入 NgxNumbersOnlyDirectiveModule:
<块引用>从'ngx-numbers-only-directive'导入{ NgxNumbersOnlyDirectiveModule }
并将其添加到您的导入数组中:
<块引用>导入:[NgxNumbersOnlyDirectiveModule]
将指令添加到输入元素。示例:
<块引用>< 输入 NgxNumbersOnly >
允许负数:
<块引用>允许使用小数:
<块引用>如果你不想添加包,指令源代码在:
<块引用>答案 26 :(得分:0)
fromCharCode返回&#39; a&#39;当按下小键盘时,&#39; 1&#39;所以应避免使用这种方法
(管理员:无法照常评论)
答案 27 :(得分:0)
HTML:
<input type="text" maxlength="5"(focusout)="onTextboxFocusOutDecimalPercentageValidate($event)"
(input)="onTextboxChangeDecimalPercentageValidate($event)">
TS:
onTextboxChangeDecimalPercentageValidate(event: Event) {
var inputData = (<HTMLInputElement>event.target).value;
//replace more than one dot
var extractedFte = inputData.replace(/[^0-9.]/g, '').replace('.', 'x')
.replace(/\./g, '').replace('x', '.');
//Extract Decimal Values
extractedFte = extractedFte.replace(/^(\d+.?\d{0,2})\d*$/, "$1");
//Reasign to same control
(<HTMLInputElement>event.target).value = extractedFte;
if (extractedFte != '' && Number(extractedFte) >= 100) {
(<HTMLInputElement>event.target).value = '100'; extractedFte = '100';
}
// if (Number(extractedFte) == 0) {
// (<HTMLInputElement>event.target).value = ''; extractedFte = '';
// }
}
onTextboxFocusOutDecimalPercentageValidate(event: Event) {
var inputData = (<HTMLInputElement>event.target).value;
//replace more than one dot
var extractedFte = inputData.replace(/[^0-9.]/g, '').replace('.', 'x')
.replace(/\./g, '').replace('x', '.');
//Extract Decimal Values
extractedFte = extractedFte.replace(/^(\d+.?\d{0,2})\d*$/, "$1");
//Reasign to same control
(<HTMLInputElement>event.target).value = extractedFte;
if (extractedFte != '' && Number(extractedFte) >= 100) {
(<HTMLInputElement>event.target).value = '100'; extractedFte = '100';
}
if (Number(extractedFte) == 0) {
(<HTMLInputElement>event.target).value = ''; extractedFte = '';
}
}
答案 28 :(得分:0)
支持清理粘贴的内容:
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[NumbersOnly]'
})
export class NumbersOnlyDirective {
DIGITS_REGEXP = new RegExp(/\D/g);
constructor(private el: ElementRef) {
// Sanatize clipboard by removing any non-numeric input after pasting
this.el.nativeElement.onpaste = (e:any) => {
e.preventDefault();
let text;
let clp = (e.originalEvent || e).clipboardData;
if (clp === undefined || clp === null) {
text = (<any>window).clipboardData.getData('text') || '';
if (text !== '') {
text = text.replace(this.DIGITS_REGEXP, '');
if (window.getSelection) {
let newNode = document.createElement('span');
newNode.innerHTML = text;
window.getSelection().getRangeAt(0).insertNode(newNode);
} else {
(<any>window).selection.createRange().pasteHTML(text);
}
}
} else {
text = clp.getData('text/plain') || '';
if (text !== '') {
text = text.replace(this.DIGITS_REGEXP, '');
document.execCommand('insertText', false, text);
}
}
};
}
@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();
}
}
}
答案 29 :(得分:0)
import React, {Component} from 'react';
import {
View,
Button,
Text,
Platform,
StyleSheet,
TouchableOpacity,
TouchableHighlight,
Animated,
ScrollView,
Image,
} from 'react-native';
import Video from 'react-native-video';
export default class App extends Component {
render() {
return (
<View style={{flex: 1, marginTop: 50}}>
<Video
source={{uri: 'YOUR_URL'}} // Can be a URL or a local file.
ref={ref => {
this.player = ref;
}} // Store reference
onBuffer={this.onBuffer} // Callback when remote video is buffering
onError={this.videoError} // Callback when video cannot be loaded
style={styles.backgroundVideo}
/>
</View>
);
}
}
const styles = StyleSheet.create({
field: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
paddingTop: 10,
paddingBottom:10,
},
backgroundVideo: {
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
},
});
答案 30 :(得分:0)
import {Directive, ElementRef, HostListener, Output, EventEmitter} from '@angular/core';
//only-digits
@Directive({
selector: '[only-digits]'
})
export class OnlyDigits {
constructor(public el: ElementRef) {
this.el.nativeElement.onkeypress = (evt) => {
if (evt.which < 48 || evt.which > 57) {
evt.preventDefault();
}
};
}
}
答案 31 :(得分:0)
您还可以创建一个实现ControlValueAccessor接口(https://angular.io/api/forms/ControlValueAccessor)的指令。
在此处查看工作示例:https://stackblitz.com/edit/angular-input-field-to-accept-only-numbers
您可以收听“ input”事件,而无需检查键码。 由于ControlValueAccessor接口,它支持复制和粘贴并与Angular Forms API很好地集成。
指令:
@Directive({
...
selector: '[onlyNumber]'
})
export class OnlyNumberDirective implements ControlValueAccessor {
private onChange: (val: string) => void;
...
private value: string;
constructor(
private elementRef: ElementRef,
private renderer: Renderer2
) {
}
...
@HostListener('input', ['$event.target.value'])
onInputChange(value: string) {
const filteredValue: string = filterValue(value);
this.updateTextInput(filteredValue, this.value !== filteredValue);
}
private updateTextInput(value, propagateChange) {
this.renderer.setProperty(this.elementRef.nativeElement, 'value', value);
if (propagateChange) {
this.onChange(value);
}
this.value = value;
}
// ControlValueAccessor Interface
...
registerOnChange(fn: any): void {
this.onChange = fn;
}
writeValue(value: string): void {
value = value ? String(value) : '';
this.updateTextInput(value, false);
}
}
function filterValue(value): string {
return value.replace(/[^0-9]*/g, '');
}
用法:
<input name="number" type="text" onlyNumber [(ngModel)]="someNumber">
答案 32 :(得分:0)
仅仅写就不够简单
onlyNumbers(event) {
if(isNaN(event.target.value * 1)) {
console.log("Not a number")
} else {
console.log("Number")
}
}
答案 33 :(得分:0)
如果使用primeng和Angular 6或更高版本,则有p-inputMask组件。它可以防止字母输入和负值 https://www.primefaces.org/primeng/#/inputmask
答案 34 :(得分:0)
只需在文本上使用类型编号,如下所示:
Swal.fire({ //
html: '
blah blah ',
input: 'select',
inputOptions: {
'none': 'Please select an option:',
'option1': 'First Option',
'option2': 'Second Option'
},
inputValidator: function(value) {
return new Promise(function(resolve, reject) {
if (value != 'none') {
resolve();
} else {
reject('You need to select an option');
}
});
}
}).then(function(theoption) {
// etc etc...
答案 35 :(得分:0)
我看到很多关于处理复制/粘贴的评论。
要回顾@omeralper的答案,你可以在onlyNumber指令中添加一个粘贴事件处理程序来处理复制/粘贴:
@HostListener('paste', ['$event']) onPaste(event) {
// Don't allow pasted text that contains non-numerics
var pastedText = (event.originalEvent || event).clipboardData.getData('text/plain');
if (pastedText) {
var regEx = new RegExp('^[0-9]*$');
if (!regEx.test(pastedText)) {
event.preventDefault();
}
}
这仅允许将内容复制并粘贴到文本框中(如果它是一个数字)。这是最简单的解决方案。更改剪贴板的内容以删除非数字更复杂,可能不值得。
要从IE获取粘贴文本,您可以使用以下内容:
window.clipboardData.getData('Text');
答案 36 :(得分:0)
Ngx Mask 有一个很好的解决方案。这是一个轻量级的安装包,所以它是值得的。当使用 type="number" 不是所需的选项时,我会使用它。
安装后,您所要做的就是:
/**
* @Assert\LessThan("today")
*/
private $date;
答案 37 :(得分:-2)
使用指令限制用户仅以下列方式输入数字:
.directive('onlyNumber', function () {
var regExp = /^[0-9]*$/;
return {
require: '?ngModel',
restrict: 'A',
priority: 1,
link: function (scope, elm, attrs, ctrl) {
ctrl.$validators.onlyNumber= function (modalValue) {
return ctrl.$isEmpty(modalValue) || regExp.test(modalValue);
};
}
};
})
在HTML中:
<input id="txtRollNumber" type="text" name="rollNumber" placeholder="Enter roll number*" ng-model="rollNumber" class="form-control" maxlength="100" required only-number />
Angular2:
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[OnlyNumber]'
})
export class OnlyNumber {
constructor(private el: ElementRef) { }
@Input() OnlyNumber: boolean;
@HostListener('keydown', ['$event']) onKeyDown(event) {
let e = <KeyboardEvent> event;
if (this.OnlyNumber) {
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();
}
}
}
}
需要在输入中将指令名称作为属性编写。
<input OnlyNumber="true" />
答案 38 :(得分:-2)
只需使用HTML5,输入type =” number”