VHS:Render.Uncache Viewhelper TYPO3 Fatal Error

Ich habe vor einigen Tagen mit dem Render.Uncache Viewhelper gearbeitet, da ich für ein Projekt einen Teilbereich meines Templates nicht gecacht haben wollte, wohingegen der Rest des Templates gerne gecacht werden durfte. Nach kurzer Recherche habe ich den ViewHelper Render.Uncache von https://fluidtypo3.org/viewhelpers/vhs/2.4.0/Render/UncacheViewHelper.html gefunden. Dieser scheint genau das zu bieten was ich gesucht habe.
„VHS:Render.Uncache Viewhelper TYPO3 Fatal Error“ weiterlesen

Dynamische Formulare mit TYPO3 Formhandler

Heute schreibe ich darüber wie man mit Typo3 Formhandler ein dynamisches Formular erstellen kann. Ein dynamisches Formular ist für mich ein Formular, welches sich je nach Nutzer Eingabe ändert. Ich stand gerade vor der Herausforderung dieses Problem für einen Kunden zu lösen. Erstellt werden sollte ein Formular welches zum einen teilweise komplett neue Eingabefelder beinhaltet, je nach Auswahl eines vorherigen Feldes und zum zweiten auch ggf. andere Pflichtfelder. Da es sich um ein sehr umfangreiches Formular handelt sollte dieses zusätzlich noch auf mehrere Seiten aufgeteilt werden.

tl;dr

Multistep Formulare mit TYPO3 Formhandler
Dynamische Validierungsregeln mit Conditions
Dynamische Templatesuffix mit Conditions

Herausforderung

Wie eingangs bereits erwähnt gab es diverse Herausforderungen zu meistern die auch eine Lösung mit reinem PHP sehr aufwändig gemacht hätten. Als erstes wäre die Aufteilung auf mehrere Seiten. Anschließend die abhängig von eingegebenen Daten andere Validierung der Formularfelder und letztendlich auch noch die Anzeige weiterer Eingabefelder je nach eingegebenen Daten.

Lösung

Im Nachhinein ist die Lösung mit TYPO3 Formhandler gar nicht so schwierig wie anfangs befürchtet. Man kann in der Formulardefinition mit Bedingungen arbeiten und auch das anzeigen weiterer Formularfelder je nach eingegebenen Daten stellt kein Hexenwerk dar. Hierfür gibt es auch bereits vorbereitete Konfigurationsmöglichkeiten.

Vorgehen

Mein Vorgehen zur Lösung dieses Problems. Ich habe das Formular erst einmal komplett aufgebaut ohne Validierungsregeln und Finisher. Dabei habe ich mich an die im Artikel Formhandler richtig konfigurieren aufgezeigten Einstellungen gehalten. Ich habe also ein Vordefiniertes Formular erstellt und dieses mit einem Master Template aufgebaut.

Der Unterschied zu dem dort beschriebenen Vorgehen ist, dass ich mehrere Schritte in dem Formular genutzt habe. Dazu habe ich neben der Datei step-1.html auch eine step-2.html und eine step-3.html. Die Typoscript Konfiguration habe ich so geändert, dass mehrere templateFile Definitionen vorliegen. Konkret sieht das wie folgt aus:

1.templateFile = TEXT
1.templateFile.value = {$formhandler.multistep-form.rootPath}/html/step-1.html
2.templateFile = TEXT
2.templateFile.value = {$formhandler.application.rootPath}/html/step-2.html
3.templateFile = TEXT
3.templateFile.value = {$formhandler.application.rootPath}/html/step-3.html

Dadurch weiß Formhandler, dass es mehrere Schritte in dem Formular gibt. Um die Speicherung der Daten in der Session etc. braucht man sich nicht weiter kümmern. Das übernimmt TYPO3 Formhandler. Eine Anforderung wurde somit jetzt bereits gelöst. Es existiert ein Formular mit mehreren Schritten.

Die nächste Anforderung die wir lösen ist es unterschiedliche Formularfelder je nach eingegebenen Daten anzuzeigen.

In den 3 HTML Dateien habe ich bisher die Mindestausprägung an Formularfeldern eingetragen. Also die Felder die alle User zu sehen bekommen. In Schritt 2 gibt es für den User die Möglichkeit das Formular zu ändern. Dazu muss dieser Daten in ein Feld eingeben und durch klick auf den Button weitere Felder hinzufügen sollen weitere Felder angezeigt werden. Dazu habe ich die Datei step-2.html so verändert, dass dort ein zweites Formular definiert wurde. Zum Vergleich einmal eine minimale Version der step-2.html

<!-- ###TEMPLATE_FORM2### -->
###master_multipart-form-start_application-form###
    ###master_section-start###
        ###master_input_field1###
        <input type="submit" ###submit_reload### class="btn btn-default tiny submit" value="###LLL:submit_expand_form###" />
        ###master_submit###
    ###master_section-end###
 
###master_form-end###
<!-- ###TEMPLATE_FORM2### -->
 
<!-- ###TEMPLATE_FORM2_expand### -->
###master_multipart-form-start_application-form###
    <input type="hidden" name="###formValuesPrefix###[expand]" value="1"/>
    ###master_section-start###
        ###master_input_field1###
        ###master_input_field2###
        ###master_submit### 
    ###master_section-end###
###master_form-end### 
<!-- ###TEMPLATE_FORM2_expand### -->

