Posted by on in Tips & Tricks

YAML Formularbaukasten und jQuery Validate

yaml-forms-jquery-validation

Einige die mit dem YAML XHTML/CSS Framework arbeiten, werden inzwischen auch den YAML Formularbaukasten nutzen. Gleichfalls werden viele auch bereits auf die jQuery Javascript Bibliothek setzen.

Ab der Version 3.1 von YAML gibt es den Formularbaukasten, der wie ich finde sehr gut gelungen ist. Im Baukasten enthalten ist auch eine Vorgabe zur Hervorhebung falsch eingegebener Daten, für die Validation der Eingabefelder (Feldprüfung).

Folgend möchte ich anhand eines kleinen Beispiels erläutern, wie man das jQuery Validation Plugin von Jörn Zaefferer und den YAML Formularbaukasten mit dem vorgegebenen Error-Handling gemeinsam nutzen kann. Natürlich kann man das Validation Plugin auch ganz normal einsetzen, nur dann sieht es eben nicht so schön aus.

Eine Beispielseite findet man hier in der Sandbox.

Anpassungen im HTML Code

Grundsätzlich sind nur wenige Anpassungen notwendig. Als Ausgangsdatei dient das YAML-Beispiel Building Forms.

Das <form> Element muss eine ID haben da sonst der jQuery Validator, nach meinen Erfahrungen, nicht immer sauber funktioniert. Folgend ein kleiner Beispiel HTML-Code.

<noscript>
  <!-- 
    Wenn javascript deaktiviert anzeigen. 
    Wenn <noscript> formatiert ist (oft mit rotem Rahmen), 
    ist es unbedingt notwendig per Javascript das Element komplett zu entfernen, 
    da sont meist Rückstände der Formatierung zu sehen sind!    
  -->
  <div>JavaScript muss aktiviert sein um das Formular absenden zu können.</div>
</noscript>

<form method="post" action="myScript.php" class="yform-validate yform" id="myForm">
  <fieldset>
    <legend>Fieldset Title</legend>

    <div class="type-select">
      <label for="testfield">Testfield <sup title="This field is required.">*</sup></label>
      <select disabled="disabled" name="testfield" id="testfield" size="1" class="required" title="custom validation error message">
        <option value="">Please select</option>
        <option value="first">first entry</option>
        <option value="second">second entry</option>
      </select>
    </div>
  </fieldset>

  <div class="type-button">
    <input disabled="disabled" style="display:none;" type="submit" value="Submit" id="submit" name="submit" />
  </div>
</form>

Als ID wurde "myForm" vergeben und bei der Auswahlbox die CSS-Klasse "required" hinzugefügt.

Mit der CSS-Klasse "required" weis das jQuery Validation Plugin das dieses Feld erforderlich ist. Hier sind natürlich noch viele weitere Möglichkeiten gegeben. Lesen Sie hierzu die Dokumentation des Validation Plugins.

Aus Spamschutz-Maßnahmen deaktiviere ich persönlich immer alle Felder mit disabled="disabled" und verstecke den Absende Button mit style="display:none;". Diese aktiviere ich dann später mit Javascript wieder.

Das Validation Script

Das ist jetzt der wichtige Teil um das jQuery Plugin sauber mit den YAML Formularbaukasten zu betreiben. Folgend ein Codebeispiel.

<!-- jQuery selbst laden -->
<script src="/beliebiegerpfad/jquery-1.3.1.js" type="text/javascript"></script> 
<!-- jQuery Validation Plugin laden -->
<script src="/beliebiegerpfad/jquery-validate/jquery.validate.js" type="text/javascript"></script> 
  
