Teil von SELFHTML aktuell Teil von Artikel Teil von JavaScript

Formularauswertung

nach unten Dieter Raber
nach unten Hinweise zum Thema
nach unten Beispiel mit Erläuterungen
nach unten Weiterführende Links

Dieter Raber

E-Mail: E-Mail d.raber@gmx.net

Bei Fragen zu diesem Beitrag bitte den Autor des Beitrags kontaktieren!

nach obennach unten

Hinweise zum Thema

Formulare kann man grundsätzlich auf dreierlei Art auswerten, nämlich clientseitig, serverseitig und mit einer Kombination beider Möglichkeiten. Bei der clientseitigen Auswertung kommt in der Regel Javascript zum Einsatz, auf der Serverseite beispielsweise PHP, ASP oder Perl.

Vor- und Nachteile der Validierung

Allgemein

Vorteil

Nachteile

Clientseitige Prüfung mit Javascript

Vorteil

Nachteile

Serverseitige Prüfung

Vorteil:

Nachteil:

Schlussfolgerung

Wenn eine Validierung nicht wirklich wichtig ist, sollte man sich fragen, ob man nicht ganz darauf verzichtet. Ansonsten ist es eine gute Idee, beide Systeme zu kombinieren, d.h. als Erstfilter kommt Javascript zum Einsatz, wenn dieses abgeschaltet ist, greift die serverseitige Lösung. Eine reine Javascript-Lösung für wichtige Daten erscheint nur sinnvoll, wenn etwa in einem Intranet die Rechnerumgebung des Benutzers genau bekannt ist.

Modulare Validierung mit JavaScript

Vorbemerkung: Bei der Entwicklung der nachfolgenden Funktion stand das deutschsprachige Seite Beispiel aus den FAQ der Newsgroup deutschsprachige Seite de.comp.lang.javascript Pate.

Wer häufig Formulare in Webseiten einsetzt, wird sich ein Script wünschen, das konfigurierbar ist, also immer wieder verwendet werden kann, ohne dass an der eigentlichen Funktion etwas geändert werden muss. Im nachfolgenden Beispiel wird ein solches Script vorgestellt. Das Beispiel ist in Javascript geschrieben, kann aber auch ohne Probleme in eine serverseitige Sprache übersetzt werden. Der Aufbau ist modular, d.h. die einzelnen Blöcke nehmen unabhängig voneinander verschiedene Prüfungen vor. Es kann jederzeit durch eigene Blöcke erweitert werden.

Was leistet das Script?

Neben den Standardtests beherrscht das Script auch einige außergewöhnliche Aufgaben. Im Einzelnen kann es

Die Überprüfung mit einem regulären Ausdruck ermöglicht es, eigene Suchkriterien festzulegen. Beispielsweise könnten in einem Feld nur Begriffe erlaubt sein, die aus bestimmten Zeichen bestehen, etwa Benutzernamen. Der passende reguläre Ausdruck wird in den entsprechenden Teil der Konfiguration eingetragen.

Die beiden letzten Teile sind eigentlich eine Mischung zwischen Validierung und Korrektur. Die Preisprüfung arbeitet so, dass Eingaben in der Form 10,--, 10,- oder 10 einfach umgewandelt werden zu 10,00. Bei unklaren Angaben wie 10,0, 10,000, bei denen das Komma möglicherweise falsch gesetzt wurde, wird eine Fehlermeldung produziert.Namen werden automatisch korrigiert, so werden lieschen müller zu Lieschen Müller, marquis de sade zu Marquis de Sade und auch d'Artagnan kommt zu seinem Recht. Weitere Besonderheiten in Namen lassen sich in ein Array eintragen, aber es gibt auch einen Punkt, wo dieser Teil der Funktion passen muss.

Erweitern der Funktion

Die Funktion kann jederzeit durch zusätzliche Prüfungen, beispielsweise eine Datumsformatierung, erweitert werden. Ich hatte auch eine Korrektur für Namen wie MacDonald oder DiCaprio in Erwägung gezogen. Es zeigte sich aber schnell, dass das sehr problematisch, wenn nicht unmöglich sein würde, da davon auch unweigerlich Namen wie Machiavelli oder Dillinger betroffen wären. Bei Erweiterungen muss man vor allem darauf achten, dass alle Teile unabhängig voneinander arbeiten.

Konfiguration

Die Funktion erwartet drei Parameter:

Wird der Parameter err_hd nicht gesetzt, lautet die Standardüberschrift "Folgende Fehler sind aufgetreten:".

