Wicked Software - Roundabout

Ausgefallen gut ins Netz!

Hinter dem Namen Wicked Software stehen ausgefallen gute und begeisterte Entwickler, für die Software wesentlich mehr ist als funktionierender Code. Wicked Software hat sich auf Joomla! spezialisiert und bietet moderne und flexible Erweiterungen.

Wir schreiben in unseren Blog mit und über Joomla!, unsere Software, Tricks & Tipps und alles was uns in den Sinn kommt und uns nützlich erscheint.

Der TinyMCE in Joomla!

Custom Fields

Wir haben ein Kontaktformular auf unserer Website und wir möchten wissen, warum die Kunden uns kontaktieren. Möchten sie zurück gerufen werden? Haben sie eine allgemeine Frage? Möchten sie einen Termin vereinbaren? Damit die Kunden diese Information im Textfeld nicht vergessen zu schreiben, werden wir einige extra Felder einfügen, die sich je nach Auswahl ein- oder ausblenden.

Als erstes legen wir die benötigten Custom Fields fürs Formular an. Das erste Feld ist eine Auswahlliste für den Grund des Kontaktes:

  • Grund (Auswahliste)
    • Rückruf
    • Terminwunsch
    • Sonstiges

Dafür gehen wir auf Komponenten -> Kontakte -> Felder. Hier wählen wir "E-Mail" im ersten Auswahlfeld:

Wir legen ein neues Feld des Typs "Liste" an:

Das Feld "Grund" machen wir als Pflichtfeld.

Wenn jemand "Rückruf" auswählt, soll ein Feld für die Telefonnummer sichtbar werden.

  • Grund (Auswahliste)
    • Rückruf
      • Telefonnummer (Pflicht)
    • Terminwunsch
    • Sonstiges

Dann legen wir als zweites das Feld "Telefonnummer" als Typ "Text" an:

Bei der Auswahl "Terminwunsch" möchten wir eine weitere Auswahl einblenden mit der Länge des Termins.

  • Grund (Auswahliste)
    • Rückruf
    • Terminwunsch
      • Terminlänge (Pflicht)
    • Sonstiges

Wir verfahren wie schon beschrieben und legen ein neues Feld des Typs "Liste" an:

Als letztes wollen wir ein "Thema" Feld haben, wenn jemand ein anderes Thema ansprechen möchte.

  • Grund (Auswahliste)
    • Rückruf
    • Terminwunsch
    • Sonstiges
      • Thema (Pflicht)

Dafür brauchen wir ein "Text" Feld:

Da wir die Felder "Telefonnummer", "Terminlänge" und "Thema" mit Hilfe von Javascript ein- und ausblenden werden, werden wir die Felder hier nicht als Pflichfeld definieren, sondern auch über das Javascript steuern.

Damit alle Felder im Formular verwendet werden können, müssen wir die Berechtigungen für die Bearbeitung für die Benutzergruppe "Public" auf erlauben setzen:

Formular

Jetzt müssen unser Formular erstellen. Wir werden mit einem Override von com_contact/contact/default_form.php arbeiten. Entweder kopieren wir uns diese Datei in unserem Template unter meintemplate/html/com_contact/contact oder wir nutzen die Override Funktion von Joomla unter Erweiterungen » Templates » Templates » Mein Template - Dateien und Details » Overrides erstellen und wählen hier unter Komponenten » com_contact » contact Mit dem Editor machen wir die default_form.php Datei auf und löschen den Code ab <?php foreach... bis <?php endforeach; ?> (Zeilen 18 bis 33). Wenn wir diesen Code behalten, werden die Felder automatisch gerendert und die Custom Fields erscheinen als ein extra Fieldset unterhalb des standard Formulars, was nicht besonders schön aussieht und auch nicht in unserem Konzept passt.

Standard Formular Ansicht

