Bryan Albrecht

Asynchrones hochladen von Dateien auf einer Website

Normalerweise werden Dateien in einer Webapplikation durch das Absenden eines Formulars durch den Benutzer auf den Server hochgeladen. Falls in diesem Formular nun noch andere Felder vorhanden sind, welche vom Server zuerst noch validiert werden müssen, so kann es sein, dass dem Benutzer das Formular noch einmal angezeigt werden muss. Dieses Mal jedoch mit einer zusätzlichen Fehlermeldung. Wenn dies der Fall ist, so geht die vom Benutzer ausgewählte Datei verloren. Es ist nicht möglich, dass das Formular wieder automatisch die richtige Datei auswählt. Dies muss vom Benutzer manuell gemacht werden.

Nutzen

Damit die ausgewählte Datei nicht beim neu Laden des Formulars verloren geht, wäre es sinnvoll, dass diese bereits vor Absenden des Formulars auf den Server hochgeladen werden würde. Dies würde bedeuten, dass im Formular nicht mehr die Datei selbst, sondern nur noch eine Referenz zur Datei gespeichert wird. Diese Referenz geht auch beim neu laden nicht verloren.

Voraussetzung

Um automatisch Dateien aus dem Browser zum Server senden zu können, werden in diesem Fall mehrere Hilfsmittel benutzt.

  • jQuery
  • jQuery.iframe-transport
  • jQuery.fileupload

Frontend

Im Frontend wird ausschliesslich mit HTML, CSS und JavaScript gearbeitet. Wie bereits bei den Voraussetzungen beschrieben, wird jQuery für die einfachere Arbeit mit JavaScript benutzt.

Formular

Um ein Bild hochladen zu können, muss sich der Auswahlbereich in einem Formular befinden dies sieht in diesem Beispiel wie folgt aus:

  1. <form id="upload" method="post" action="/Controller/Method" enctype="multipart/form-data">
  2. <div id="drop">
  3.     <a>Upload File</a>
  4.     <input type="file" name="upl" multiple="" id="fileuploader">
  5. </div>
  6. </form>

Die ID’s werden später im JavaScript benutzt, um die einzelnen Elemente problemlos ansprechen zu können.
Als Action soll später die richtige Methode so wie der richtige Controller angegeben werden. Dies beschreibt, wohin das Bild gesendet werden soll.
Wenn das Formular nun im Browser geöffnet wird, so sieht dieses wie folgt aus:

Unstyled

Da der Benutzer später kein richtiges Eingabefeld mehr vor sich haben soll, muss noch einiges gemacht werden. Ein Teil davon ist das Styling. Das Ziel ist es, dass der Benutzer einen Knopf vor sich hat, welcher wie folgt aussieht:

Styled

Um dieses Ziel zu erreichen, müssen folgende Zeilen CSS verwendet werden:

  1. upload {
  2.     width: 30%;
  3.     margin: 0 auto;
  4.     margin-top: 100px;
  5.     background-color: #5ebfef;
  6.     padding: 3px;
  7.     border-radius: 3px;
  8. }
  9. #drop a {
  10.     background: #0099e5 no-repeat 25px;
  11.     padding: 30px 0px;
  12.     color: #fff;
  13.     width: 50%;
  14.     cursor: pointer;
  15.     display: inline-block;
  16.     text-align: center;
  17.     text-decoration: none;
  18.     font-size: 25px;
  19.     font-weight: bold;
  20.     font-family: calibri;
  21.     letter-spacing: 1px;
  22.     border-bottom: 1px solid #5ebfef;
  23.     border-radius: 3px;
  24. }
  25. #drop input {
  26.     display: none;
  27. }

Javascript

Um die Logik im Frontend richtig umsetzen zu können, braucht es einige JavaScript Funktionen.

Eine Wichtige Funktion ist, dass eine Datei direkt auf den Button gezogen werden kann, ohne dass der Browser diese Datei versucht darzustellen. Dies wird wie folgt gemacht:

  1. $(document).on('drop dragover', function (e) {
  2. e.preventDefault();
  3. });

Die Haupt JavaScript Funktion liegt beim Heraufladen der Datei. Die gesamte Funktion sieht wie folgt aus:

  1. $('#upload').fileupload({
  2. dropZone: $('#drop'),
  3. add: function (e, data) {
  4. var jqXHR = data.submit();
  5. },
  6. fail: function (e, data) {
  7. alert('Es ist ein Fehler aufgetreten.');
  8. },
  9. done: function (e, data) {
  10. // Logik, wenn alles gut gegangen ist
  11. }
  12. });

Damit der im Bild blau hinterlegte Text auch als Button dient, braucht es noch ein Script, welches das Input Feld auslöst, wenn auf den Text geklickt wird. Dieser sieht wie folgt aus:

  1. $('#drop a').click(function () {
  2. $(this).parent().find('input').click();
  3. });