![]() |
Formularauswertung |
|
| |
| E-Mail: |
|---|
Bei Fragen zu diesem Beitrag bitte den Autor des Beitrags kontaktieren!
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.
Vorteil
Nachteile
Vorteil
Nachteile
Vorteil:
Nachteil:
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.
Vorbemerkung: Bei der Entwicklung der nachfolgenden Funktion stand
das
Beispiel
aus den FAQ der Newsgroup
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.
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.
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.
Die Funktion erwartet drei Parameter:
sender), this
ist in der Regel die richtige Wahl,myarray),
sowie Informationen darüber, was jeweils geprüft werden soll und
die entsprechende Fehlermeldung,err_hd).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 |
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:
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.
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)">
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;
}
}
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
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.
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.
Die folgenden Stellen werden empfohlen, um das obige Beispiel besser zu verstehen, oder um weitere Möglichkeiten und Details zu erfahren.
SELFHTML:
Formulareingaben überprüfen
SELFHTML:
Reguläre Ausdrücke
SELFHTML:
RegExp-Objekt
Prüfung
von E-Mail-Syntax über reguläre Ausdrücke