In unserem Override werden wir die Felder manuell einfügen und zwar in der Reihenfolge, in der wir sie benötigen. Die Standardfelder von com_contact werden mit z.B. <?php echo $this->form->getLabel('contact_email'); ?> fürs Label und <?php echo $this->form->getInput('contact_email'); ?> fürs Input gerendert. Für Custom Fields müssen wir den Aufruf mit "com_fields" ergänzen, z.B. <?php echo $this->form->getLabel('grund','com_fields'); ?> und <?php echo $this->form->getInput('grund','com_fields'); ?>. Der Code fürs Formular sieht jetzt so aus:

			
<fieldset>
  <div id="grund" class="control-group">
    <div class="control-label">
      <?php echo $this->form->getLabel('grund','com_fields'); ?>      
    </div>
    <div class="controls">
      <?php echo $this->form->getInput('grund','com_fields'); ?>
    </div>
  </div>
  <div id="termin" class="control-group" style="display: none;">
    <div class="control-label">
      <?php echo $this->form->getLabel('terminlaenge','com_fields'); ?>      
    </div>
    <div class="controls">
      <?php echo $this->form->getInput('terminlaenge','com_fields'); ?>
    </div>
  </div>
  <div id="thema" class="control-group" style="display: none;">
    <div class="control-label">
      <?php echo $this->form->getLabel('thema','com_fields'); ?>      
    </div>
    <div class="controls">
      <?php echo $this->form->getInput('thema','com_fields'); ?>
    </div>
  </div>
  <div id="telefon" class="control-group" style="display: none;">
    <div class="control-label">
      <?php echo $this->form->getLabel('telefon','com_fields'); ?>
    </div>
    <div class="controls">
      <?php echo $this->form->getInput('telefon','com_fields'); ?>
    </div>
  </div>
  <div class="control-group">
    <div class="control-label">
      <?php echo $this->form->getLabel('contact_name'); ?>
    </div>
    <div class="controls">
      <?php echo $this->form->getInput('contact_name'); ?>
    </div>
  </div>
  <div class="control-group">
    <div class="control-label">
      <?php echo $this->form->getLabel('contact_email'); ?>
    </div>
    <div class="controls">
      <?php echo $this->form->getInput('contact_email'); ?>
    </div>
  </div>
  <div class="control-group">
    <div class="control-label">
      <?php echo $this->form->getLabel('contact_subject'); ?>
    </div>
    <div class="controls">
      <?php echo $this->form->getInput('contact_subject'); ?>
    </div>
  </div>
  <div class="control-group">
    <div class="control-label">
      <?php echo $this->form->getLabel('contact_message'); ?>
    </div>
    <div class="controls">
      <?php echo $this->form->getInput('contact_message'); ?>
    </div>
  </div>
  <div id="captcha" class="control-group">
    <div class="control-label">
      <?php echo $this->form->getLabel('captcha'); ?>      
    </div>
    <div class="controls">
      <?php echo $this->form->getInput('captcha'); ?>
    </div>
  </div>
  </fieldset>

Das ist das Ergebniss auf der Website:

Wir möchten aber nicht alle Felder auf einmal sehen, sondern erst einblenden je nach Auswahl im Feld "Grund". Um das zu erreichen, ist der erste Schritt, die Felder mit style="display: none;" zu verstecken:

Javascript

Um die Felder zu steuern werden wir ein Javascript im Formular einfügen. Wir haben jedes Feld in einem div Container mit einer ID gesteckt. Das erlaubt uns, mittels Javascript die Bereiche ein- und auszublenden. Mit $('#termin').hide(); z.B. verstecken wir den Container mit dem Feld "Terminlänge" (Das "$"-Zeichen ist hierbei ein Alias für "jQuery").
Aber eins nach dem anderen. Unser Javascript sieht am Ende so aus:

<script type="text/javascript">
(function($)
{
    $(function()
    {
        $('#jform_com_fields_grund').on('change', function()
        {
            var $this = $(this),
            value = $this.val();
           
            $('#termin').hide();
            $('#telefon').hide();
            $('#thema').hide();
        
            if (value == 'Rückruf')
            {
                $('#telefon').show();
                $('#termin').hide();
                $('#thema').hide();
                $("#jform_com_fields_telefonnummer-lbl").addClass("required");
                $("#jform_com_fields_telefonnummer-lbl").append('<span id="tel" class="star"> *</span>');
                $("#jform_com_fields_telefonnummer").addClass("required");
                $("#jform_com_fields_telefonnummer").attr('required', 'required');
                $("#them").empty();
                $("#jform_com_fields_thema-lbl").removeClass("required");
                $("#jform_com_fields_thema").removeClass("required");
                $("#jform_com_fields_thema").removeAttr('required');
                $("#term").empty();
                $("#jform_com_fields_terminlaenge-lbl").removeClass("required");
                $("#jform_com_fields_terminlaenge").removeClass("required");
                $("#jform_com_fields_terminlaenge").removeAttr('required');
            }
            if (value == 'Terminwunsch')
            {
                $('#termin').show();
                $('#telefon').hide();
                $('#thema').hide();
                $("#jform_com_fields_terminlaenge-lbl").addClass("required");
                $("#jform_com_fields_terminlaenge-lbl").append('<span id="term" class="star"> *</span>');
                $("#jform_com_fields_terminlaenge").addClass("required");
                $("#jform_com_fields_terminlaenge").attr('required', 'required');
                $("#them").empty();
                $("#jform_com_fields_thema-lbl").removeClass("required");
                $("#jform_com_fields_thema").removeClass("required");
                $("#jform_com_fields_thema").removeAttr('required');
                $("#tel").empty();
                $("#jform_com_fields_telefonnummer-lbl").removeClass("required");
                $("#jform_com_fields_telefonnummer").removeClass("required");
                $("#jform_com_fields_telefonnummer").removeAttr('required');
            }
            if (value == 'Sonstiges')
            {
                $('#thema').show();
                $('#termin').hide();
                $('#telefon').hide();
                $("#jform_com_fields_thema-lbl").addClass("required");
                $("#jform_com_fields_thema-lbl").append('<span id="them" class="star"> *</span>');
                $("#jform_com_fields_thema").addClass("required");
                $("#jform_com_fields_thema").attr('required', 'required');
                $("#tel").empty();
                $("#jform_com_fields_telefonnummer-lbl").removeClass("required");
                $("#jform_com_fields_telefonnummer").removeClass("required");
                $("#jform_com_fields_telefonnummer").removeAttr('required');
                $("#term").empty();
                $("#jform_com_fields_terminlaenge-lbl").removeClass("required");
                $("#jform_com_fields_terminlaenge").removeClass("required");
                $("#jform_com_fields_terminlaenge").removeAttr('required');
            }
        });
    });
})(jQuery);
</script>