<script type="text/javascript">
  $(document).ready(function(){
    
    // Instanz von #myForm für schnelleren DOM-Select
    $myForm = $("#myForm");

    // Verstecke das <noscript> Elemente vollständig 
    $("noscript").hide(); 
    
    // Aktiviere Felder indem man das Attribut disabled entfernt
    $(":input:disabled", $myForm).removeAttr("disabled"); 
    
    // Abesende Button Anzeigen
    $("#submit", $myForm).show();

    // Nun zur eigentlichen Validation
    /* 
     * Erstelle Validation Handler 
     */
    $myForm.validate({
      errorPlacement: function(error, element) {
        element.parent().addClass("error");
        error.prependTo( element.parent() );
      },
      errorClass: "message",
      errorElement: "strong",
      onkeyup: false, // deaktivieren - notwendig wegen errorHandlerContainer 
      onclick: false // deaktivieren - notwendig wegen errorHandlerContainer 
    });
    
    // Das war jetzt der Normale Aufruf und nun der Teil, 
    // der für die YAML-Forms benötigt wird!
    /* 
     * Funktion um Fehlermeldungen an richtiger Stelle anzuzeigen 
     * und wieder entsprechend zu entfernen. 
    */
    var errorHandlerContainer = function(){
      $(this).valid(); // Validiert das aktive Feld (je nach Ereignis - blur, keyup, change)
            
      var $cont = $(this).parent(); // Hole Übergerodnetes Div des Feldes 
      var haserror = $("strong.message:visible", $cont).size(); // Finde Fehler-Nachricht
      if (haserror<1) {
        $cont.removeClass("error"); // Kein Fehler Entferne Error CSS-Klasse.  
      } else {
        $cont.addClass("error"); // Wenn Fehler füge Error CSS-Klasse hinzu.    
      }
    } 
    
    // Prüfe wenn Ereignis blur (gegenteil von focus)
    $(":input", $myForm).blur(errorHandlerContainer); 
    // Prüfe wenn Ereignis keyup
    $("input, textarea", $myForm).keyup(errorHandlerContainer); 
    // Prüfe wenn Ereignis change (selectbox)
    $("select", $myForm).change(errorHandlerContainer); 
  });
  </script>

[Update 24.02.2010]

Im obigen Code gibt es ein paar Fehler beim Hervorheben der invaliden bzw. zurücksetzten der validen Elemente. Das keyup Event legt den Focus in Webkit Browsern lahm, wenn man mit dem Tabulator bei einem noch nicht validen Feld weiter springt. Außerdem ist das entfernen des disabled Attributes auf alle Input-Elemente im Allgemeinen nicht sinnvoll. Folgend ein bedeutend schlankerer Code der Multi-Formular-Fähig ist. Die Validation greift im folgenden Beispiel auf alle Formulare mit der CSS-Klasse "yform-validate".

<!-- jQuery selbst laden -->
<script src="/beliebiegerpfad/jquery-1.3.1.js" type="text/javascript"></script> 
<!-- jQuery Validation Plugin laden -->
<script src="/beliebiegerpfad/jquery-validate/jquery.validate.js" type="text/javascript"></script> 
  
<script type="text/javascript">
  $(document).ready(function(){

    var yformValidation = function() {
      // arbeitet alle Formulare mit der CSS-Klasse "yform-validate" ab.
      $("form.yform-validate").each(function() {
        $myForm = $(this);
    
        // Initialisiere form Validation
        $myForm.validate({
          errorPlacement: function(error, element) {
            // Error Element am Ende der yform Container einfügen
            error.prependTo( element.parent() );
          },
          errorClass: "message",
          errorElement: "strong",
          highlight: function(element, errorClass) {
            // Füge CSS-Klasse "error" im Invaliden yform Container hinzu
            $(element).parent().addClass("error");
          },
          unhighlight: function(element, errorClass) {       
            // Entferne CSS-Klasse "error" im Validen yform Container
            $(element).parent().removeClass("error");
          }
        });
        
      });
    };
  
    // Initialisiere form Validation
    if ( $.isFunction($.fn.validate)) { yformValidation(); }    

  });
  </script>

[/Update]

Im Quellcode habe ich bereits alles wichtige dokumentiert mittels Kommentare.

Das war es an dieser Stelle dann eigentlich auch schon. Auf jQuery und dem Validation Plugin sowie dem YAML Framework gehe ich hier nicht näher ein. Lesen Sie dazu bitte die entsprechenden Dokumentationen.

Tagged in: Javascript jQuery YAML
Trackback URL for this blog entry.