web-dev-qa-db-de.com

Integration von Dropzone.js in vorhandene HTML-Formulare mit anderen Feldern

Ich habe derzeit ein HTML-Formular, in das die Benutzer Details zu einer Anzeige eintragen, die sie veröffentlichen möchten. Ich möchte nun eine Dropzone zum Hochladen von Bildern des Artikels zum Verkauf hinzufügen können. Ich habe dropzone.js gefunden, was anscheinend das meiste tut, was ich brauche. Beim Durchsehen der Dokumentation scheint es jedoch so, als müssten Sie die Klasse des gesamten Formulars als 'dropzone' angeben (im Gegensatz zu nur dem Eingabeelement). Das bedeutet dann, dass meine gesamte Form zur Dropzone wird. Ist es möglich, die Dropzone nur in einem Teil meiner Form zu verwenden, d. H. Indem Sie nur das Element als Klasse Dropzone und nicht als ganze Form angeben?

Ich könnte separate Formulare verwenden, aber ich möchte, dass der Benutzer alles mit einer einzigen Schaltfläche senden kann.

Gibt es eine andere Bibliothek, die dies tun kann?

Danke vielmals

146
Ben Thompson

Hier ist eine andere Möglichkeit: Fügen Sie eine div in Ihrem Formular mit einem Klassennamen Dropzone hinzu und implementieren Sie Dropzone programmgesteuert.

HTML: 

<div id="dZUpload" class="dropzone">
      <div class="dz-default dz-message"></div>
</div>

JQuery: 

$(document).ready(function () {
    Dropzone.autoDiscover = false;
    $("#dZUpload").dropzone({
        url: "hn_SimpeFileUploader.ashx",
        addRemoveLinks: true,
        success: function (file, response) {
            var imgName = response;
            file.previewElement.classList.add("dz-success");
            console.log("Successfully uploaded :" + imgName);
        },
        error: function (file, response) {
            file.previewElement.classList.add("dz-error");
        }
    });
});

Hinweis: Deaktivieren von AutoDiscover. Andernfalls versucht Dropzone zweimal, eine Verbindung herzustellen

Blogartikel: Dropzone js + Asp.net: Einfache Möglichkeit, Bulk-Bilder hochzuladen

53
Satinder singh

Ich hatte genau das gleiche Problem und stellte fest, dass Varan Sinayees Antwort die einzige war, die die ursprüngliche Frage tatsächlich gelöst hat. Diese Antwort kann jedoch vereinfacht werden, also hier eine einfachere Version.

Die Schritte sind:

  1. Erstellen Sie ein normales Formular (vergessen Sie nicht die Methode und die Argumente, da dies nicht mehr von dropzone gehandhabt wird).

  2. Geben Sie ein Div mit class="dropzone" (so fügen Sie Dropzone an es an) und id="yourDropzoneName" (zum Ändern der Optionen) ein.

  3. Legen Sie die Dropzone-Optionen fest, um die URL festzulegen, an der das Formular und die Dateien gepostet werden sollen. Deaktivieren Sie autoProcessQueue (dies geschieht nur, wenn der Benutzer auf "Abschicken" klickt) und lässt mehrere Uploads zu (falls erforderlich).

  4. Stellen Sie die init-Funktion so ein, dass Dropzone anstelle des Standardverhaltens verwendet wird, wenn Sie auf die Schaltfläche "Senden" klicken.

  5. Verwenden Sie noch in der init-Funktion die Ereignisbehandlungsroutine "sendmultiple", um die Formulardaten zusammen mit den Dateien zu senden.

Voilà! Sie können die Daten jetzt wie in einem normalen Formular in $ _POST und $ _FILES abrufen (im Beispiel würde dies in upload.php passieren)

HTML

<form action="upload.php" enctype="multipart/form-data" method="POST">
    <input type="text" id ="firstname" name ="firstname" />
    <input type="text" id ="lastname" name ="lastname" />
    <div class="dropzone" id="myDropzone"></div>
    <button type="submit" id="submit-all"> upload </button>
</form>

JS

Dropzone.options.myDropzone= {
    url: 'upload.php',
    autoProcessQueue: false,
    uploadMultiple: true,
    parallelUploads: 5,
    maxFiles: 5,
    maxFilesize: 1,
    acceptedFiles: 'image/*',
    addRemoveLinks: true,
    init: function() {
        dzClosure = this; // Makes sure that 'this' is understood inside the functions below.

        // for Dropzone to process the queue (instead of default form behavior):
        document.getElementById("submit-all").addEventListener("click", function(e) {
            // Make sure that the form isn't actually being sent.
            e.preventDefault();
            e.stopPropagation();
            dzClosure.processQueue();
        });

        //send all the form data along with the files:
        this.on("sendingmultiple", function(data, xhr, formData) {
            formData.append("firstname", jQuery("#firstname").val());
            formData.append("lastname", jQuery("#lastname").val());
        });
    }
}
28
mrtnmgs