Beispiel einer Konfiguration:

  var msg_1 = 'Fehler:';

  var var_1 = new Array()
  var_1[0] = new Array('name_1','check_1','fehlermeldung_1',/regexp_1/);
  var_1[1] = new Array('name_2','check_2','fehlermeldung_2','');

Erläuterung:

Parameter Beispiel Beschreibung
name_n strasse das Attribut name des Elementes, das geprüft werden soll
check_n e die Prüfung, die erfolgen soll
fehlermeldung_n Sie haben keine Straße eingetragen Fehlermeldung für das betreffende Element
regexp_n [0-9A-Za-z]{3,16} regulärer Ausdruck
msg_1 Es sind Fehler aufgetreten eigene Überschrift für die Fehlermeldung

Bei einer nach Prüfung nach r muss der reguläre Audruck ohne Anführungszeichen zwischen Schrägstrichen stehen (/[0-9A-Za-z]{3,16}/), in allen anderen Fällen müssen an dieser Stelle leere Anführungszeichen ('') notiert werden.

Mögliche Werte für check_n:

Wert Merkwort Prüfung
e empty das Element darf nicht leer sein
n number das Element muss eine Zahl sein
m mail eine Emailadresse muss formal richtig sein
r regexp der Wert soll ein bestimmtes Muster haben
p price der Wert soll in der Form "10,00" sein (mit Komma)
p. price_dot der Wert soll in der Form "10.00" sein (mit Punkt)
c capitalize Namen sollen korrigiert werden

Für eine Prüfung nach mehreren Kriterien muss das entsprechende Element mehrfach aufgeführt werden. Bei einem Preischeck wird automatisch überprüft, ob der Wert eine Zahl ist. Für die Namenskorrektur wird keine Fehlermeldung benötigt. Bei einer Prüfung von Emailadressen, Zahlwerten und Preisen, sowie bei der Anwendung eines regulären Ausdrucks werden die Werte in der Fehlermeldung mit ausgegeben. Den einzelnen Fehlern wird ein · und ein Leerzeichen vorangestellt und die Meldung mit alert() angezeigt.
Das Ergebnis sieht etwa so aus: Popup-Seite Fehlermeldung

Soll die Datei mit der Funktion für mehrere Formulare im gleichen Projekt genutzt werden, müssen entsprechend viele Konfigurationsarrays mit verschiedenen Namen angelegt werden.

Einbindung und Aufruf der Funktion

Natürlich muss das Script selbst in die HTML-Seite eingebunden werden:

  <script type="text/JavaScript" src="form_validation.js"></script>

Aufgerufen werden kann es mit zwei oder drei Parametern:

  <form name="form_name" id="form_name" onSubmit="return validate(this,var_1)">
  <form name="form_name" id="form_name" onSubmit="return validate(this,var_1,msg_1)">

nach obennach unten

Beispiel mit Erläuterungen

Beispiel

Popup-Seite Anzeigebeispiel: So sieht's aus

Die Konfiguration kann entweder direkt im Script stehen oder zwischen entsprechende script-Tags in der HTML-Datei notiert werden.

var msg_1 = 'Fehler:';

var var_1 = new Array()
var_1[0] = new Array('ort','e','Sie haben keinen Wohnort angegeben','');
var_1[1] = new Array('email','m','ist keine gültige Emailadresse','');
var_1[2] = new Array('anzahl','n','ist keine Zahl','');
var_1[3] = new Array('anzahl','e','Sie haben keine Anzahl angegeben','');
var_1[4] = new Array('einzelpreis','p','ist kein gültiger Preis','');
var_1[5] = new Array('benutzer','r','Der Benutzername muss aus 8 Zeichen bestehen',/\w{8}/);
var_1[6] = new Array('benutzer','c','','');

Das Script selbst sieht so aus:

function validate(sender,myarray,err_hd) {

var err_msg = !err_hd?new Array('Folgende Fehler sind aufgetreten:\n'):new Array(err_hd+'\n');
var error = false;

for (i=0;i<myarray.length;i++) {
  field = document.forms[sender.name].elements[myarray[i][0]];

/* Block 1 überprüft Felder, die ausgefüllt sein müssen */
  if (myarray[i][1].indexOf('e')>-1) {
    if (!field.value) {
      error = true;
      err_msg.push(myarray[i][2]);
    }
  }

/* Block 2 überprüft, ob die Emailadresse formal richtig ist */
  else if (myarray[i][1].indexOf('m')>-1) {
    if (field.value) {
      var usr = "([a-zA-Z0-9][a-zA-Z0-9_.-]*|\"([^\\\\\x80-\xff\015\012\"]|\\\\[^\x80-\xff])+\")";
      var domain = "([a-zA-Z0-9][a-zA-Z0-9._-]*\\.)*[a-zA-Z0-9][a-zA-Z0-9._-]*\\.[a-zA-Z]{2,5}";
      var regex = "^"+usr+"\@"+domain+"$";
      var myrxp = new RegExp(regex);
      var check = (myrxp.test(field.value));
        if (check!=true) {
          error=true;
          err_msg.push(field.value+" "+myarray[i][2]);
        }
      }
    }

/* Block 3 überprüft Felder, deren Wert eine Zahl sein muss */
  else if (myarray[i][1].indexOf('n')>-1) {
    var num_error = false;
    if(field.value) {
      var myvalue = field.value;
      var num = myvalue.match(/[^0-9,\.]/gi)
      var dot = myvalue.match(/\./g);
      var com = myvalue.match(/,/g);
      if (num!=null) {
        num_error = true;
      }
      else if ((dot!=null)&&(dot.length>1)) {
        num_error = true;
      }
      else if ((com!=null)&&(com.length>1)) {
        num_error = true;
      }
      else if ((com!=null)&&(dot!=null)) {
        num_error = true;
      }
    }
    if (num_error==true) {
        error = true;
        err_msg.push(myvalue+" "+myarray[i][2]);
    }
  }

/* Block 4 überprüft Wert anhand eines regulären Audrucks auf bestimmte Muster */
  else if (myarray[i][1].indexOf('r')>-1) {
    var regexp = myarray[i][3];
    if (field.value) {
      if (!regexp.test(field.value)) {
        error = true;
        err_msg.push(field.value+" "+myarray[i][2]);
      }
    }
  }

/* Block 5 überprüft Felder, die als Preis formatiert sein müssen, ändert die Formatierung eventuell */
  else if (myarray[i][1].indexOf('p')>-1) {
    var myvalue = field.value;
    var reg = /,-{1,}|\.-{1,}/;
    var nantest_value = myvalue.replace(reg,"");
    var num = nantest_value.match(/[^0-9,\.]/gi)
    sep = myarray[i][1].substr(1,1)?myarray[i][1].substr(1,1):',';
    if (field.value) {
      var myvalue = field.value.replace(/\./,',');
      if (myvalue.indexOf(',')==-1) {
        field.value = myvalue+sep+'00';
      }
      else if (myvalue.indexOf(",--")>-1) {
        field.value = myvalue.replace(/,--/,sep+'00');
      }
      else if (myvalue.indexOf(",-")>-1) {
        field.value = myvalue.replace(/,-/,sep+'00');
      }
      else if (!myvalue.substring(myvalue.indexOf(',') + 2)) {
        error=true;
        err_msg.push(field.value+" "+myarray[i][2]);
      }
      else if (myvalue.substring(myvalue.indexOf(',') + 3)!='') {
        error=true;
        err_msg.push(field.value+" "+myarray[i][2]);
      }
      else if (num!=null) {
        error=true;
        err_msg.push(field.value+" "+myarray[i][2]);
      }
    }
  }

/* Block 6 überprüft Namensfelder, und korrigiert evtl. die Groß-/Kleinschreibung */
  else if (myarray[i][1].indexOf('c')>-1) {
    var noble = new Array("de","von","van","der","d","la","da","of");
    var newvalue='';
    var myvalue = field.value.split(/\b/);
    for (k=0;k<myvalue.length;k++) {
      newvalue+= myvalue[k].substr(0,1).toUpperCase()+myvalue[k].substring(1);
    }
    for(k=0;k<noble.length;k++){
      var reg = new RegExp ("\\b"+noble[k]+"\\b","gi");
      newvalue = newvalue.replace(reg,noble[k]);
    }
    field.value = newvalue;
  }
}

/* im Fehlerfall werden hier die gesammelten Fehlermeldungen verarbeitet und angezeigt. Wenn das
Formular ohne Beanstandung ist, wird es übertragen */
  if (error) {
    err_msg = err_msg.join('\n\xB7 ');
    alert(err_msg);
    return false;
  }
  else {
    return true;
  }
}

Erläuterung:

Innerhalb der Funktion wird zunächst die Variable error_msg für die Fehlermeldungen initialisiert. Wenn keine eigene Überschrift error_hd angegeben wurde, besteht die Meldung bis dahin aus der Standardüberschrift.

