Skip to main content

Der sicherste Weg zu einem number-only Textfeld

Es gibt diverse Anwendungsfälle, bei denen auf einer Webseite von den Nutzer/-innen verlangt wird, eine Zahlenkombination einzugeben. Dies kann zum Beispiel die Eingabe einer Kartennummer oder auch eines Aktivierungscodes sein. Solche Eingabefelder dürfen natürlich keine Buchstaben oder andere Zeichen enthalten. Allerdings ist es nicht ganz so trivial, wie es klingt, dieses gewünschte Verhalten zu erreichen.

Abgesehen davon, dass die Eingabe generell beim und nach dem Abschicken validiert werden soll, wäre es natürlich schön, wenn es gar nicht möglich wäre, etwas anderes als Ziffern in das Textfeld zu schreiben.

Vornweg gesagt: Ohne JavaScript ist dies nicht möglich. Aber schauen wir uns doch trotzdem mal an, welche reinen HTML-Strukturen vermeintlich zur Verfügung stehen

type = «number»

<input type="number">

Das «type»-Attribut mit dem Wert «number» scheint auf den ersten Blick genau das zu sein, was wir brauchen.

Das Ergebnis verwundert jedoch etwas: In Firefox, Safari und Edge lassen sich trotzdem Buchstaben eingeben. Der Browser markiert das Textfeld dabei zwar als ungültig, blockiert aber nicht die eigentliche Eingabe. Immerhin ein Fortschritt, aber nicht genau das, was wir suchen.

In Chrome sieht es schon eher nach dem von uns gewünschten Verhalten aus. Nur Ziffern können eingegeben werden und alle sonstigen Zeichen und Buchstaben werden ignoriert — Moment. Wirklich alle? Nicht ganz, denn bspw. «.» und «e» sind auch erlaubt.

Der Punkt («.») ist erlaubt, weil grundsätzlich auch die Eingabe von Zahlen mit Nachkommastellen möglich ist. Die Eingabe «8.7» würde dann auch gültig sein und somit abgeschickt werden können.

Der Buchstabe «e» ist erlaubt, um die wissenschaftliche Notation von grossen Zahlen darzustellen (bspw. «3e10» oder «1e+10»).

So gesehen macht das natürlich Sinn, aber wir wollen eben keine Zahlen, sondern eine Reihe von Ziffern erzwingen.

Dieser Aspekt führt uns vermutlich zum nächsten Attribut.

pattern=»[0-9]+»

<input pattern="[0-9]+">

Das «pattern»-Attribut, welches einen Regex enthält, der nur Ziffern erlaubt, macht ebenfalls den Anschein, als würde es das machen, was wir möchten. Leider lässt uns jedoch auch dieses Attribut im Stich. Die Eingabe wird nämlich überhaupt nicht eingeschränkt, sondern lediglich das Textfeld als ungültig markiert.

Dieses Attribut können wir also auch beiseite legen.

Kommen wir nun also doch zu einer funktionierenden Lösung mit JavaScript.

JavaScript

Da die vermeintlich einfachen Methoden nicht das gewünschte Verhalten bezwecken, müssen wir mit JavaScript nachhelfen. Im Grunde gibt es drei Herangehensweisen, die nachfolgend kurz erläutert werden.

Eine im Web häufig erwähnte Methode ist, bei jedem Tastendruck anhand des KeyCodes zu entscheiden, ob es eine Ziffer ist und demnach alles andere zu verwerfen.

—> Dieses Vorgehen ist sehr gefährlich und umständlich. Es muss akribisch dafür gesorgt sein, dass Navigationstasten, wie Enter, Pfeiltasten, Backspace, Delete, etc. nicht blockiert werden. Ausserdem ist es äusserst schwierig, das Copy-and-Paste-Verhalten sauber zuzulassen und auch dort keine anderen Zeichen zuzulassen.

Bei der zweiten Methode merkt man sich den aktuell eingegebenen Wert und prüft diesen mittels Regex. Falls die Eingabe Ziffern beinhaltet, wird diese verworfen, indem wieder auf den alten Wert zurückgegriffen wird. Dies ist bereits gut möglich und legitim, bietet aber noch die Schwierigkeit, das Copy-and-Paste-Verhalten zu berücksichtigen.

Der Vor- oder Nachteil dieser Methode gegenüber der dritten (je nach Anwendungszweck) ist folgender:
Wenn sich ein gemischter Text in der Zwischenablage befindet (bspw. «123abc») und eingefügt wird, dann passiert nichts. Weil der Text nicht nur aus Zahlen besteht, wird er abgelehnt. Somit bleibt das Eingabefeld leer und der/die Nutzer/-in weiss nicht, wieso es nicht funktioniert.

Die dritte und einfachste, obwohl nicht weniger sichere Methode ist, die Eingabe zuzulassen und dann ganz einfach alles, was keine Ziffer ist, zu löschen. Der Code dafür sieht dann beispielsweise so aus:

<input type="text" data-number-only />

// Unsere Funktion soll beim "input"-Event ausgeführt werden
document.querySelector('[data-number-only]')
.addEventListener('input', function(){

// Aktuelle Eingabe abholen
var value = this.value;

// Mittels Regex-Replace werden alle Nicht-Ziffern entfernt
value = value.replace(/\D/g, '');

// Aktuelle Eingabe überschreiben mit der gefilterten Eingabe
this.value = value;
});

Voilà! Dies funktioniert in allen Browser und mobilen Geräten mit jeglichen Möglichkeiten von Copy-and-Paste und Autocomplete, weil immer schön abgewartet wird, bis sich der Wert im Textfeld befindet.

Vorsicht: Per Browser-Konsole könnte ein/eine Nutzer/-in theoretisch den Wert programmatisch setzen, wodurch das im Beispiel verwendete “input”-Event nicht ausgelöst wird. Solche forcierten Falscheingaben sollten natürlich grundsätzlich mithilfe serverseitiger Validierung verhindert werden.

Tipp: Damit auf Geräten (insb. mobile Geräte) die Zahlentastatur forciert wird, kann das folgende Attribut hinzugefügt werden:

<input data-number-only inputmode="numeric" />

Geschrieben von:
Raphael Ulrich, Frontend-Entwickler bei der raffiniert media AG

Bleib mit unserem Newsletter auf dem Laufenden

Hast du eine Idee?

Nur keine scheu! Schreib uns.