Beispiel - Ein JavaScript Formular
Formulare per JavaScript benutzerfreundlicher zu gestalten ist eine sehr gute Idee. Nichts ist verwirrender und nerviger als ein Formular auszufüllen und nach dem Abschicken mehrmals zurück zur Formularseite geschickt zu werden weil man Etwas vergesssen hat oder die Eingabe falsch formatiert war. Es ist um einiges einfacher, diese Meldung vor dem Abschicken des Formulars zu erhalten, und dadurch Ladezeiten und Servertraffic zu sparen.
Formulare und JavaScript - viel Macht bringt auch viel Verantwortung
Wir können es dem Besucher einfacher machen Formulare auszufüllen, indem wir diese per JavaScript um Funktionalität bereichern. Allerdings müssen wir einige Fallen beachten:
- Die Formulareingaben müssen zusätzlich auf dem Server überprüft werden, da ansonsten Besucher ohne JavaScript unzulässige Werte abschicken können.
- Es gibt kein "Formularskript", das alle Probleme für uns löst. Jedes Formular ist einzigartig und folgt seinen eigenen Prüfregeln und Ablauf. Skripte, die versuchen jede Möglichkeit vorherzusehen sind meistens viel zu groß und komplex. Eine einfachere Möglichkeit ist nur die Teile zu verwenden, die wirklich benötigt werden. Das macht es uns einfacher, Änderungen vorzunehmen und führt zu schnelleren Webseiten.
- Wir sollten versuchen, die gleiche Prüftechnik im Browser und auf
dem Server zu verwenden. Obwohl wir Klassen zum Überprüfen
per JavaScript verwenden könnten, ist das keine gute Idee, da
<input class="required" ... />
nicht an den Server geschickt wird, und damit den Arbeitsaufwand verdoppelt.
Unser HTML-Formular
<form action="formsend.php" method="post" onsubmit="return checkform(this);"> <p> <input type="hidden" name="required" id="required" value="name,surname,email,tac,msg" /> <label for="name" >Name</label> <input type="text" name="name" id="name" /><span>*</span> </p> <p> <label for="surname">Surname</label> <input type="text" name="surname" id="surname" /><span>*</span> </p> <p> <label for="email">Email</label> <input type="text" name="email" id="email" /><span>*</span> </p> <p> <label for="phone">Phone number</label> <input type="text" name="phone" id="phone" /> </p> <p> <input type="checkbox" name="tac" id="tac" /> I have read the <label for="tac">terms and conditions</label> and agree with them.</label><span>*</span> </p> <p> <label for="msg">Your message</label> <textarea name="msg" id="msg"></textarea><span>*</span> </p> <p> <input type="submit" value="Send information" /> </p> </form>
Das ist ein standardkonformes Formular, welches label
Elemente
verwendet, um es blinden Besuchern, oder solchen, die Schwierigkeiten haben einen
kleinen Haken einer Tickbox hinzuzufügen, zu vereinfachen.
Zur Überprüfung haben wir ein verstecktes Feld
eingefügt, das die Namen aller Pflichtfelder auflistet. Diese Art der
Übergabe der Pflichtfelder hat sich seit Jahren als Quasi-Standard eingebürgert.
Die Prüfregeln lauten wiefolgt:
- Stelle sicher, dass jedes Pflichtfeld ausgefüllt oder - im Falle der "Terms and Conditions" - aktiviert ist.
- Stelle sicher, das die übergebene Email im korrekten Format ist.
Die meisten Formularskripte führen die fehlerhaften Pflichfelder in einer
Warnung, einem alert
auf. Das kann sinnvoll sein, wenn das Formular
sehr groß und komplex ist, wirkt aber unbeholfen und ist häßlich. Wir
werden einen anderen Weg gehen: Jedes fehlerhafte Pflichtfeld soll rot eingefärbt
und mit einem Warnungsbild versehen werden.
Weiterhin soll überhalb des "Abschicken" Knopfes eine Warnung erscheinen, die dem Besucher erklärt, dass Fehler vorgekommen sind.
Unser checkform()
Skript
Zuallererst definieren wir alle Variablen, die wir verwenden wollen. Dann
überprüfen wir, ob ein Feld mit der ID required
besteht, und lesen die Namen der Pflichtfelder aus, indem wir den Inhalt dieses
Feldes am Komma aufteilen.
function checkform(of) { var reqfields,em,i,f,ty; if(document.getElementById('required')) { reqfields=document.getElementById('required').value.split(',');
Dann überprüfen wir, ob ein Element mit der ID errormessage
besteht und löschen dieses. Dieses Element ist unsere Fehlermeldung,
die später erstellt und beschrieben wird. Das
Löschen ist notwendig, um mehreren Meldungen vorzubeugen.
if(document.getElementById('errormsg')){ em=document.getElementById('errormsg'); em.parentNode.removeChild(em); }
Dann beginnen wir durch die einzelnen Pflichtfelder zu gehen und überprüfen, ob der vorhergegangene Knoten auf der gleichen Ebene ein Bild ist. Falls dem so ist, löschen wir das Bild, ebenfalls um mehrere Bilder zu vermeiden. Wir löschen die Hintergrundfarbe des Pflichtfeldes aus dem gleichen Grund.
for(i=0;i<reqfields.length;i++) { f=document.getElementById(reqfields[i]); if(f.previousSibling && /img/i.test(f.previousSibling.nodeName)){ f.parentNode.removeChild(f.previousSibling); } f.style.background='transparent';
Nun überprüfen wir das Formular. Wir überprüfen, ob das
Pflichtfeld vorhanden ist, und um welche Art von Formularfeld es sich handelt.
Das ist nötig, da man bei Textfeldern das value
Attribut
überprüfen muss, und bei Tickboxen das checked
Attribut. Falls
das Feld einen Fehler aufweist, übergeben wir dessen ID und das
Formular als Objekt an die Funktion adderr
:
if(f){ ty=f.type.toLowerCase(); switch(ty) { case 'text': if(f.value==''){adderr(f.id,of)} if(f.id=='email' && !isEmailAddr(f.value)){ adderr(f.id,fieldnames[f.id],of) } break; case 'textarea': if(f.value==''){adderr(f.id,of)} break; case 'checkbox': if(!f.checked){adderr(f.id,of)} break; /* extend as needed */ } } } }
Das ist schon alles, was die Hauptfunktion angeht. Wir überprüfen,
ob ein Element mit der ID errormsg
vorhanden ist und
geben false
zurück, falls dem so ist. Das stoppt den
onsubmit
Aufruf des Formulars und schickt das Formular nicht an
den Server.
if(document.getElementById('errormsg')) { return false; } }
Das adderr()
Skript
Nun widmen wir uns der Funktion, die ein Bild einfügt und das Feld
einfärbt, wenn es Fehler aufweist. Wir erstellen das Bild als Element und
fügen es vor dem Feld ein, das wir durch die übergebene ID
identifizieren können. Da wir die ID übergeben bekommen,
müssen wir nicht überprüfen, ob das Feld vorhanden ist oder nicht.
Wir färben das Feld ein, indem wir dessen background
Attribut
ändern und geben dem Bild einen Alternativtext und einen Titel.
function adderr(id,of) { var se,i,nli,na; i=document.createElement('img'); i.src='img/alert.gif'; i.alt='Error'; i.title='This field has an error!'; se=document.getElementById(id); se.parentNode.insertBefore(i,se) se.style.background='#fcc';
Nun überprüfen wir, ob das Element mit der ID errormsg
schon vorhanden ist, und erstellen es nötigenfalls. Ein paar weitere Stiländerungen
lassen die Meldung wichtiger erscheinen.
if(!document.getElementById('errormsg')){ var em=document.createElement('p'); em.id='errormsg'; em.style.border='2px solid #c00'; em.style.padding='5px'; em.style.width='20em'; em.appendChild(document.createTextNode('Please enter or change the fields marked with a ')) i=document.createElement('img'); i.src='img/alert.gif'; i.alt='Error'; i.title='This field has an error!'; em.appendChild(i);
Wir gehen durch alle Elemente mit dem Namen input
und
testen, ob es sich bei dem Element um den Abschickknopf handelt. Falls dem so ist,
fügen wir unsere Fehlermeldung vor diesem Element ein.
for(var i=0;i<of.getElementsByTagName('input').length;i++) { nowelm=of.getElementsByTagName('input')[i]; if(/submit/i.test(nowelm.getAttribute('type'))) { var sb=nowelm; break; } } sb.parentNode.insertBefore(em,sb); }
Diese Kondition wird nur beim ersten Fehler ausgeführt.
Letztendlich überprüfen wir, ob die ID des
Elementes email
lautet und testen deren Wert mittels eines
regulären Ausdrucks. Wenn es sich bei dem Wert nicht
um eine Email handelt, fügen wir eine Fehlermeldung hinzu.
if(id=='email' && !isEmailAddr(document.getElementById(id).value)){ pn=document.createElement('p'); pn.appendChild(document.createTextNode('Your email seems to be invalid')) document.getElementById('errormsg').appendChild(pn); } } function isEmailAddr(str) { return str.match(/^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/); }
Das ist Alles, was nötig ist, um unser Formular zu verbessern. Probiere das Beispiel aus, um zu sehen wie das Skript sich verhält.
Selbstversuche
Lade das das HTML Beispiel herunter und versuche Dich sich an einer der folgenden Aufgaben. Folge den Lösungsverweisen um eine mögliche Lösung zu sehen. Die Lösungsbeispiele beinhalten das notwendige JavaScript, was zwar nicht mit den Grundsätzen des barrierefreien JavaScripts übereinstimmt, aber einfacher zu lesen und verstehen ist.
- Ändere das Skript soweit um, dass es anstatt der allgemeinen Fehlermeldung
eine Liste der fehlerhaften Pflichfelder ausgibt. Hole den Namen der Pflichtfelder
aus deren
label
Elementen. Lösung Elementliste. - Verlinke diese Liste zu dem dazugehörigen Formularfeld. Lösung verlinkte Elementliste.