Der Schritt 2 in dem Formular beinhaltet jetzt also erst einmal ein Input Field welches hier field1 heißt. Außerdem wird ein Button angezeigt welcher dafür sorgt, dass der aktuelle Schritt neu geladen wird. Der ###submit_reload### Button wird normalerweise genutzt um Dateien hoch zu laden und das Formular genau mit den eingegebenen Daten wieder anzuzeigen. Diesen nutze ich hier einfach um das Formular abzuschicken ohne dass Validierungsregeln geprüft werden und das Formular zum nächsten Schritt weiter geht. Wenn auf diesen Button geklickt wird soll nun aber ein weiteres Formularelement angezeigt werden. In dem Fall kommt das zweite definierte Form in der oben dargestellten Datei zum Einsatz. Das Formular ist mit dem Marker ###TEMPLATE_FORM2_expand### bezeichnet. Damit TYPO3 Formhandler jetzt dieses Formular anzeigt anstelle des normale ###TEMPLATE_FORM2### muss ein bisschen TypoScript in der Konfiguration geändert werden.

plugin.Tx_Formhandler.settings.predef.multistep-form {
    # Configure different settings for Formhandler using conditions like these
    if {
        1 {
            
            conditions{
                # If the field1 is not empty and step-2-reload equals "+"
                OR1 {
                    AND1 = field1 !=
                    AND2 = step-2-reload = +
                }
                # OR the field expand equals "1"
                OR2 {
                    AND1 = expand = 1
                }
            }
            isTrue {
                # Make settings for a different step 2
                2 {
                    templateSuffix = _expand
                    validators.1.config.fieldConf {
                        field2.errorCheck.1 = required
                    }
                }
            }
        }
    }
}

In obigem TypoScript ist der Teil zu sehen, der dafür zuständig ist, dass je nach eingegebenen Daten ein anderer Formularteil ausgegeben wird. Ich habe dort ein paar Bedingungen und sollten diese zutreffen so wird der templateSuffix _expand gesetzt. Ich prüfe darauf, dass field1 Inhalt enthält und zweitens, dass das Feld step-2-reload gleich dem Wert „+“ ist. step-2-reload entspricht dem Submit Feld welches in dem Formular ###TEMPLATE_FORM2### gesetzt wurde. Sollten diese beiden Bedingungen zutreffen so nutzt Formhandler zur Darstellung das oben definierte Formular ###TEMPLATE_FORM2_expand###.
Die zweite Bedingung die ich gesetzt habe prüft auf das Feld expand. Dieses ist in der Konfiguration von ###TEMPLATE_FORM2_expand### gesetzt. Diese zweite Bedingung ist notwendig, da ansonsten nach dem Abschicken und ggf. aufgrund von Validierungsfehlern erneutem anzeigen von step-2 nicht die expand Version angezeigt würde sondern wieder nur die normale, da ja die Werte des step-2-reload nicht mehr in den Formulardaten enthalten wären.
Mit dieser Konfiguration haben wir die zweite Anforderung gelöst. Es ist möglich abhängig von den eingegebenen Daten unterschiedliche Formularelemente anzuzeigen.

Im obigen TypoScript ist bereits ein Teil der dynamischen Validierung zu sehen.

validators.1.config.fieldConf {
    field2.errorCheck.1 = required
}

Diese Validierungsregeln werden nur angewendet, sofern das expand Formular auch angezeigt wird. Andernfalls wäre es für den Besucher auch nicht möglich das Formular abzuschicken, da ein Feld validiert werden würde, welches so gar nicht vorhanden wäre.

Kommen wir generell zu den Validierungsregeln. Da wir ein Multistep Formular haben müssen wir auch die Validierungsregeln auf mehrere Schritte aufteilen. Ansonsten würde TYPO3 Formhandler alle Regeln bei jedem Schritt ausführen, was dazu führen würde, dass der Besucher der Webseite nicht zu Schritt zwei kommen würde, da Felder die entsprechenden Felder noch nicht validiert wurden.
Die Aufteilung der Regeln auf die einzelnen Schritte ist mit dem folgenden TypoScript möglich.

   # Validation Rules step1
   1.validators {
       1.class = Validator_Default
       1.config.fieldConf {
           fieldstep1.erorChedk.1 = required
       }
   }
   # Validation Rules step2 
   2.validators {
       1.class = Validator_Default
       1.config.fieldConf {
           field1.errorCheck.1 = required
       }
   }
   # Validation Rules step3
   3.validators {
       1.class = Validator_Default
       1.config.fieldConf {
           fieldstep3.errorCheck.1 = required
       }
   }

Zurück zu der Anforderung, dass Felder abhängig von eingegebenen Daten validiert werden sollen. Mithilfe von Conditions ist es ebenfalls möglich Felder abhängig von anderen eingegebene Daten um weitere Validierungsregeln zu ergänzen. Oben weiter bin ich da schon kurz drauf eingegangen. Man kann Conditions definieren und im isTrue Block nur weitere Validation Rules setzen. Dadurch haben wir auch eine Möglichkeit die Anforderung nach dynamischer Validierung von Formularfeldern abhängig von eingegebenen Daten erfüllt.

Ich hoffe dieser Artikel war verständlich für dich und konnte dir weiter helfen. Solltest du Fragen zu einem Teil haben, so hinterlasse mir einfach einen Kommentar oder nutze mein Kontaktformular. Ich freue mich über Feedback.

Fazit

Es ist mit TYPO3 Formhandler möglich dynamische Formulare zu erstellen. Nachdem man die Funktionsweise von Formhandler verstanden hat kann man damit sehr einfach sehr umfangreiche Formulare erstellen. Ein Punkt den ich mir in den nächsten Tagen noch ansehen werde ist die Nutzung von Ajax um das Formular zu validieren bzw. abzuschicken. Dieses ist mit TYPO3 Formhandler ebenfalls möglich, das habe ich jedoch noch nicht bei so einem umfangreichen Formular genutzt.