borisbaer: Javascript-Validierung: Eingaben nach Fehlern überprüfen und entsprechend reagieren

Beitrag lesen

problematische Seite

Hallo Rolf,

  • Ich habe ein Zeichen im Benutzernamen eingetippt und das ganze Formular wird rot. WTF? Du solltest im input-Event nur das Element prüfen, das gerade bearbeitet wird, und Tests wie "mind. 2 Zeichen" im input zu prüfen ergibt keinen Sinn. Ob die Eingabe zu kurz ist, weißt Du erst, wenn der User das Feld verlässt (change-Event). Ob es sinnvoll ist, im blur-Event Validierungen durchzuführen, weiß ich auch nicht. Ich tabbe nur durch's Formular und gleich wird alles rot - das ist ganz schön deprimierend.

ja, so wollte ich es auch nicht lassen. Ist nur zum Testen.

  • Ich wollte Benutzername "Müller" eingeben. → Der Benutzername darf nur alphanumerische Zeichen enthalten. WTF?

Auch hier ... von diesen Regeln sind manche nur Platzhalter, auch sie sind nur zum Testen da. Ich habe leider noch keine RegEx für a-z, a-Z, 0-9, Umlaute, Leerzeichen und was man sonst noch vielleicht erlauben sollte. Wenn man jenseits der alphanumerischen Zeichen geht, dann ergeben sich ja gleich ganz viele Eventualitäten, die man beachten muss. Darum kümmere ich mich später.

  • Deine Password-Reveal Button funktioniert nicht.

Hmm, bei mir geht er. 🤷‍♂️

  1. Du musst nicht die Submit-Buttons suchen und dann deren Form, sondern direkt die Forms. Denn so läufst Du für das sign-up und das sign-in Form zweimal da durch. Gut, dass Du onclick und onkeydown verwendst und nicht addEventListener.
  2. Form-Validation macht man nicht im click-Handler des submit-Buttons, sondern im submit-Event des Forms
form.forEach( node => {
	⋮
	node.onsubmit = e => {

		if ( node.name === 'sign-in' ) {
			if ( !validate( username, [ { name: 'required' } ] ) )
				e.preventDefault();
			if ( !validate( password, [ { name: 'required' } ] ) )
				e.preventDefault();
		}

		if ( node.name === 'sign-up' ) {
			if ( !validate( username, [ { name: 'required' }, { name: 'minlength', param: 2 }, { name: 'maxlength', param: 20 }, { name: 'alphanumeric' }, { name: 'verify' } ] ) )
				e.preventDefault();}
	}
});

Ist das so besser?

  1. Feld-Validation macht man nicht im keydown-Handler eines input-Elements, sondern im input-Event für Sofortprüfungen und im change-Event für Prüfungen beim Verlassen des Feldes.

Was meinst du mit „input-Event für Sofortprüfungen“? Kenne ich leider nicht.

  1. Das erspart Dir dann auch den setTimeout im keydown-Event. Der ist vermutlich drin, damit die FM nicht schon kommt, bevor Du die Taste losgelassen hast...

Andersrum. Damit die Fehlermeldung nicht erst nach dem nächsten Tastenschlag erscheint.

WHOA! Du setzt bei jedem Tastendruck zweimal einen neuen blur-Handler. Aber eben auch erst bei einem Tastendruck. Ohne einen Tastendruck gibt's keinen blur-Handler. Da die verify-Regel bei jedem Tastendruck angestoßen wird, solltest Du an dieser Stelle keine Eventhandler registrieren. Sowas macht man einmal vorneweg. Aber wie auch immer - der fetch sollte nicht im onblur passieren, sondern im change-Event.

Okay, das ist gut zu wissen, danke! Wäre es dann nicht vielleicht sogar besser für die den verify-Check direkt ein onchange in den input zu schreiben? Z.B. onchange="validate( this, [ { name: 'verify' } ] );".

Kennst Du eigentlich unsere Wiki-Artikel zur browsereigenen Validierung in HTML und JavaScript? Die nimmt Dir etliche deiner Probleme automatisch ab, weil sie die Fehlerbehandlung pro Formular durchführt.

Kannte ich noch nicht, danke! Muss ich mir mal genauer anschauen. Sieht jedenfalls vielversprechend aus. Ich wusste z.B. nicht, dass man invalid als Event Listener benutzen kann. Aber kann man hier auch gleich mehrere Fehlermeldungen pro Feld anzeigen lassen? Also z.B. „braucht Großbuchstaben“, „braucht Sonderzeichen“ oder so.

Ein Problem bleibt bei mir zudem noch bestehen. Beim onsubmit-Event muss ja ein preventDefault her. Du siehst, dass ich es oben mehrmals stehen habe. Ich möchte diese Redundanz vermeiden. die validate-Funktion gibt bei mir momentan ein true aus, falls keine Fehler vorliegen und ansonsten false. Wie kann ich das Script so schreiben, dass ich nicht dauernd das e.preventDefault() reinschreiben muss?

Theoretisch müsste ich ja schauen, ob mindestens eine validate-Funktion ein false ausgibt und dann preventDefault() aufrufen. Gehe ich aber z.B. so vor, dass ich schreibe …

if (
	!validate( username, [ { name: 'required' } ] )
		||
	!validate( password, [ { name: 'required' } ] )
)
	e.preventDefault();

… dann funktioniert das Ein- und Ausblenden der Fehlermeldungen nicht mehr richtig …

Grüße
Boris