Wie kann ich in Angular 2 ein Eingabefeld (Textfeld) so maskieren, dass nur Zahlen und keine alphabetischen Zeichen akzeptiert werden?
Ich habe die folgende HTML-Eingabe:
<input
type="text"
*ngSwitchDefault
class="form-control"
(change)="onInputChange()"
[(ngModel)]="config.Value"
(focus)="handleFocus($event)"
(blur)="handleBlur($event)"
/>
Die obige Eingabe ist eine generische Texteingabe, die entweder als einfaches Textfeld oder als numerisches Feld verwendet werden kann, um beispielsweise das Jahr anzuzeigen.
Wie kann ich mit Angular 2 dasselbe Eingabesteuerelement verwenden und eine Art Filter / Maske auf dieses Feld anwenden, sodass nur Zahlen akzeptiert werden?
Was sind die verschiedenen Möglichkeiten, wie ich dies erreichen kann?
Hinweis: Ich muss dies nur mit einem Textfeld und nicht mit dem Typ der Eingabenummer erreichen.
html
angular
input
angularjs-directive
Aniruddha Pondhe
quelle
quelle
Antworten:
Sie können angle2-Direktiven verwenden. 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(); } } } }
und Sie müssen den Direktivennamen in Ihre Eingabe als Attribut schreiben
<input OnlyNumber="true" />
Vergessen Sie nicht, Ihre Direktive in das Deklarationsarray Ihres Moduls zu schreiben.
Bei Verwendung von Regex benötigen Sie weiterhin Funktionstasten
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(); } } }
quelle
(e.keyCode == 86 && e.ctrlKey === true)
zu Bedingungen hinzufügen , Kopie funktioniert, aber Einfügen funktionierte nichtWenn Sie keine Richtlinie wollen
https://stackblitz.com/edit/numeric-only
in component.html
<input (keypress)="numberOnly($event)" type="text">
in 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; } }
quelle
Ich weiß, dass dies eine alte Frage ist, aber da dies eine übliche Funktion ist, möchte ich die von mir vorgenommenen Änderungen mitteilen:
Ersetzen Sie Zeichenfolgen wie ".33" und "33". für die richtigen Versionen: 0.33 und 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); } } } }
Verwendung:
<input NumbersOnly [allowDecimals]="true" [allowSign]="true" type="text">
quelle
Ich möchte auf der Antwort von @omeralper aufbauen, die meiner Meinung nach eine gute Grundlage für eine solide Lösung bot.
Was ich vorschlage, ist eine vereinfachte und aktuelle Version mit den neuesten Webstandards. Es ist wichtig zu beachten, dass event.keycode aus den Webstandards entfernt wird und zukünftige Browser-Updates dies möglicherweise nicht mehr unterstützen. Siehe https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
Weiterhin ist die Methode
String.fromCharCode(e.keyCode);
garantiert nicht, dass der keyCode, der sich auf die vom Benutzer gedrückte Taste bezieht, dem erwarteten Buchstaben entspricht, der auf der Tastatur des Benutzers angegeben ist, da unterschiedliche Tastaturkonfigurationen dazu führen, dass ein bestimmter Keycode unterschiedliche Zeichen enthält. Wenn Sie dies verwenden, treten Fehler auf, die schwer zu identifizieren sind und die Funktionalität für bestimmte Benutzer leicht beeinträchtigen können. Ich schlage eher die Verwendung von event.key vor, siehe Dokumente hier https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key
Außerdem möchten wir nur, dass die resultierende Ausgabe eine gültige Dezimalzahl ist. Dies bedeutet, dass die Nummern 1, 11.2, 5000.2341234 akzeptiert werden sollten, der Wert 1.1.2 jedoch nicht akzeptiert werden sollte.
Beachten Sie, dass ich in meiner Lösung die Funktionen zum Ausschneiden, Kopieren und Einfügen ausschließe, da Fenster für Fehler geöffnet werden, insbesondere wenn unerwünschte Texte in zugehörige Felder eingefügt werden. Dies würde einen Bereinigungsprozess für einen Keyup-Handler erfordern. Das ist nicht der Umfang dieses Threads.
Hier ist die Lösung, die ich vorschlage.
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(); } } }
quelle
Eine präzisere Lösung. Versuchen Sie diese Anweisung.
Kann auch verwendet werden, wenn Sie ReactiveForms verwenden.
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, '')); } }
Verwenden Sie es für Ihre Eingaben wie folgt:
<input matInput formControlName="aNumberField" numberOnly>
quelle
<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(); } }
quelle
Sie müssen stattdessen type = "number" als Text verwenden. Sie können auch maximale und minimale Zahlen angeben
<input type="number" name="quantity" min="1" max="5">
quelle
type="number"
ist, dass es Charaktere
als Teil der wissenschaftlichen Notation akzeptiertSie können es so erreichen
<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; }
hoffe das wird dir helfen.
quelle
Sie könnten Regex verwenden:
<input type="text" (keypress)="numericOnly($event)"> numericOnly(event): boolean { let patt = /^([0-9])$/; let result = patt.test(event.key); return result; }
quelle
Verwenden Sie das
pattern
Attribut für die Eingabe wie folgt:<input type="text" pattern="[0-9]+" >
quelle
Ich weiß, dass dies viele Antworten hat, aber ich musste Folgendes behandeln (was keine der Antworten vollständig zu unterstützen schien):
Die Lösung ermöglicht es mir, einen Textbereich wie diesen zu definieren:
<textarea class="form-control" [(ngModel)]="this.myModelVariable" appOnlyNumbers [allowNegative]="true" [allowMultiLine]="true" [allowDecimal]="true" [maxLength]="10" placeholder="Enter values (one per line)"></textarea>
Oder wenn ich nur positive ganze Zahlen will
<textarea class="form-control" [(ngModel)]="this.myModelVariable" appOnlyNumbers [allowMultiLine]="true" [maxLength]="9" placeholder="Enter values (one per line)"></textarea>
Hier ist meine Anweisung:
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; } } } }
quelle
Um dies zu erreichen, habe ich eine Funktion wie folgt an die onInput-Methode gebunden:
(input)="stripText(infoForm.get('uin'))
Hier ist das Beispiel in meinem Formular:
<form [formGroup]="infoForm" (submit)="next()" class="ui form"> <input type="text" formControlName="uin" name="uin" id="uin" (input)="stripText(infoForm.get('uin'))" required/> </form>
Dann habe ich meiner Komponente die folgende Funktion hinzugefügt:
stripText(control: FormControl) { control.setValue(control.value.replace(/[^0-9]/g, '')); }
Diese Regex
/[^0-9]/g
sucht nach etwas, das keine Zahl ist, und mit.replace
I setze ich, dass es durch nichts ersetzt wird. Wenn ein Benutzer versucht, ein Zeichen einzugeben, das keine Zahl ist (in diesem Fall ein Zeichen, das nicht null bis neun ist), sieht es so aus, als ob im Textfeld nichts passiert.quelle
Vielen Dank an JeanPaul A. und rdanielmurphy. Ich hatte meine eigene benutzerdefinierte Anweisung erstellt, um das Eingabefeld nur auf die Anzahl zu beschränken. Außerdem wurden die Eingabeattribute max und min hinzugefügt. Funktioniert auch in Winkel 7.
Winkelig
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 />
quelle
Ein moderner Ansatz für die beste Antwort (ohne veralteten 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(); } }
quelle
Beliebige RegExp-Direktive
Hier ist eine kleine Direktive, die einen beliebigen regulären Ausdruck verwendet und den Benutzer blockiert, um einen ungültigen Wert einzugeben
Code-Snippet anzeigen
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(); } }
Um nur Zahlen zu maskieren, verwenden Sie
<input [allowedRegExp]="'^[0-9]*$'" type="text" ... >
quelle
Erstellen Sie einfach eine Direktive und fügen Sie unten den Hostlistener hinzu:
@HostListener('input', ['$event']) onInput(event: Event) { this.elementRef.nativeElement.value = (<HTMLInputElement>event.currentTarget).value.replace(/[^0-9]/g, ''); }
Ersetzen Sie ungültigen Text durch leeren. Alle Schlüssel und Tastenkombinationen funktionieren jetzt in allen Browsern bis IE9.
quelle
Muster für das gültige Handynummernmuster ('^ ((\ + 91 -?) | 0)? [0-9] {10} $')
Muster zum Akzeptieren nur der Nummer aus dem Textfeldmuster ('[0-9] *')
Muster, um nur eine Nummer mit einer bestimmten Nummer zu akzeptieren, z. B.: Pincode. Muster ('^ [0-9] {5} $')
quelle
Ich habe einige Änderungen an der obigen Richtlinie vorgenommen und min, max, maxlength implementiert.
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(); } } }
quelle
aus der Antwort von @omeralper. Ich ändere ein wenig, das Punkt ASCII nicht akzeptiert (Schlüsselcode 110,190). und benutze let ch = (e.key); Wenn Sie die Sprache ändern (z. B. Thai oder Japanisch), wird der Charakter dieser Sprache nicht akzeptiert
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(); } } }
Ich hoffe das hilft :)
quelle
Sie können diesen Validator erstellen und in Ihre Komponente importieren.
Überprüft grundsätzlich die Formulareingabezeichenfolge:
So implementieren Sie es in Ihrem Projekt:
in Ihre Komponente importieren
import { NumberValidator } from '../../validators/number.validator';
inputNumber: ['', [NumberValidator.isInteger]],
(change)="deleteCharIfInvalid()"
an die Eingabe. Wenn dies der Fallform.get('inputNumber').hasError('isInteger')
isttrue
, löschen Sie das zuletzt eingefügte Zeichen.// 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; } }
quelle
Number.isInteger(Math.floor(control.value))
immer wahr sein? Ich denke es sollteparseFloat
stattdessen sein.Mit Unterstützung für die Bereinigung eingefügter Inhalte:
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(); } } }
quelle
Hier ist eine einfache Anweisung: Einfache Anweisung Bei einem Keydown-Ereignis wird überprüft, ob die Länge eines Schlüssels eins ist und der Schlüssel keine Zahl ist,
preventDefault()
und dieses Zeichen wird nicht gerendert.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 />
Einschränkungen: Auf diese Weise können Sie mit einer Maus andere Zeichen einfügen. Um dies zu vermeiden, können Sie das Modell als Eingabe an die Direktive übergeben und
ngOnChage
an dieses Modell den Wert nur in Zahlen ändern:Wie unten:
BEARBEITEN: Code hinzugefügt, um Änderungen im Modell zu erkennen und den Wert der Eingabe zu aktualisieren
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" />
quelle
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(); } }; } }
Richtlinie ist auch der beste Weg, dies zu tun
quelle
Casting, weil es auch mit führenden 0 wie 00345 funktioniert
@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, '')); } }
quelle
<input oninput="this.value=this.value.replace(/[^0-9]/g,'')"
oder: 2. in der HTML-Datei:
<input [(ngModel)]="data" (keypress)="stripText($event)" class="form-control">
in der ts-Datei:
stripText(event) { const seperator = '^([0-9])'; const maskSeperator = new RegExp(seperator , 'g'); let result =maskSeperator.test(event.key); return result; }
Diese 2 Lösung funktioniert
quelle
fromCharCode gibt beim Drücken des Nummernblocks '1' 'a' zurück, daher sollte dieses Methoid vermieden werden
(admin: konnte nicht wie gewohnt kommentieren)
quelle
Ich habe viele Kommentare zum Umgang mit Kopieren / Einfügen gesehen.
Um die Antwort von @omeralper zu deaktivieren, können Sie der onlyNumber-Direktive einen Paste-Ereignishandler hinzufügen, um das Kopieren / Einfügen zu handhaben:
@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(); } }
Dadurch können Inhalte nur dann kopiert und in das Textfeld eingefügt werden, wenn es sich um eine Zahl handelt. Das ist die einfachste Lösung. Das Ändern des Inhalts der Zwischenablage zum Entfernen von nicht numerischen Elementen ist viel komplizierter und möglicherweise nicht sinnvoll.
Um eingefügten Text aus dem IE zu erhalten, können Sie Folgendes verwenden:
window.clipboardData.getData('Text');
quelle
Wenn Sie primeng und Angular 6 oder höher verwenden, gibt es die p-inputMask-Komponente. Es verhindert Alpha-Typisierung UND negative Werte https://www.primefaces.org/primeng/#/inputmask
quelle
Wäre nicht einfach genug, nur zu schreiben
onlyNumbers(event) { if(isNaN(event.target.value * 1)) { console.log("Not a number") } else { console.log("Number") }
}}
quelle
Sie können auch eine Direktive erstellen, die die ControlValueAccessor-Schnittstelle implementiert ( https://angular.io/api/forms/ControlValueAccessor ).
Siehe Arbeitsbeispiel hier: https://stackblitz.com/edit/angular-input-field-to-accept-only-numbers
Sie können das Eingabeereignis abhören und müssen nicht nach Schlüsselcodes suchen. Es unterstützt das Kopieren und Einfügen und lässt sich dank der ControlValueAccessor-Schnittstelle gut in die Angular Forms-API integrieren.
Richtlinie:
@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, ''); }
Verwendung:
<input name="number" type="text" onlyNumber [(ngModel)]="someNumber">
quelle