ganischou: Formularvaldierung client-/serverseitig per javascript&PHP

Hallo JavaScript und PHP Cracks

Ich bin am verzweifeln und mir läuft die Zeit davon. Am nächsten Mittwoch (14.Jan.2009) habe ich meine Abschlussprüfung für eine Web-Weiterbildung. Leider ist javascript und PHP nicht gerade mein Ding. Mein Problem: Für die Prüfung muss als Vorbereitung eine fiktive WebSeite erstellt werden (basierend darauf werden zusätzliche Prüfungsaufgaben gestellt),welche auch ein Formular enthält.

Das Formular muss sowohl client-, als auch serverseitig validiert werden per RegExp.

Was wird validiert: Vorname Nachname Strasse PLZ Ort E-Mail Telefon (höchst wahrscheinlich wir an der Prüfung auch noch eine Validierung eines erweiterten Formulars verlangt,d.h. Validierung von checkboxen usw.

Das besondere am Formular: -Französische Zeichen müssen erlaubt sein -PLZ max 5 Zahlen -Telefon: nur Zahlen, Leerschläge, +,/ und ()

-bei falscher Eingabe soll der Feldhintergrund ROT werden und ein informativer Text NEBEN dem Formularfeld ebenfalls in ROTER Farbe erscheinen (dabei sind zwei verschiedene Hinweistexte vorgesehen: 1x für ein leeres Feld und 1x für nicht erlaubte Zeichen) -Bei korrekter Eingabe wird Formularfeld GRÜN -Die Validierung soll sowohl beim verlassen eines Textfeldes, als auch beim Versenden des Formulars erfolgen

folgendes Javascript habe ich aus einer Lektion, welches glaube ich ziemlich gut als Vorlage dienen könnte. Validierung erfolgt aber mit alertboxen, welche ich  eben nicht will!

// JavaScript Document
//Author Andreas Grosse

//-------Formularvalidierung mit Anwendung von Regulaeren Ausdrücken-----//

//----Überprüfung beim Verlassen der Formularfelder onblur---//
        function formcheck()
{
 /*definition zeichensatz utf-8*/
 document.charset = "utf-8";

 /*definition errormeldung*/
 /*errormeldung werden in seperatem array gespeichert*/
 var error = new Array();
 /*anzahl fehler festhalten, d.h. sie werden nummeriert für die schlaufe array beginnt dabei immer mit 0 gleich 1.feld*/
 var anzahlfehler = 0;

 /*variable vordefinierter ausgabesatz als einleitung fehlender, fehlerhaften formularfeldeingaben*/
 var ausgabe = "Fehlerhafte Eingabe in folgenden Feldern:\n";

 /*defintionen für reguläre ausdrücke
 http://de.selfhtml.org/javascript/objekte/regexp.htm
 definitionen, d.h. welche ausdrücke erlaubt sind, findet immer zwischen zwei // statt*/
 /* das hausdächli ^ (alt + ^ + spacebar) bedeutet 1. buchstaben*/
 /*alles was ich zulassen will für den 1. buchstabe steht innerhalb der eckigen klammern*/
 /* + bedeutet es muss am anfang eines dieser zeichen vorkommen*/
 /* $ zeichen bedeuten das ende der zeichenkette*/
 /* leerzeichen ist \s\*/
 /* * bedeutet das zeichen kann vorkommen, muss aber nicht vorkommen als 1. zeichen*/
 /*definition für feld vor- und nachname*/
 var regText= /^([a-zA-ZüÜäÄöÖéèàçâ])+([a-zA-ZüÜäÄöÖéèàçâ\-\.\s])*$/;

 /*definitioen für feld strasse*/
 /*zusätzlich müssen zahlen erlaubt sein auch an der 1. stelle, z.b. französische strassen*/
 var regStrasse= /^([0-9a-zA-ZüÜäÄöÖéèàçâ])+([0-9a-zA-ZüÜäÄöÖéèàçâ\-\.\s])*$/;

 /*definitioen für feld plz*/
 /*nur 4 - 5 zahlen erlaubt wird mit geschlungenen klammern definiert {4,5} bedeutet min. 4 max 5 zahlen sind erlaubt*/
 var regPLZ= /^[0-9]{4,5}$/;

 /*definitioen für feld telefonfeld*/
 /*zahlen sind erlaubt, abstand(\s), + zeichen, bindestriche, klammern (\( oder \) )*/
 var regTelefon= /^[0-9\s\+\-\(\)]{9,30}$/;

 /*definitioen für feld e-mail*/
 /*zahlen sind erlaubt, als erstes zeichen darf es zahlen, buchstaben oder _ (kein sonderzeichen braucht zur definition keinen backslash)*/
 /*nach 1. oder n. zeichen muss zwingend ein @ kommen*/
 /*am schluss der adresse muss ein punkt kommen, d.h. nach stern backslash punkt *\. */
 var regEmail= /^([a-zA-Z0-9_])+([a-zA-Z0-9_\.\-])*@([a-zA-Z0-9])+([a-zA-Z0-9_\.\-])+\.([a-zA-Z0-9]){2,6}$/;




 /*überprüfung von vorname*/
 /*abrufen von eingabe von feldinhalt per document.getElementById('idname').value; value für wert des feldes */
 var eingabe = document.getElementById('vorname').value;

 /*überprüfung ob überhaupt etwas eingegegben wurde und ob es den defintion der erlaubten zeichen von oben entspricht*/
 /*wenn variable eingabe leer (==null)ist oder den regeln von oben entspricht, d.h. match(regText)*/
 if (eingabe==""||(eingabe.match(regText)==null))
 {
  /*errormeldung für vorname*/
  error [anzahlfehler] = "Vorname";
  anzahlfehler++;


 }


 /*überprüfung von nachname*/
  var eingabe = document.getElementById('nachname').value;

 /*überprüfung ob überhaupt etwas eingegegben wurde und ob es den defintion der erlaubten zeichen von oben entspricht*/
 /*wenn variable eingabe leer (==null)ist oder den regeln von oben entspricht, d.h. match(regText)*/
 if (eingabe==""||(eingabe.match(regText)==null))
 {
  /*errormeldung für nachname*/
  error [anzahlfehler] = "Nachname";
  anzahlfehler++;


 }

 /*überprüfung von strasse*/
  var eingabe = document.getElementById('strasse').value;

 /*überprüfung ob überhaupt etwas eingegegben wurde und ob es den defintion der erlaubten zeichen von oben entspricht*/
 /*wenn variable eingabe leer (==null)ist oder den regeln von oben entspricht, d.h. match(regText)*/
 if (eingabe==""||(eingabe.match(regStrasse)==null))
 {
  /*errormeldung für strasse*/
  error [anzahlfehler] = "Strasse";
  anzahlfehler++;


 }

 /*überprüfung von PLZ*/
  var eingabe = document.getElementById('plz').value;

 /*überprüfung ob überhaupt etwas eingegegben wurde und ob es den defintion der erlaubten zeichen von oben entspricht*/
 /*wenn variable eingabe leer (==null)ist oder den regeln von oben entspricht, d.h. match(regText)*/
 if (eingabe==""||(eingabe.match(regPLZ)==null))
 {
  /*errormeldung für PLZ*/
  error [anzahlfehler] = "PLZ";
  anzahlfehler++;


 }

 /*überprüfung von ort*/
  var eingabe = document.getElementById('ort').value;

 /*überprüfung ob überhaupt etwas eingegegben wurde und ob es den defintino der erlaubten zeichen von oben entspricht*/
 /*wenn variable eingabe leer (==null)ist oder den regeln von oben entspricht, d.h. match(regText)*/
 if (eingabe==""||(eingabe.match(regText)==null))
 {
  /*errormeldung für ort*/
  error [anzahlfehler] = "Ort";
  anzahlfehler++;


 }

 /*überprüfung von email*/
  var eingabe = document.getElementById('email').value;

 /*überprüfung ob überhaupt etwas eingegegben wurde und ob es den defintino der erlaubten zeichen von oben entspricht*/
 /*wenn variable eingabe leer (==null)ist oder den regeln von oben entspricht, d.h. match(regText)*/
 if (eingabe==""||(eingabe.match(regEmail)==null))
 {
  /*errormeldung für email*/
  error [anzahlfehler] = "E-Mail";
  anzahlfehler++;


 }

 /*überprüfung von telefonnummer*/
  var eingabe = document.getElementById('telefon').value;

 /*überprüfung ob überhaupt etwas eingegegben wurde und ob es den defintino der erlaubten zeichen von oben entspricht*/
 /*wenn variable eingabe leer (==null)ist oder den regeln von oben entspricht, d.h. match(regText)*/
 if (eingabe==""||(eingabe.match(regTelefon)==null))
 {
  /*errormeldung für telefonnummer*/
  error [anzahlfehler] = "Telefonnummer";
  anzahlfehler++;


 }

 /*falls fehler vorhanden, zeige meldung an*/

 if (anzahlfehler > 0)

 {

  for (i=0; i<anzahlfehler; i++)
 {
  ausgabe += error[i] + "\n"; /* "\n" steht für einen zeilenumbruch*/
 }

 alert (ausgabe);






 /*sicherstellen, dass formular nicht doch verschickt wird benutz man return false*/
 return false;
 }




}

zugehörendes HTML:

<!--beginn des kontaktformulars-->
<form id="formular" name="formular" method="post" action="" onsubmit="return formcheck ()">
<fieldset>
  <legend>Personalien</legend>

  <label for="vorname" >Vorname: </label>
  <input type="text" name="vorname"id="vorname" accesskey="v" tabindex="1" onblur="formcheck()"/>
 <span style="color:#FF0000;visibility:hidden" id="errVorname">Bitte tragen Sie Ihren Vornamen ein!</span>

  <label for="nachname">Nachname:  </label>
  <input type="text" name="nachname" id="nachname" accesskey="n" tabindex="2" onblur="formcheck()" />
  <span style="color:#FF0000;visibility:hidden" id="errNachname">Bitte tragen Sie Ihren Nachnamen ein!</span>

  <label for="strasse">Strasse:</label>
  <input type="text" name="strasse" id="strasse" accesskey="s" tabindex="3" onblur="formcheck()" />
   <span style="color:#FF0000;visibility:hidden" id="errStrasse">Bitte tragen Sie die Strasse ein!</span>

  <label for="plz">PLZ:</label>
  <input type="text" name="plz" id="plz" accesskey="p" tabindex="4" onblur="formcheck()"/>
   <span style="color:#FF0000;visibility:hidden" id="errPlz">Bitte tragen Sie die PLZ ein!</span>

  <label for="ort">Ort:</label>
  <input type="text" name="ort" id="ort" accesskey="o" tabindex="5" onblur="formcheck()"/>
 <span style="color:#FF0000;visibility:hidden" id="errOrt">Bitte tragen Sie den Ort ein!</span>

  <label for="email">E-Mail:</label>
  <input type="text" name="email" id="email" accesskey="e" tabindex="6" onblur="formcheck()"/>
  <span style="color:#FF0000;visibility:hidden" id="errEmail">Bitte tragen Sie eine E-Mail Adresse ein!</span>

  <label for="telefon">Telefon:</label>
  <input type="text" name="telefon" id="telefon" accesskey="t" tabindex="7" onblur="formcheck()" />
   <span style="color:#FF0000;visibility:hidden" id="errTelefon">Bitte tragen Sie Ihre Telefonnummer ein!</span>

  <label for="senden"></label>
  <input type="submit" name="Submit" value="Senden" tabindex="8" />

  </fieldset>
</form>

Nur, wie gebe ich die Fehlermeldungen neben den Textfeldern aus (getElementById??? und ansprechen von Errormeldungen errErrorname) und formatiere die Textfelder entsprechend der Eingabe (falsch=rot, richtig=grün). Von der serverseitigen Validierung habe ich noch keine Vorlage.

Zudem ist ein PHP-Mailversand vorgesehen. Die Angaben im Mail müssen pro Tag in einem speziellen Ordner als CSV-Dateien gespeichert werden,UNIX-Zeitstempel als Dateiname. Als Routine sollen alle Dateien die älter als 30Tage sind gelöscht werden.Die Routine kann durch Anklicken einer Schaltfläche auf einer Seite ausgelöst werden.

Ich weiss, dass ist verdammt viel was ich verlange, leider habe ich kaum noch Zeit für die Vorbereitung neben 100% Berufstätigkeit! Bitte helft mir.Wenn jemand meinen Hilferuf hört, bin ich im zu tiefst dankbar!

Grüsse

Andi

  1. ... Ja das ist etwas viel. Ich habe dein Beitrag überflogen und kann dir hier nur einen Theoretischen Ansatz in Stichpunkten bieten, der vielleicht auch nicht unbedingt das Ideal ist:

    In JavaScript:

    • Event onsubmit zur Kontrolle der Validation
    • Funktion zur Validation mit Argumenten "Pattern" und "Fehlermeldung" und Elementreferenz. Die Funktion prüft den Wert des Feldes und fügt ggf. eine Klasse "error" zu dessen Container (z.B. DIV um INPUT) und einen neuen Knoten mit der Fehlermeldung ein. CSS formatiert die Meldung dann rot oder wie du willst. Ist ein Funktionsaufruf zum Schluss gekommen, dass ein Feld falsch befüllt ist, so wird das Formularsenden verhindert.

    In PHP:
    Da machst du dass dann ähnlich. Im Fehlerfall wird dann per PHP die Klasse und die Meldung zu Text hinzugefügt. Gesendete Werte in $_POST musst du auch wieder in die Felder legen.
    Zum Schluss muss alles noch per mail() versandt werden. Achtung: SPAM sollte vorgesorgt sein.

    Grüße
    Timbo

  2. Mahlzeit ganischou,

    Ich bin am verzweifeln und mir läuft die Zeit davon. Am nächsten Mittwoch (14.Jan.2009) habe ich meine Abschlussprüfung für eine Web-Weiterbildung. Leider ist javascript und PHP nicht gerade mein Ding.

    1. ketzerische Frage: Wieso machst Du dann eine entsprechende Weiterbildung?

    Nur, wie gebe ich die Fehlermeldungen neben den Textfeldern aus (getElementById??? und ansprechen von Errormeldungen errErrorname) und formatiere die Textfelder entsprechend der Eingabe (falsch=rot, richtig=grün).

    Indem Du ihnen je nach Vorhandensein von Fehlern die entsprechenden Klassen - für die natürlich entsprechende Formatierungsanweisungen definiert werden - zuweist. Beispiel:

    <style type="text/css">  
    [code lang=css]input.error {  
      background-color: #fcc;  
    }  
    input.ok {  
      background-color: #cfc;  
    }  
    span.error {  
      color: #f00;  
      visibility: visible;  
    }  
    span.ok {  
      visibility: hidden;  
    }
    

    </style>
    ...
    <label for="vorname">Vorname: </label>
    <input type="text" name="vorname" id="vorname" accesskey="v" tabindex="1" onblur="formcheck()">
    <span class="ok" id="errVorname">Bitte tragen Sie Ihren Vornamen ein!</span>
    [/code]

    Wenn Du den Eingabefelder und den <span>s jetzt je nach Ergebnis der Auswertung die Klasse "error" oder "ok" zuweist, sollte es wie gewünscht funktionieren.

    Von der serverseitigen Validierung habe ich noch keine Vorlage.

    2. ketzerische Frage: Du entwickelst also Anwendungen nur mit entsprechenden Vorgaben?

    Ich weiss, dass ist verdammt viel was ich verlange,

    Ja.

    leider habe ich kaum noch Zeit für die Vorbereitung neben 100% Berufstätigkeit!

    3. ketzerische Frage: Fällt Dir das alles jetzt erst ein? Oder werden bei dieser "Weiterbildung" die Fristen immer derart kurz gesetzt? Wenn ersteres zutrifft: wieso lässt Du Dir damit so viel Zeit, wenn Du doch weißt, dass Du diese eigentlich nicht hast?

    MfG,
    EKKi

    --
    sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
  3. Hallo,

    jeder muss mal klein anfangen ... bzgl. php lernst du sehr viel, wenn du im php manual liest! dort findest du alles, was du brauchst, wenn du "php delete files" googlest findest du garantiert bald mal zB wie man datein löscht und unter den befehlen haben leute auch oft beispiel-codes gepostet zusätzlich zu den beispielen, die eh schon dort dabei sind.

    ein einfach nachzuvollziehende anregung zu deiner serverseitigen umsetzung:

    wenn nach dem submit ein php-script aufgerufen wird, lässt du erstmal alle felder überprüfen. z.B. für "telefon". es gibt nach

    import_request_variables("P");

    automatisch für jedes <input> feld eine $variable, die den name trägt des jew. feldes. dann lässt du alle variablen überprüfen, ob sie leer sind oder nicht, wenn sie leer ist, weist du einer $error-variablen einen wert zu (sonst wäre diese variable 0), wodurch dann später NICHT das mail gesendet wird, nichts gespeichert wird etc... sondern dann lässt du noch einmal das Mailformular schreiben, wobei du überall die jeweilige $msg_variable schon reinschreibst. ist sie nicht definiert, wirs sie auch nicht aufscheinen. dort, wo du bereits ein ergebnis hattest, wird dieses auch wieder aufscheinen, weil du $---txt einfügst.

    Siehe beispiel telefon:

    if ($telefon==0) {
    $error=1;
    $telefon_msg="Bitte tragen Sie Ihre Telefonnummer ein!";
    }

    if ($error)
    {
    echo "<input type="text" name="telefon" id="telefon" accesskey="t" tabindex="7" onblur="formcheck()" value="$telefon" /><span style="color:#FF0000;" id="errTelefon">$telefon_msg</span>"
    }
    else
    {
    sendmail();
    speichern_etc();
    }

    scirpt zum löschen von datein ($server_dir musst du vorher einen wert zuweisen ....).

    $fileArray = array();
      foreach (glob($server_dir."/*") as $filename_del) {
        $diff = time() - fileatime($filename_del); // fileatime liefert den Unixtimestamp des letzten Zugriffs auf eine Datei
        if($diff > 3600) // älter als 1 Stunde
        {
          unlink($filename_del);
        }
      }

    1. echo $begrüßung;

      wenn nach dem submit ein php-script aufgerufen wird, lässt du erstmal alle felder überprüfen. z.B. für "telefon". es gibt nach
      import_request_variables("P");
      automatisch für jedes <input> feld eine $variable, die den name trägt des jew. feldes.

      Das sollte man besonders als Anfänger nicht tun. Nicht umsonst ist das Feature register_globals nicht mehr aktiv und ab PHP6 nicht mehr vorhanden. Es gelangen damit nämlich nicht nur die gewünschten Werte als Variablen ins Script sondern alle übertragenen. Wenn man es auch noch unterlässt Variablen vor der Erstverwendung explizit zu initialisieren, hat man schöne Sicherheitslücken.

      import_request_variables("P") ist auch gar nicht notwendig, denn alle (per POST) übertragenen Werte stehen bereits im Array $_POST. Einträge in einem Array unterscheiden sich grundsätzlich nicht von "normalen" Variablen. Die Einträge im $_POST-Array können ohne weitere Maßnahmen sofort verwendet werden. Außerdem sieht man einem $_POST['telefon'] sofort seine Herkunft an, einem $telefon hingegen nicht.

      Siehe beispiel telefon:

      if ($telefon==0) {

      Auf 0 zu prüfen wenn man eine Nicht-Eingabe (Leerstring) testen will ist nicht sehr sinnvoll. Auch dann nicht, wenn PHPs automatische Typkonvertierung diesen Vergleich zulässt. Besser ist es so:

      if (empty($_POST['telefon']))

      $error=1;
      $telefon_msg="Bitte tragen Sie Ihre Telefonnummer ein!";

      Ich nehme für solche Fälle ein Array, beispielsweise $error. Vor allen Prüfungen initialisiere ich es als leeres Array:

      $error = array();

      Wenn für ein Feld eine Meldung auszugeben ist, bekommt $error einen Eintrag

      $error['telefon'] = 'fehlermeldungstext';

      (Sollen mehrere Meldungen abgelegt werden können, kann man das in einem verschachtelten Array tun.)

      }

      if ($error)

      Nach meiner Version:

      if (!empty($error))

      {
      echo "<input type="text" name="telefon" id="telefon" accesskey="t" tabindex="7" onblur="formcheck()" value="$telefon" /><span style="color:#FF0000;" id="errTelefon">$telefon_msg</span>"

      Und da hätten wir das Problem. Wenn angenommenerweise der Name die Prüfung nicht bestanden hat, das Telefon aber schon, wäre $error auch auf 1 gesetzt und $telefon_msg normalerweise nicht vorhanden. Mit register_globals oder import_request_variables() könnte man es aber per Parameterübergabe setzen und schon hast du ungewollten Inhalt in deiner Seite ausgegeben.

      Meine $error-Array-Variante hingegen kann man neben der generellen Befragung mit empty() bei der Ausgabe befragen, ob sie einen Eintrag für Telefon oder Name oder ... enthält und das dann ausgeben.

      echo '<input ... name="telefon"> ';
        if (isset($error['telefon']))
          echo $error['telefon'];

      echo "$verabschiedung $name";