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:

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:

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 Alert 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.

  1. Ä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.
  2. Verlinke diese Liste zu dem dazugehörigen Formularfeld. Lösung verlinkte Elementliste.
Creative Commons License Unless otherwise expressly stated, all original material of whatever nature created by Christian Heilmann and included in this web site and any related pages is licensed under the Creative Commons License.