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 dieselbe Eingabesteuerung 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 erreichen, indem ich nur ein Textfeld verwende und nicht den Eingabenummerntyp.
Könnten Sie einfach das HTML-Attribut verwenden? Typ=Zahl
– inoabrisch
4. Januar 2017 um 13:58 Uhr
@inoabrian Ich möchte dies erreichen, ohne den Zahlentyp zu verwenden.
– Aniruddha Pondhe
5. Januar 2017 um 6:32 Uhr
Dies kann Ihnen helfen: stackoverflow.com/questions/39799436/…
Das Problem bei diesem Ansatz besteht darin, dass Schlüsselereignisse das Einfügen eines Benutzers oder das automatische Ausfüllen des Eingabefelds durch einen Browser nicht erfassen. Das ist also eine schlechte Lösung.
– Darryn Hosking
21. August 2018 um 9:38 Uhr
Ich habe die letzte Zeile der Methode validatevalue geändert, um das Hinzufügen einer Null für ungültiges Einfügen zu verhindern. if (gültig) { this.hostElement.nativeElement[‘value’] = Wert;}
– Abdul Rehman Sayed
22. Oktober 2018 um 11:08 Uhr
Können Sie bitte auch die Drag & Drop-Validierung hinzufügen? Außerdem ist mir aufgefallen, dass sich der Wert des Eingabefelds in den mit 0 aufgefüllten Wert für das führende und nachfolgende Dezimaltrennzeichen ändert, der Wert jedoch nicht in der bidirektionalen Bindungsvariablen aktualisiert wird. zum Beispiel: [(NgModel)]=”myVariable” , hier, wenn wir .3 in das Eingabefeld eingeben, ändert sich der Wert in der Texteingabe auf 0,3 auf Blur, aber der Wert in myVariable bleibt immer noch ‘.3’ .
– Sushmit Sagar
1. März 2019 um 6:52 Uhr
Die Eingabe zum Löschen und Eingeben fehlt, aber die Lösung ist trotzdem sehr gut
– Oleg Bondarenko
8. Oktober 2020 um 15:11 Uhr
@SushmitSagar, um sicherzustellen, dass die 2-Wege-Datenbindung funktioniert, fügen Sie Folgendes hinzu: @Output() ngModelChange:EventEmitter = new EventEmitter(); zu den Deklarationen und fügen Sie dann hinzu: this.ngModelChange.emit(valid ? value : 0); als letzte Zeile in der Methode validateValue
– Gabriel H
16. April 2021 um 7:29 Uhr
Fügen Sie diese Zeilen auch zur validateValue-Methode hinzu: //Entfernen Sie unnötige führende Nullen let secondChar=value.charAt(1); if (firstCharacter==’0’&&(secondChar!=”||secondChar!=this.decimalSeparator)) { value=value.substring(1); }
– Gabriel H
16. April 2021 um 9:29 Uhr
JeanPaul A.
Ich möchte auf der Antwort von @omeralper aufbauen, die meiner Meinung nach eine gute Grundlage für eine solide Lösung bietet.
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 wurde und zukünftige Browser-Updates dies möglicherweise nicht mehr unterstützen. Sehen https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
Außerdem 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 identifiziert wird, da unterschiedliche Tastaturkonfigurationen zu unterschiedlichen Zeichen eines bestimmten Tastencodes führen. Wenn Sie dies verwenden, werden Fehler eingeführt, die schwer zu identifizieren sind und die Funktionalität für bestimmte Benutzer leicht beeinträchtigen können. Vielmehr schlage ich die Verwendung von event.key vor, siehe Dokumentation hier https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key
Außerdem wollen wir nur, dass die resultierende Ausgabe eine gültige Dezimalzahl ist. Das bedeutet, dass die Zahlen 1, 11.2, 5000.2341234 akzeptiert werden sollen, aber der Wert 1.1.2 nicht akzeptiert werden soll.
Beachten Sie, dass ich in meiner Lösung die Funktionen zum Ausschneiden, Kopieren und Einfügen ausschließe, da sie Fenster für Fehler öffnen, insbesondere wenn Benutzer unerwünschten Text in zugehörige Felder einfügen. Das würde einen Bereinigungsprozess auf einem Keyup-Handler erfordern; was nicht Gegenstand dieses Threads ist.
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();
}
}
}
Das ist ein wirklich interessanter Ansatz. Haben Sie Vorschläge, wie Sie die Funktion zum Kopieren/Einfügen implementieren können, ohne auf ältere Methoden wie (e.keyCode == 67 && e.ctrlKey === true) zurückzugreifen?
– Ender2050
18. August 2017 um 14:28 Uhr
Ich habe das nicht persönlich ausprobiert, aber Sie können sich auch die ausgelösten Copy/Paste-Ereignisse anhören. Sie erzeugen ein ClipboardEvent ( developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent ), die die Daten enthält, die kopiert/eingefügt werden. Der einzige Nachteil ist, dass dies noch experimentell ist und nur von den neuesten Browsern unterstützt wird – caniuse.com/#search=paste
– Jean Paul A.
19. August 2017 um 10:15 Uhr
Ich habe einen ähnlichen Ansatz versucht, aber leider funktioniert dies nicht für jeden Fall. Ihre “nächste” Variable geht davon aus, dass das gedrückte Zeichen am Ende des aktuell eingegebenen Werts steht. Dies ist nicht immer der Fall. Zum Beispiel, wenn jemand 100 eintippt und dann beschließt, es 1100 zu machen, indem er eine 1 an den Anfang anhängt. Ihre “nächste” Variable wird falsch sein (1001).
– Carlos Rodríguez
23. August 2017 um 23:07 Uhr
Da der „nächste“ Wert nur verwendet wird, um zu prüfen, ob der Eingabebetrag eine gültige Dezimalzahl ist (und nicht, um den Wert festzulegen), würde das Anhängen am Ende die Regex-Validierung nicht ändern.
– Jean Paul A.
24. August 2017 um 6:31 Uhr
Nur möchte ich diese Zeile hinzufügen, um sie in der Eingabesteuerung anzuwenden.
– Lrodriguez84
25. April 2018 um 13:15 Uhr
Ben Gulapa
Eine kürzere Lösung. Probieren Sie diese Direktive aus.
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, ''));
}
}
Das ist ein wirklich interessanter Ansatz. Haben Sie Vorschläge, wie Sie die Funktion zum Kopieren/Einfügen implementieren können, ohne auf ältere Methoden wie (e.keyCode == 67 && e.ctrlKey === true) zurückzugreifen?
– Ender2050
18. August 2017 um 14:28 Uhr
Ich habe das nicht persönlich ausprobiert, aber Sie können sich auch die ausgelösten Copy/Paste-Ereignisse anhören. Sie erzeugen ein ClipboardEvent ( developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent ), die die Daten enthält, die kopiert/eingefügt werden. Der einzige Nachteil ist, dass dies noch experimentell ist und nur von den neuesten Browsern unterstützt wird – caniuse.com/#search=paste
– Jean Paul A.
19. August 2017 um 10:15 Uhr
Ich habe einen ähnlichen Ansatz versucht, aber leider funktioniert dies nicht für jeden Fall. Ihre “nächste” Variable geht davon aus, dass das gedrückte Zeichen am Ende des aktuell eingegebenen Werts steht. Dies ist nicht immer der Fall. Zum Beispiel, wenn jemand 100 eintippt und dann beschließt, es 1100 zu machen, indem er eine 1 an den Anfang anhängt. Ihre “nächste” Variable wird falsch sein (1001).
– Carlos Rodríguez
23. August 2017 um 23:07 Uhr
Da der „nächste“ Wert nur verwendet wird, um zu prüfen, ob der Eingabebetrag eine gültige Dezimalzahl ist (und nicht, um den Wert festzulegen), würde das Anhängen am Ende die Regex-Validierung nicht ändern.
– Jean Paul A.
24. August 2017 um 6:31 Uhr
Nur möchte ich diese Zeile hinzufügen, um sie in der Eingabesteuerung anzuwenden.
– Lrodriguez84
25. April 2018 um 13:15 Uhr
Zia Khan
Sie müssen type=”number” anstelle von text verwenden. Sie können auch maximale und minimale Zahlen angeben
Ich möchte dies erreichen, ohne den Zahlentyp zu verwenden.
– Aniruddha Pondhe
5. Januar 2017 um 6:32 Uhr
Die Unterstützung für den Zahlentyp ist immer noch ziemlich fehlerhaft, wie in dieser Antwort beschrieben: stackoverflow.com/a/14995890/1156185
– Nikolaus Forney
16. Mai 2017 um 9:35 Uhr
Die Kehrseite von type="number" ist, dass es Charakter akzeptiert e als Teil der wissenschaftlichen Notation
– Benutzer776686
16. Juni 2017 um 10:18 Uhr
Der Nachteil von type=”number” ist, dass es die Tastatur kaputt macht und den Benutzer raten lässt, warum die Tastatur nicht mehr funktioniert. Das Filtern ist sehr benutzerfreundlich, ein besserer Ansatz ist es, eine klare Fehlermeldung anzuzeigen und die Eingabe intakt zu halten. Wenn ein Benutzer a1b2c3 eingibt, macht es absolut keinen Sinn, ihm das Ergebnis “123” zu geben.
– Cäsar
6. Juni 2021 um 15:53 Uhr
10011900cookie-checkAngular2 – Eingabefeld, um nur Zahlen zu akzeptierenyes
Könnten Sie einfach das HTML-Attribut verwenden? Typ=Zahl
– inoabrisch
4. Januar 2017 um 13:58 Uhr
@inoabrian Ich möchte dies erreichen, ohne den Zahlentyp zu verwenden.
– Aniruddha Pondhe
5. Januar 2017 um 6:32 Uhr
Dies kann Ihnen helfen: stackoverflow.com/questions/39799436/…
– Chandan7
5. Januar 2017 um 7:45 Uhr