NixAhnung: Erweiterung JS Uploadtool

Hallo zusammen,

ich habe hier das folgende js Uploadtool gefunden, was auch prima funktioniert. Nun versuche ich schon länger das Tool um zwei Funktionen zu erweitern, jedoch ohne nennenswerten Erfolg weshalb ich hier um Unterstützung bitte. 🙄

1.) Nachdem eine Datei ausgewählt wurde, sollte diese irgendwie aus der Liste wieder zu entfernen sein. 2.) Bei Dateien über 5MB soll ein Hinweis kommen dass diese zu gross ist und sie soll nicht in die Uplosliste aufgenommen werden.

Vielen Dank.

HTML:

<input type="file" id="files" name="datei[]" accept="image/gif,image/jpeg" multiple="multiple">
<output id="list"></output>
<script>
	function dateiauswahl(evt) {
		var dateien = evt.target.files; 
		for (var i = 0, f; f = dateien[i]; i++) {
			if (!f.type.match('image.*')) {
				continue;
			}
			var reader = new FileReader();
			reader.onload = (function (theFile) {
				return function (e) {
					var vorschau = document.createElement('img');
					vorschau.className = 'vorschau';
					vorschau.src = e.target.result;
					vorschau.title = theFile.name;
					document.getElementById('list')
					.insertBefore(vorschau, null);
				};
			})(f);
			reader.readAsDataURL(f);
		}
	}
	document.getElementById('files')
	.addEventListener('change', dateiauswahl, false);
	</script>
  1. Hallo NixAhnung,

    naja, was man so "Tool" nennt. <input type="file" ... multiple="multiple"> ist ein normales Browser-Control. Damit wählst Du eine Liste von Dateien aus. Ändern kannst Du die nicht - was ausgewählt ist, ist ausgewählt. Du kannst nur komplett neu auswählen. Wenn Du Dateien einzeln löschen willst, bist Du eher bei 100 Zeilen JS statt 10, weil Du dann alles von Hand bauen musst.

    Im Übrigen muss deine Vorschau bei einer Neuauswahl gelöscht werden, sonst fügst Du die neuen Vorschaubilder nur den alten hinzu.

    Mach dazu am Anfang der dateiauswahl-Funktion diese Zeile hinein:

    document.getElementById('list').innerHTML = "";
    

    Für die Dateigröße - hast Du es schon mit f.size versucht? Da, wo Du auch f.type abfragst. Da sollte die Dateigröße drinstehen.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. @Rolf B, vielen Dank für deine Antwort.

      Nun, den HTML code für den Upload habe ich ergänzend mal mitgeliefert 😉

      Das mit dem f.size hatte ich schon getestet und jetzt nochmal an der Stelle wo f.type abgefragt wird.

      Klappt leider nicht, es werden auch Dateien > 100 byte genommen... Habe ich das falsch eingesetzt?

      if (!f.type.match('image.*') && f.size <= '100') {
      				continue;
      			}
      
      1. Hallo NixAhnung,

        willkommen in der Welt der elementaren Logik. Es ist gar nicht so leicht, so zu denken wie ein Computer.

        Dein Versuch hat mehrere Probleme. Du könntest das inspizieren, wenn Du die Entwicklerwerkzeuge des Browsers öffnest (mit Strg+Shift+I oder mit F12) und in der Quelltext-Ansicht einen Breakpoint auf dieser if-Anweisung setzt. Dazu klickst Du mit der Maus auf die Zeilennummer vor dieser Zeile, sie bekommt dann einen roten Punkt. Bei der nächsten Ausführung des Codes pausiert das Script an dieser Stelle und Du kannst in der Konsole Werte abfragen. Oder die Maus auf bestimmte Variablen halten und er sollte Dir den Wert anzeigen.

        Die Probleme:

        1. f.size enthält eine Zahl, keine Zeichenkette. Du solltest also deinen Vergleichswert nicht in Anführungszeichen setzen.
        2. Wenn die if-Bedingung erfüllt ist, wird der continue Befehl ausgeführt. Dieser Befehl überspringt den Rest des Schleifeninhalts, d.h. in diesem Fall wird die Datei nicht angenommen. Du musst die if-Bedingung also so formulieren, dass er auf den continue läuft, wenn sie den falschen Medientyp hat (das steht schon da) ODER wenn sie zu groß ist.

        ODER heißt: || statt &&
        Zu groß heißt: f.size > 5000000 statt f.size < 100

        Rolf

        --
        sumpsi - posui - obstruxi
        1. @Rolf, vielen Dank für deine Ausführung und deine Hilfe.

          Habe das jetzt zum testen mal so umgesetzt:

          if (!f.type.match('image.*') || f.size > 10) {
          				continue;
          			}
          

          Das Ergebnis ist, dass zwar keine Vorschau (Thumbnail) mehr angezeigt wird, jedoch der Dateinahmen dennoch aufgeführt wird und die Datei beim speichern auch hochgeladen wird...

          Mit dieser funktion lassen sich zB. auch .pdf Dateien hochladen, obwohl ja ungleich Bild-Datei auch mit diesem continue übersprungen werden sollte.

          Evtl. eine Idee woran es liegen könnte? Vielen Dank.

          1. Hallo NixAhnung,

            stimmt, eine falsche Datei bleibt ja in der files-Liste des input-Elements drin. Und die ist unveränderlich. Du kannst also nur irgendwie den Upload komplett verbieten.

            Warum PDFs durchkommen, ist mir im Moment auch nicht klar. Welchen Filetype haben die denn? Hast Du das mal mit console.log() ausgegeben? Es sollte application/pdf sein. Ein bisschen solltest Du auch selbst debuggen. Reines Code-Abschreiben ist nicht unser Ziel hier.

            Rolf

            --
            sumpsi - posui - obstruxi
            1. Hallo Rolf, vielen Dank für deine Geduld.

              Reines Code-Abschreiben ist nicht unser Ziel hier.

              Das ist nicht meine Absicht..

              Jedoch Die Uploadfunktion habe ich hier von der Seite und für die zwei von mir benötigten Funktionen bin ich tatsächlich schon länger am recherchieren und habe schon alles mögliche erfolglos getestet.

              Meine ansätze waren eben auch f.size.. was jedoch leider nicht so ist. Daher habe ich mich nun in der Hoffnung auf des Rätsels Lösung, hier registriert und meine Herausforderung mal geschildert.

              Dann sind meine zwei gewünschten Punkte tatsächlich auch für JS Spezis herausfordernd? 🤷‍♂️

              1. Hallo NixAhnung,

                Jedoch Die Uploadfunktion habe ich hier von der Seite

                womit Du uns jetzt in die Verantwortung bringen willst, die von Dir gewünschten Sonderlocken zu ergänzen?!

                Auf der von Dir erwähnten Seite steht auch, wie man einen Einzel-Upload macht. Nimm die Dateien aus dem File-Input, filtere die Liste nach ok/nicht ok und schick die brauchbaren Dateien dann einzeln hoch. Das sollte passen.

                Gerne kannst Du uns dein Ergebnis dann auf deiner Homepage vorstellen. Um es Dir vorzuprogrammieren, oder um mit Dir in einen PN-Briefwechsel zu treten, fehlt mir leider die Zeit.

                Rolf

                --
                sumpsi - posui - obstruxi
              2. Lieber NixAhnung,

                Du sagst nicht genau, wo auf „dieser Seite“ Du den Code für den Upload her hast. Wenn Du aber große Dateien hochladen willst und an einem vom Server gesetzten Größenlimit scheiterst, dann findest Du vielleicht in diesem Artikel Hilfe: Multiupload per JavaScript unterstützen

                Liebe Grüße

                Felix Riesterer

                1. Hallo Felix Riesterer,

                  such nach FileReader im Wiki, da gibt's nur 3 Seiten und der Code ist dort.

                  Das Ausfiltern passiert aber nur für die Vorschau, hochgeladen wird immer alles. Für die Lösung muss man halt den Upload "hintenrum" anstoßen, über Einzel-Uploads wie auf der Seite beschrieben oder über ein FormData Objekt.

                  Einzel-Uploads brauchen mehr Server-Ressouren wenn man sie parallelisiert (weil jeder Upload einen Server-Task bindet), dafür könnte man aber das progress-Event belauschen und eine Fortschrittsanzeige erzeugen. Hab ich noch nicht ausprobiert. Mit FormData ist's nur ein Request, der die Dateien nacheinander schickt.

                  Dafür haben wir nichts im Wiki - wie wir auch generell wenig zu FormData haben.

                  Rolf

                  --
                  sumpsi - posui - obstruxi
                  1. Lieber Rolf,

                    such nach FileReader im Wiki, da gibt's nur 3 Seiten und der Code ist dort.

                    OK, vielleicht hat es einen Sinn, das veraltete Plupload Dingens durch ein Script mit dem FileReader zu ersetzen, um parzielle Uploads zu realisieren, die auch große Dateien hochladen können.

                    Einzel-Uploads brauchen mehr Server-Ressouren wenn man sie parallelisiert (weil jeder Upload einen Server-Task bindet), dafür könnte man aber das progress-Event belauschen und eine Fortschrittsanzeige erzeugen. Hab ich noch nicht ausprobiert. Mit FormData ist's nur ein Request, der die Dateien nacheinander schickt.

                    Wenn man die Dateien bei Bedarf in Teilen hochlädt, ist das sequenziell und belegt nur den einen Thread auf dem Server. Deshalb fand ich das mit Plupload damals eine echt gute Idee! Dieses „damals“ war natürlich zu einer Zeit (November 2009), zu der der Flash-Player noch zum Stand der Technik gehörte. Das Zerlegen einer Datei beim Client war noch eine echte Fummelei, wenn man das Browser-übergreifend umsetzen wollte. Heute ist das längst etwas Anderes.

                    Dafür haben wir nichts im Wiki - wie wir auch generell wenig zu FormData haben.

                    Ich wollte schon länger mal an diese Plupload-Ersetzung ran. Betrifft ja nur den JS-Teil, weil der PHP-Teil genau so bleiben kann.

                    Liebe Grüße

                    Felix Riesterer

                    1. Hallo Felix,

                      das veraltete Plupload Dingens

                      Ugh - das scheint ja auf den ersten Blick vollkommen tot. Weder Flash noch Silverlight laufen in aktuellen Browsern. Aber Tiny scheint es portiert zu haben, dass es aktuelle Web APIs verwendet. Und damit könnte es wieder interessant werden, falls es einem die Grundproblematiken abnimmt.

                      Rolf

                      --
                      sumpsi - posui - obstruxi
                      1. Servus!

                        Hallo Felix,

                        das veraltete Plupload Dingens

                        Das war ein ToDo im letzten Januar. Evtl. können wir es nächsten Januar abschließen?

                        ToDo im Januar: File Upload vom 15.01.2023

                        Herzliche Grüße

                        Matthias Scharwies

                        --
                        Die Signatur findet sich auf der Rückseite des Beitrags.
  2. Hallo,

    1.) Nachdem eine Datei ausgewählt wurde, sollte diese irgendwie aus der Liste wieder zu entfernen sein. 2.) Bei Dateien über 5MB soll ein Hinweis kommen dass diese zu gross ist und sie soll nicht in die Uplosliste aufgenommen werden.

    Schonmalk daraüber nachgedacht, das Rad nicht nochmal neu zu erfinden?

    ich selber nutze eine alte version eines fileuploaders, die sehr schön funktioniert. Eine neuere Version scheint noch komfortabler geworden zu sein.

    https://innostudio.de/fileuploader

    Gruß, Kai (der mit dem Produkt nichts zu tun hat und selber nur Anwender ist)

    1. Hallo Kai,

      Schonmal daraüber nachgedacht, das Rad nicht nochmal neu zu erfinden?

      Deshalb könnte man ja auch das PLUpload-Beispiel überarbeiten.

      Der Innostudio-Uploader hingegen beginnt seine Beschreibung mit den Worten:

      A jQuery tool that...

      🤮
      browserTab.close();

      Rolf

      --
      sumpsi - posui - obstruxi
      1. Hallo Rolf,

        Der Innostudio-Uploader hingegen beginnt seine Beschreibung mit den Worten:

        A jQuery tool that...

        🤮
        browserTab.close();

        Geschmacksache.
        Da ich ohnehin jquery nutze, finde ich es konsequent, ein weiteres jquery-Tool einzusetzen.

        Kai

        1. Lieber Kai,

          Geschmacksache.

          nö. ;-)

          Da ich ohnehin jquery nutze,

          War es nicht so, dass man seit einiger Zeit auf jQuery getrost verzichten kann, weil es jetzt mit Vanilla JavaScript (und ECMA 6 im Hintergrund) so viele nützliche Sachen gibt, dass man damit besseren Code schreiben kann?

          finde ich es konsequent, ein weiteres jquery-Tool einzusetzen.

          Refactoring mit Vanilla ist ja auch lästig und wird von niemandem bezahlt. Habe ich schon mal gehört. Ist für Leute, die den Fokus auf Pragmatismus legen anstatt auf Idealismus, weil sie sich letzteren nicht leisten wollen oder dürfen. Wenn Du aber nur etwas "findest", dann geht es bei Dir eher ums Wollen denn um's Dürfen. Und nicht nur an Weihnachten gilt: Des Menschen Wille ist sein Himmelreich.

          Liebe Grüße

          Felix Riesterer

          1. Hallo Felix,

            Refactoring mit Vanilla ist ja auch lästig und wird von niemandem bezahlt. Habe ich schon mal gehört. Ist für Leute, die den Fokus auf Pragmatismus legen anstatt auf Idealismus, weil sie sich letzteren nicht leisten wollen oder dürfen.

            Da hast Du Recht.

            Also bleibts bei mir bei jquery. 😀

            Kai