Jetzt werden wir beschreiben, was die Befehle bewirken. Die Namen der Elemente (IDs), die wir ansprechen wollen, können wir im Quellcode des Formulars ablesen (z.B. das Feld "Grund" hat die ID jform_com_fields_grund). Das Feld "Grund" ist unser Ausgangspunkt, wenn sich hier etwas ändert, soll im Formular etwas passieren. Deswegen schauen wir als erstes ob sich das Feld ändert mit $('#jform_com_fields_grund').on('change', function() Dann holen wir uns den Wert des Feldes, also was ausgewählt ist:

var $this = $(this),
value = $this.val();

Und verstecken die weiteren Felder:

$('#termin').hide();
$('#telefon').hide();
$('#thema').hide();

Wenn als Grund "Rückruf" ausgewählt ist

if (value == 'Rückruf')) {

soll das Feld "Telefonnummer" eingeblendet werden

$('#telefon').show();

Die weiteren Felder bleiben versteckt

$('#termin').hide();
$('#thema').hide();

"Telefonnummer" soll ein Pflichtfeld werden. Dafür werden wir die Klasse "required" am Label und Input ergänzen und ein Sternchen neben dem Label einfügen. Damit beim Absenden des Formulars das Feld als pflichtig geprüft werden kann, brauchen wir noch das Attribut "required" zu ergänzen.

if (value == 'Rückruf')
{
  $('#telefon').show();
  $('#termin').hide();
  $('#thema').hide();
  $("#jform_com_fields_telefonnummer-lbl").addClass("required");
  $("#jform_com_fields_telefonnummer-lbl").append('<span id="them" class="star"> *</span>');
  $("#jform_com_fields_telefonnummer").addClass("required");
  $("#jform_com_fields_telefonnummer").attr('required', 'required');
}

Und das machen wir genauso für die anderen Werte für "Grund" mit dem einblenden der entsprechenden Felder.

Wir müssen aber auch noch an alle Varianten denken, was passiert z.B. wenn jemand zuerst als Grund "Terminwunsch" auswählt und sich dann doch für "Rückruf" entscheidet? In diesem Fall würde das Feld "Terminlänge" noch als Pflichtfeld markiert sein und ein Fehler beim Absenden des Formulars verursachen. Um das zu verhindern, werden wir die Klassen und Attributen der anderen Felder (wenn vorhanden) entfernen. Auch das Sternchen müssen wir wegmachen. Damit wir das "richtige" Sternchen ansprechen, haben wir den Sternen auch eine ID gegeben. Am Ende sieht der Code für die Auswahl "Rückruf" so aus:

if (value == 'Rückruf')
{
  $('#telefon').show();
  $('#termin').hide();
  $('#thema').hide();
  $("#jform_com_fields_telefonnummer-lbl").addClass("required");
  $("#jform_com_fields_telefonnummer-lbl").append('<span id="tel" class="star"> *</span>');
  $("#jform_com_fields_telefonnummer").addClass("required");
  $("#jform_com_fields_telefonnummer").attr('required', 'required');
  $("#them").empty();
  $("#jform_com_fields_thema-lbl").removeClass("required");
  $("#jform_com_fields_thema").removeClass("required");
  $("#jform_com_fields_thema").removeAttr('required');
  $("#term").empty();
  $("#jform_com_fields_terminlaenge-lbl").removeClass("required");
  $("#jform_com_fields_terminlaenge").removeClass("required");
  $("#jform_com_fields_terminlaenge").removeAttr('required');
 }

Jetzt wird der Code für die anderen Werte und Felder ergänzt und fertig ist unser dynamisches Formular mit Joomla Boardmitteln.

Fazit

Mit Custom Fields kann man sehr gut das Standardformular von Joomla erweitern. Mit Overrides und ein bisschen Javascript lassen sich dann dynamische Formulare gestalten, ohne Einsatz von Dritterweiterungen.

Override Custom Fields Kontaktformular
Autor: Dr. Viviana Menzel
Dr. Viviana Menzel

Ich beschäftige mich seit 2006 mit Joomla! Seit 2008 bin ich selbstständige Webentwicklerin und habe mich auf die Entwicklung von Websites auf Basis von Joomla! spezialisiert. Ich schreibe gerne Artikel über Joomla! und habe auch Vorträge beim JoomlaDay Deutschland gehalten.