Das Array var_1 durchläuft eine for-Schleife solange, bis alle Werte geprüft sind. In der nächsten Zeile (field = ..) wird aus dem Wert name aus var_1 das jeweilige Eingabefeld ermitttelt. Eine bedingte Anweisung mit if/else verteilt dann die Werte entsprechend des zweiten Parameters e, n, m, r, p, p. oder c auf die einzelnen Prüfungen.

Im ersten Block wird geprüft, ob ein Element einen Wert enthält; if(!field.value) bedeutet, wenn der Wert nicht existiert bzw. leer ist. Wenn die Bedingung zutrifft, wird error auf true gesetzt und die Fehlermeldung wandert in das Array error_msg. Das gleiche Muster zieht sich durch alle Blöcke.

In Block zwei wird eine Emailadresse mithilfe eines regulären Ausdrucks auf ihre formale Gültigkeit überprüft. Der reguläre Ausdruck stammt von Christian Kruse und Antje Hofmann aus dem Beitrag Seite Prüfung von E-Mail-Syntax über reguläre Ausdrücke.

Block drei schaut sich Zahlen genauer an. Mit den Variablen num, dot und com wird getestet, ob es in dem betreffenden Wert irgend etwas außer Ziffern, Kommas und Punkten gibt. Die nachfolgende if/else-Bedingung stellt zudem sicher, dass der Wert höchstens ein Komma oder einen Punkt enthält. Diese Prüfung ist wesentlich aufwendiger als ein Test mit isNaN(), hat demgegenüber aber den Vorteil, dass sie auch Kommas als Dezimaltrennzeichen akzeptiert.

Im vierten Block wird der eingebene Wert ebenfalls mit einem regulären Ausdruck und der Methode test() auf ein bestimmtes Muster hin untersucht. Wenn das Suchmuster nicht gefunden wird, wird eine entsprechende Fehlermeldung ausgegeben.

Die Preisprüfung/-korrektur in Block fünf arbeitet zum Teil ähnlich wie die Prüfung auf Zahlen. Ein temporärer Wert nantest_value, von dem eventuell vorhandene ",--" und ähnliches abgeschnitten wurden, darf danach nur noch Zahlen enthalten. Anschließend finden die verschiedenen Umwandlungen in das gewünschte Format statt. Wurde als Parameter p. (price_dot) angegeben, ändert das die Variable sep entsprechend ab. In den letzten beiden Fällen der Preisprüfung werden für die nicht eindeutigen Eingaben die entsprechenden Fehlermeldungen vorbereitet.

Die Namenskorrektur in Block sechs ist eigentlich mehr eine Spielerei, aber manchmal ganz nützlich. Zunächst werden erst alle ersten Buchstaben eines Wortes großgeschrieben. Anschließend werden die Adelspräpositionen durch ihre Entsprechungen aus noble augetauscht. Das Array lässt sich natürlich beliebig erweitern.

Beachten Sie:

Das Script wurde getestet unter Debian Linux testing mit Mozilla 1.2.1, Konqueror 3.1, Opera 6.11 und Netscape 4.77. Mit Mozilla, Netscape und Konqueror gab es keine Probleme. Opera kam mit der Namenskorrektur nicht zurecht und verwandelte alle Buchstaben bis auf die Adelstitel in Großbuchstaben. Unter Windows XP professionell ohne Service Pack 1 wurde getestet mit Mozilla 1.2.1, Internet Explorer 6.0, Netscape 4.08, Opera 6.04 und Opera 7 beta. Es funktionierte reibungslos in Mozilla, Netscape und Internet Explorer. Opera 7 verhielt sich wie im Test wie unter Linux, Opera 6.04 ersetzte bei der Namenskorrektur nur den ersten Buchstaben im String.

nach obennach unten

Weiterführende Links

Die folgenden Stellen werden empfohlen, um das obige Beispiel besser zu verstehen, oder um weitere Möglichkeiten und Details zu erfahren.

bereichsübergreifende Seite SELFHTML: Formulareingaben überprüfen
bereichsübergreifende Seite SELFHTML: Reguläre Ausdrücke
bereichsübergreifende Seite SELFHTML: RegExp-Objekt

Seite Prüfung von E-Mail-Syntax über reguläre Ausdrücke

Teil von SELFHTML aktuell Teil von Artikel Teil von JavaScript

© 2007 bereichsübergreifende Seite Impressum