Webformulare mit Datei-Upload ohne Neuladen der Seite (Ajax in der Praxis)

Christoph Heidenreich
Christoph Heidenreich Freut sich wenn MySQL zum Einsatz kommt und ist ansonsten im PHP/JavaScript Umfeld unterwegs.

Das neue Design der Full-responsive LeasePlan Webseite sah mehrere Webformulare auf einer Seite vor. Da Formulare jedoch normalerweise beim Absenden dafür sorgen, dass die gesamte Seite neu geladen wird, waren Anpassungen notwendig. Durch das Laden der gesamten Seite, beim Absenden eines Formulars, entsteht nicht nur durch die Wartezeit Frust. Auch die übertragene Datenmenge spielt - in Anbetracht der steigenden Zahl mobiler Anwender - eine große Rolle.

Nur das Formular sollte nach dem Absenden neu geladen werden

Der Nutzer hat keinen Vorteil davon, wenn das Absenden des Formulars die gesamte Seite neu lädt. Es ist eher frustrierend nach dem Absenden auf eine leere weiße Seite zu starren und sich zu fragen, was denn nun gerade überhaupt passiert.

Welchen Nutzen hat der Benutzer von einer solchen Anpassung? Ganz einfach:

  • Es findet weniger Datentransfer statt, da nur die Formulardaten an den Server gesendet werden und die Antwort des Servers ist geringer, da maximal nur das Formular erneut an den Client gesendet werden muss. Besonders für Anwender von mobilen Geräten ist dies sehr nützlich, da nicht jeder eine unbegrenzte Flatrate besitzt oder immer den besten Empfang hat.
  • Der Benutzer landet nach dem Absenden nicht wieder am Anfang der Seite, da kein erneutes Laden stattfindet.
  • Es ist möglich die Seite neu zu laden, ohne dass der Browser das Formular erneut absenden will, da die Seite weiterhin per GET aufgerufen wird und der POST an den Server nur über Ajax stattfindet.
  • Bei Verwendung mehrerer Webformulare auf einer inhaltsstarken Seite können diese nacheinander abgesendet werden. Falls ein Nutzer mehrere Webformulare gleichzeitig bearbeiten will, gehen nach dem Absenden eines Webformulars die bereits eingegebenen Daten in einem anderen Formular nicht verloren.

Technisch lässt sich das recht einfach lösen, in dem man das Formular per Ajax absenden lässt. Dadurch werden nur die eingegebenen Formulardaten an den Server gesendet. Als Antwort des Servers ist somit nicht mehr die komplette Seite notwendig, sondern nur die Antwort des Formulars. Dies kann je nach Anforderungen natürlich stark variieren. Im Fehlerfall sollte natürlich eine sprechende Fehlermeldung erscheinen und das Formular mit den entsprechenden falsch gefüllten Feldern hervorgehoben werden. Bei einem erfolgreichen Absenden, sollte dementsprechend eine Erfolgsmeldung erscheinen.


Beispiel für eine Umsetzung des Datei-Uploads über Ajax

Aufbau des Formulars:

<form name="name-des-formulars" method="post" enctype="multipart/form-data">
    <div>
        <label for="name">Name</label>
        <input type="text" id="name" name="name-des-formulars[name]">
    </div>
 
    <div>
        <label for="document">Dokument</label>
        <input type="file" id="document" name="name-des-formulars[document]">
    </div>
 
    <!-- weitere Felder -->
 
    <div>
        <button value="submit" type="submit" onclick="yourJavaScriptFunction(clickEvent);" name="name-des-formulars[submit]">Absenden</button>
    </div>
</form>

Wichtig

Für den Datei-Upload ist die Eigenschaft "enctype" im Formular auf "multipart/form-data" zu setzen.

Auszug des JavaScripts:

function yourJavaScriptFunction(clickEvent) {
    clickEvent.preventDefault();
  
    // Initialisierung weiterer Variablen
  
    var formPostData = new FormData(document.forms.namedItem('name-des-formulars'));
 
 
    jQuery.ajax({
        type: "post",
        url: requestURL,
        data: formPostData,
        dataType: "json",
        contentType: false,
        cache: false,
        processData: false,
        //...

Für den Datei-Upload verwenden wir hier das FormData Objekt, da ansonsten die Dateien nicht mit versendet werden. Zusätzlich sind die Einstellungen contentType und processData hierfür auf false zu setzen, da hier unterschiedliche Formate (Text, Bilder, Dokumente, etc.) übertragen werden. Zu dem sollte das Caching ebenfalls nicht aktiviert sein, da es hier um individuelle Benutzerspezifische Daten geht, die nicht gecached werden können.


Wie kann das ganze in TYPO3 mit Formhandler realisiert werden?

Wir bei punkt.de verwenden unter anderem die Extension Formhandler für Webformulare, da diese einfach anzupassen und zu erweitern ist und sehr viel Funktionalität bietet. Um Formhandler Formulare per Ajax absenden zu lassen sind nur wenige Anpassungen notwendig:

Zuerst benötigen wir einen eigenen AjaxFileUploadHandler der von Tx_Formhandler_AjaxHandler_JQuery erbt. Dies ist notwendig, da wir die Daten über das FormData Object übergeben wollen um einen Datei-Upload über Ajax zu erhalten und dies noch nicht über Formhandler konfigurierbar ist.

class Tx_PtFormhandler_AjaxFileUploadHandler_JQuery extends Tx_Formhandler_AjaxHandler_Jquery
{
    public function initAjax()
    {
        // der Code dieser Funktion aus der Eltern-Klasse sollte hier entsprechend dem obigen Beispiel angepasst werden
    }

Wichtig

Durch die Verwendung eines eigenen AjaxHandlers hat man zwar die freie Hand über den Code ohne die Extension patchen zu müssen, jedoch sollte man bei Updates die Eltern-Klasse mit dem eigenen AjaxHandler vergleichen, um mögliche Probleme durch Code-Änderungen vorzubeugen.

Als nächstes muss das entsprechende Formular noch auf Ajax umgestellt werden:

ajax {
   class = Tx_PtFormhandler_AjaxFileUploadHandler_JQuery
   config {
      jsPosition = footer
      ajaxSubmit = 1
      ajaxSubmitCallback = formhandlerCallbackOnAjaxSubmit
      submitButtonSelector = #my-form-id
   }
}

In dieser Konfiguration gibt es einige wichtige Aspekte, die es im Zusammenhang mit der Verwendung von Ajax zu beachten gibt:

  • jsPosition: je nach dem wie bzw. wo die jQuery Library eingebunden wird, ist eine entsprechende Positionierung des Formhandler Inline-JavaScripts wichtig.
  • ajaxSubmitCallback: wenn es im Formular JavaScript Code gibt, der den Inhalt der Webformulare manipuliert wie z.B. ein eigener Datei-Upload, kann der ajaxSubmitCallback genutzt werden, um eine Initialisierungsfunktion für solchen Code erneut ausführen zu lassen, da bei Fehlern, das Formular erneut gerendert wird und der JavaScript-Code der Seite nicht erneut ausgeführt wird. Die aufgerufene Funktion muss natürlich auf der gesamten Seite zur Verfügung stehen.
  • submitButtonSelector: bei Verwendung mehrerer Webformulare auf einer Seite muss ein Submit-Button darüber definiert werden, da ansonsten der automatisch generierte JavaScript Code nicht mehr das korrekte Formular berücksichtigt. 

Mit diesen wenigen Anpassungen an Webformulare, lassen sich die Performance, die Ladezeit, die Usability, sowie der Traffic (sowohl für Client als auch für Server) optimieren. Eine Investition, die sich für Webseiten-Betreiber und Webseiten-Besucher lohnt.

Autor: Christoph Heidenreich

Kommentare

Bisher wurden noch keine Kommentare eingereicht.


Weitere Beiträge

19. August 2016

Anzeigen dynamischer Seiteninhalte im Zusammenspiel mit dem Zurück-Button

In Zeiten von dynamisch nachgeladenem Seiteninhalt kommt es häufiger vor, dass ein Zurückspringen auf … mehr

21. Juni 2016

Agile Coach Camp 17.-19. Juni 2016 in Rückersbach

Es waren einmal zwei ScrumMasterinnen bei punkt.de, die sich nach Fortbildung und Inspiration sehnten. … mehr