Ani*_*dhe 62 html input angularjs-directive angular
在Angular2中,如何屏蔽输入字段(文本框),使其仅接受数字而不接受字母?
我有以下HTML输入:
<input
type="text"
*ngSwitchDefault
class="form-control"
(change)="onInputChange()"
[(ngModel)]="config.Value"
(focus)="handleFocus($event)"
(blur)="handleBlur($event)"
/>
Run Code Online (Sandbox Code Playgroud)
上面的输入是通用文本输入,可以用作简单文本字段或数字字段(例如显示年份).
使用angular2,我如何使用相同的输入控件并在此字段上应用某种过滤器/蒙版,这样它只接受数字?我可以通过哪些不同方式实现这一目标?
注意:我需要仅使用文本框而不使用输入数字类型来实现此目的.
ome*_*per 95
您可以使用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();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
并且您需要在输入中将指令名称作为属性编写
<input OnlyNumber="true" />
Run Code Online (Sandbox Code Playgroud)
不要忘记在模块的声明数组中编写指令.
通过使用正则表达式,您仍然需要功能键
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
ras*_*dnk 50
如果你不想要一个指令
https://stackblitz.com/edit/numeric-only
在component.html中
<input (keypress)="numberOnly($event)" type="text">
Run Code Online (Sandbox Code Playgroud)
在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;
}
}
Run Code Online (Sandbox Code Playgroud)
Jea*_* A. 28
我想建立@omeralper给出的答案,我认为这为一个可靠的解决方案提供了良好的基础.
我建议的是一个简化的最新版本,其中包含最新的Web标准.请务必注意,event.keycode已从Web标准中删除,未来的浏览器更新可能不再支持它.请参阅https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
此外,该方法
String.fromCharCode(e.keyCode);
Run Code Online (Sandbox Code Playgroud)
不保证与用户按下的键有关的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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
Elv*_*dez 21
我知道这是一个老问题,但由于这是一个常见的功能,我想分享我所做的修改:
替换".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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)用法:
<input NumbersOnly
[allowDecimals]="true"
[allowSign]="true"
type="text">
Run Code Online (Sandbox Code Playgroud)
ket*_*han 13
<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();
}
}
Run Code Online (Sandbox Code Playgroud)
Ben*_*apa 13
更简洁的解决方案.试试这个指令.
如果您正在使用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, ''));
}
}
Run Code Online (Sandbox Code Playgroud)
在输入上使用它如下:
<input matInput formControlName="aNumberField" numberOnly>
Run Code Online (Sandbox Code Playgroud)
Jas*_*n W 11
我知道这有很多答案,但我需要处理以下问题(似乎没有一个答案完全支持):
该解决方案允许我像这样定义一个 textarea:
<textarea class="form-control" [(ngModel)]="this.myModelVariable"
appOnlyNumbers [allowNegative]="true" [allowMultiLine]="true"
[allowDecimal]="true" [maxLength]="10"
placeholder="Enter values (one per line)"></textarea>
Run Code Online (Sandbox Code Playgroud)
或者如果我只想要正整数
<textarea class="form-control" [(ngModel)]="this.myModelVariable"
appOnlyNumbers [allowMultiLine]="true" [maxLength]="9"
placeholder="Enter values (one per line)"></textarea>
Run Code Online (Sandbox Code Playgroud)
这是我的指令:
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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 8
您需要使用type ="number"而不是文本.您还可以指定最大和最小数字
<input type="number" name="quantity" min="1" max="5">
Run Code Online (Sandbox Code Playgroud)
你可以像这样实现它
<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;
}
Run Code Online (Sandbox Code Playgroud)
希望这会帮助你.
最佳答案的现代方法(不推荐使用 e.keyCode):
@HostListener('keydown', ['$event']) onKeyDown(event) {
let e = <KeyboardEvent> event;
if (['Delete', 'Backspace', 'Tab', 'Escape', 'Enter', 'NumLock', 'ArrowLeft', 'ArrowRight', 'End', 'Home', '.'].indexOf(e.key) !== -1 ||
// Allow: Ctrl+A
(e.key === 'a' && (e.ctrlKey || e.metaKey)) ||
// Allow: Ctrl+C
(e.key === 'c' && (e.ctrlKey || e.metaKey)) ||
// Allow: Ctrl+V
(e.key === 'v' && (e.ctrlKey || e.metaKey)) ||
// Allow: Ctrl+X
(e.key === 'x' && (e.ctrlKey || e.metaKey))) {
// let it happen, don't do anything
return;
}
// Ensure that it is a number and stop the keypress
if ((e.shiftKey || ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].indexOf(e.key) === -1)) {
e.preventDefault();
}
}
Run Code Online (Sandbox Code Playgroud)
使用pattern属性进行输入,如下所示:
<input type="text" pattern="[0-9]+" >
Run Code Online (Sandbox Code Playgroud)
<input oninput="this.value=this.value.replace(/[^0-9]/g,'')"或: 2. 在 HTML 文件中:
<input [(ngModel)]="data" (keypress)="stripText($event)"
class="form-control">
Run Code Online (Sandbox Code Playgroud)
在 ts 文件中:
stripText(event) {
const seperator = '^([0-9])';
const maskSeperator = new RegExp(seperator , 'g');
let result =maskSeperator.test(event.key); return result; }
Run Code Online (Sandbox Code Playgroud)
这 2 个解决方案有效
您可以使用正则表达式:
<input type="text" (keypress)="numericOnly($event)">
numericOnly(event): boolean {
let patt = /^([0-9])$/;
let result = patt.test(event.key);
return result;
}
Run Code Online (Sandbox Code Playgroud)
感谢 JeanPaul A. 和 rdanielmurphy。我已经制定了自己的自定义指令,用于将输入字段限制为仅数字。还添加了 max 和 min 输入属性。也将在角度 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();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
HTML
<input type="text" class="text-area" [(ngModel)]="itemName" maxlength="3" appNumberOnly />
Run Code Online (Sandbox Code Playgroud)
这是使用任意正则表达式并阻止用户键入无效值的小指令
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();
}
}Run Code Online (Sandbox Code Playgroud)
只屏蔽数字使用
<input [allowedRegExp]="'^[0-9]*$'" type="text" ... >
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
169941 次 |
| 最近记录: |