"Dropzone.js" ist die am häufigsten verwendete Bibliothek zum Hochladen von Bildern . Wenn Sie "dropzone.js" nur als Teil Ihres Formulars anzeigen möchten, sollten Sie die folgenden Schritte ausführen:

1) für die Kundenseite:

HTML:

    <form action="/" enctype="multipart/form-data" method="POST">
        <input type="text" id ="Username" name ="Username" />
        <div class="dropzone" id="my-dropzone" name="mainFileUploader">
            <div class="fallback">
                <input name="file" type="file" multiple />
            </div>
        </div>
    </form>
    <div>
        <button type="submit" id="submit-all"> upload </button>
    </div>

JQuery:

    <script>
        Dropzone.options.myDropzone = {
            url: "/Account/Create",
            autoProcessQueue: false,
            uploadMultiple: true,
            parallelUploads: 100,
            maxFiles: 100,
            acceptedFiles: "image/*",

            init: function () {

                var submitButton = document.querySelector("#submit-all");
                var wrapperThis = this;

                submitButton.addEventListener("click", function () {
                    wrapperThis.processQueue();
                });

                this.on("addedfile", function (file) {

                    // Create the remove button
                    var removeButton = Dropzone.createElement("<button class='btn btn-lg dark'>Remove File</button>");

                    // Listen to the click event
                    removeButton.addEventListener("click", function (e) {
                        // Make sure the button click doesn't submit the form:
                        e.preventDefault();
                        e.stopPropagation();

                        // Remove the file preview.
                        wrapperThis.removeFile(file);
                        // If you want to the delete the file on the server as well,
                        // you can do the AJAX request here.
                    });

                    // Add the button to the file preview element.
                    file.previewElement.appendChild(removeButton);
                });

                this.on('sendingmultiple', function (data, xhr, formData) {
                    formData.append("Username", $("#Username").val());
                });
            }
        };
    </script>

2) für die Serverseite:

ASP.Net MVC

    [HttpPost]
    public ActionResult Create()
    {
        var postedUsername = Request.Form["Username"].ToString();
        foreach (var imageFile in Request.Files)
        {

        }

        return Json(new { status = true, Message = "Account created." });
    }
17
Varan Sinayee

Enyos Tutorial ist ausgezeichnet.

Ich fand, dass das Beispielskript im Tutorial für eine in die Dropzone eingebettete Schaltfläche (d. H. Das Formularelement) gut funktioniert hat. Wenn Sie die Schaltfläche außerhalb des Formularelements haben möchten, konnte ich sie mit einem Klickereignis ausführen:

Zuerst das HTML:

<form id="my-awesome-dropzone" action="/upload" class="dropzone">  
    <div class="dropzone-previews"></div>
    <div class="fallback"> <!-- this is the fallback if JS isn't working -->
        <input name="file" type="file" multiple />
    </div>

</form>
<button type="submit" id="submit-all" class="btn btn-primary btn-xs">Upload the file</button>

Dann das Skript-Tag ....

Dropzone.options.myAwesomeDropzone = { // The camelized version of the ID of the form element

    // The configuration we've talked about above
    autoProcessQueue: false,
    uploadMultiple: true,
    parallelUploads: 25,
    maxFiles: 25,

    // The setting up of the dropzone
    init: function() {
        var myDropzone = this;

        // Here's the change from enyo's tutorial...

        $("#submit-all").click(function (e) {
            e.preventDefault();
            e.stopPropagation();
            myDropzone.processQueue();
        }); 
    }
}
11
kablamus

Zusätzlich zu dem, was sqram gesagt hat, hat Dropzone die zusätzliche undokumentierte Option "hiddenInputContainer". Alles, was Sie tun müssen, ist, diese Option auf den Selektor des Formulars zu setzen, an das das ausgeblendete Dateifeld angehängt werden soll. Und voila! Das ".dz-hidden-input" -Dateifeld, das Dropzone normalerweise dem Körper hinzufügt, bewegt sich auf magische Weise in Ihr Formular. Keine Änderung des Dropzone-Quellcodes.

Während dies funktioniert, um das Dropzone-Dateifeld in Ihr Formular zu verschieben, hat das Feld keinen Namen. Sie müssen also hinzufügen:

_this.hiddenFileInput.setAttribute("name", "field_name[]");

nach dropzone.js nach dieser Zeile:

_this.hiddenFileInput = document.createElement("input");

um die Linie 547 herum.

4
Codedragon

Sie können formData ändern, indem Sie das 'sendende' Ereignis aus Ihrer Dropzone abrufen.

dropZone.on('sending', function(data, xhr, formData){
        formData.append('fieldname', 'value');
});
4
shawnrushefsky

Um alle Dateien zusammen mit anderen Formulardaten in einer einzigen Anforderung zu übermitteln, können Sie die temporären verborgenen input-Knoten von Dropzone.js in Ihr Formular kopieren. Sie können dies innerhalb der addedfiles-Ereignisprozedur tun:

var myDropzone = new Dropzone("myDivSelector", { url: "#", autoProcessQueue: false });
myDropzone.on("addedfiles", () => {
  // Input node with selected files. It will be removed from document shortly in order to
  // give user ability to choose another set of files.
  var usedInput = myDropzone.hiddenFileInput;
  // Append it to form after stack become empty, because if you append it earlier
  // it will be removed from its parent node by Dropzone.js.
  setTimeout(() => {
    // myForm - is form node that you want to submit.
    myForm.appendChild(usedInput);
    // Set some unique name in order to submit data.
    usedInput.name = "foo";
  }, 0);
});

Offensichtlich ist dies eine Problemlösung, die von den Implementierungsdetails abhängig ist. Zugehöriger Quellcode .

3
Leonid Vasilev

Ich habe dafür eine automatisiertere Lösung. 

HTML:

<form role="form" enctype="multipart/form-data" action="{{ $url }}" method="{{ $method }}">
    {{ csrf_field() }}

    <!-- You can add extra form fields here -->

    <input hidden id="file" name="file"/>

    <!-- You can add extra form fields here -->

    <div class="dropzone dropzone-file-area" id="fileUpload">
        <div class="dz-default dz-message">
            <h3 class="sbold">Drop files here to upload</h3>
            <span>You can also click to open file browser</span>
        </div>
    </div>

    <!-- You can add extra form fields here -->

    <button type="submit">Submit</button>
</form>

JavaScript:

Dropzone.options.fileUpload = {
    url: 'blackHole.php',
    addRemoveLinks: true,
    accept: function(file) {
        let fileReader = new FileReader();

        fileReader.readAsDataURL(file);
        fileReader.onloadend = function() {

            let content = fileReader.result;
            $('#file').val(content);
            file.previewElement.classList.add("dz-success");
        }
        file.previewElement.classList.add("dz-complete");
    }
}

Laravel:

// Get file content
$file = base64_decode(request('file'));

Die DropZone Discovery muss nicht deaktiviert werden, und das normale Formularsenden kann die Datei mit allen anderen Formularfeldern über die Standardformularserialisierung senden. 

Dieser Mechanismus speichert den Dateiinhalt als base64-String im verborgenen Eingabefeld, wenn er verarbeitet wird. Sie können es in PHP durch die Standardmethode base64_decode() wieder in eine Binärzeichenfolge decodieren.

Ich weiß nicht, ob diese Methode mit großen Dateien kompromittiert wird, aber sie funktioniert mit ~ 40 MB-Dateien. 

3
Umair Ahmed

Dies ist nur ein weiteres Beispiel für die Verwendung von Dropzone.js in einem vorhandenen Formular. 

dropzone.js:

 init: function() {

   this.on("success", function(file, responseText) {
     //alert("HELLO ?" + responseText); 
     mylittlefix(responseText);
   });

   return noop;
 },

Dann stelle ich später in die Datei 

function mylittlefix(responseText) {
  $('#botofform').append('<input type="hidden" name="files[]" value="'+ responseText +'">');
}

Dies setzt voraus, dass Sie ein div mit der ID #botofform haben. Auf diese Weise können Sie beim Hochladen die Namen der hochgeladenen Dateien verwenden. 

Hinweis: Mein Upload-Skript hat theuploadedfilename.jpeg Dubblenote zurückgegeben. Sie müssten außerdem ein Bereinigungsskript erstellen, das das Upload-Verzeichnis auf nicht verwendete Dateien überprüft und diese löscht.

0
taggart

Hier ist mein Beispiel, basiert auf Django + Dropzone. View hat select (erforderlich) und abschicken.

<form action="/share/upload/" class="dropzone" id="uploadDropzone">
    {% csrf_token %}
        <select id="warehouse" required>
            <option value="">Select a warehouse</option>
                {% for warehouse in warehouses %}
                    <option value={{forloop.counter0}}>{{warehouse.warehousename}}</option>
                {% endfor %}
        </select>
    <button id="submit-upload btn" type="submit">upload</button>
</form>

<script src="{% static '/js/libs/dropzone/dropzone.js' %}"></script>
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script>
    var filename = "";

    Dropzone.options.uploadDropzone = {
        paramName: "file",  // The name that will be used to transfer the file,
        maxFilesize: 250,   // MB
        autoProcessQueue: false,
        accept: function(file, done) {
            console.log(file.name);
            filename = file.name;
            done();    // !Very important
        },
        init: function() {
            var myDropzone = this,
            submitButton = document.querySelector("[type=submit]");

            submitButton.addEventListener('click', function(e) {
                var isValid = document.querySelector('#warehouse').reportValidity();
                e.preventDefault();
                e.stopPropagation();
                if (isValid)
                    myDropzone.processQueue();
            });

            this.on('sendingmultiple', function(data, xhr, formData) {
                formData.append("warehouse", jQuery("#warehouse option:selected").val());
            });
        }
    };
</script>
0
smartworld-dm