dropzone.js - how to do something after ALL files are uploaded
Asked Answered
R

9

62

I am using dropzone.js for my drag-drop file upload solution. I am stuck at something where I need to call a function after all the files are uploaded. In this case,

Dropzone.options.filedrop = {
    maxFilesize: 4096,
    init: function () {
        this.on("complete", function (file) {
            doSomething();
        });
    }
};

doSomething() will be called for each file that has been uploaded. How can I call a function after all the files are uploaded?

Rhyme answered 8/6, 2013 at 10:13 Comment(0)
S
134

EDIT: There is now a queuecomplete event that you can use for exactly that purpose.


Previous answer:

Paul B.'s answer works, but an easier way to do so, is by checking if there are still files in the queue or uploading whenever a file completes. This way you don't have to keep track of the files yourself:

Dropzone.options.filedrop = {
  init: function () {
    this.on("complete", function (file) {
      if (this.getUploadingFiles().length === 0 && this.getQueuedFiles().length === 0) {
        doSomething();
      }
    });
  }
};
Stung answered 24/6, 2013 at 12:55 Comment(9)
@Emin Fair enough :) Actually, that's good, b/c this IS the better solution. And makes a better use of the API.Parthia
I'd like to add that in the mean time there is an additional event called queuecomplete that fires when the queue is finished uploading.Hannahannah
Also, don't forget to check for any files in an ERROR state (ie bad file type, size, etc). See my answer, below, for a new function to check that.Lientery
Just an fyi, "finished uploading" for queuecomplete fires even if the uploaded file is rejected due to a server-side validation error, so it isn't the same as making sure that the uploaded files are actually successful.Croaky
Work like a charm!Phobia
queuecomplete did it for meSheela
@Stung could you please reconsider your answer after the comment from https://mcmap.net/q/319817/-dropzone-js-how-to-do-something-after-all-files-are-uploadedRhyme
i want to show the files uploaded by the dropzone is it a possible to do an ajax get call inside the complete event ?Serious
queuecomplete gets fired for each batch and will only work if you disable the parallelUploads option. this.getActiveFiles() is a better option because it queries queued and uploading in one method. src: github.com/dropzone/dropzone/blob/…Veneaux
M
48

Just use queuecomplete that's what its there for and its so so simple. Check the docs http://www.dropzonejs.com/

queuecomplete > Called when all files in the queue finished uploading.

      this.on("queuecomplete", function (file) {
          alert("All files have uploaded ");
      });
Merwyn answered 30/9, 2014 at 6:33 Comment(2)
Does anyone know if this should fire for each file in the queue? That is the behaviour I'm experiencing.Yeah
For me with dropzone 5.3 it fires once after the queue has been emptied (aka all files been uploaded)Billiards
P
12

There is probably a way (or three) to do this... however, I see one issue with your goal: how do you know when all the files have been uploaded? To rephrase in a way that makes more sense... how do you know what "all" means? According to the documentation, init gets called at the initialization of the Dropzone itself, and then you set up the complete event handler to do something when each file that's uploaded is complete. But, what mechanism is the user given to allow the program to know when he's dropped all the files he's intended to drop? If you are assuming that he/she will do a batch drop (i.e., drop onto the Dropzone 2-whatever number of files, at once, in one drop action), then the following code could/possibly should work:

Dropzone.options.filedrop = {
    maxFilesize: 4096,
    init: function () {
        var totalFiles = 0,
            completeFiles = 0;
        this.on("addedfile", function (file) {
            totalFiles += 1;
        });
        this.on("removed file", function (file) {
            totalFiles -= 1;
        });
        this.on("complete", function (file) {
            completeFiles += 1;
            if (completeFiles === totalFiles) {
                doSomething();
            }
        });
    }
};

Basically, you watch any time someone adds/removes files from the Dropzone, and keep a count in closure variables. Then, when each file download is complete, you increment the completeFiles progress counter var, and see if it now equals the totalCount you'd been watching and updating as the user placed things in the Dropzone. (Note: never used the plug-in/JS lib., so this is best guess as to what you could do to get what you want.)

Parthia answered 8/6, 2013 at 12:26 Comment(2)
Cool, I thought of a counter too, but I got confused about the scope of the variable and how long it will be alive etc.,Lacour
Add another condition when the totalFiles is already 0 or else you could get negative totalFiles value.Northbound
D
5

A 'queuecomplete' event has been added. See Issue 317.

Danedanegeld answered 18/2, 2014 at 20:49 Comment(0)
M
4
this.on("totaluploadprogress", function(totalBytes, totalBytesSent){


                    if(totalBytes == 100) {

                        //all done! call func here
                    }
                });
Marlo answered 13/2, 2014 at 0:5 Comment(0)
I
4

I up-voted you as your method is simple. I did make only a couple of slight amends as sometimes the event fires even though there are no bytes to send - On my machine it did it when I clicked the remove button on a file.

myDropzone.on("totaluploadprogress", function(totalPercentage, totalBytesToBeSent, totalBytesSent ){
            if(totalPercentage >= 100 && totalBytesSent) {
                // All done! Call func here
            }
        });
Interactive answered 10/4, 2014 at 4:32 Comment(0)
L
2

In addition to @enyo's answer in checking for files that are still uploading or in the queue, I also created a new function in dropzone.js to check for any files in an ERROR state (ie bad file type, size, etc).

Dropzone.prototype.getErroredFiles = function () {
    var file, _i, _len, _ref, _results;
    _ref = this.files;
    _results = [];
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        file = _ref[_i];
        if (file.status === Dropzone.ERROR) {
            _results.push(file);
        }
    }
    return _results;
};

And thus, the check would become:

  if (this.getUploadingFiles().length === 0 && this.getQueuedFiles().length === 0 && this.getErroredFiles().length === 0) {
    doSomething();
  }
Lientery answered 9/9, 2014 at 17:28 Comment(0)
R
2

I was trying to work with that solutions but it doesn't work. But later I was realize that the function it wasn't declared so I watch in to the dropzone.com page and take the example to call events. So finally work on my site. For those like me who don't understand JavaScript very well, I leave you the example.

<script type="text/javascript" src="/js/dropzone.js"></script>
<script type="text/javascript">
// This example uses jQuery so it creates the Dropzone, only when the DOM has
// loaded.

// Disabling autoDiscover, otherwise Dropzone will try to attach twice.
Dropzone.autoDiscover = false;
// or disable for specific dropzone:
// Dropzone.options.myDropzone = false;

$(function() {
  // Now that the DOM is fully loaded, create the dropzone, and setup the
  // event listeners
  var myDropzone = new Dropzone(".dropzone");

  myDropzone.on("queuecomplete", function(file, res) {
      if (myDropzone.files[0].status != Dropzone.SUCCESS ) {
          alert('yea baby');
      } else {
          alert('cry baby');

      }
  });
});
</script>
Roundly answered 15/12, 2016 at 18:50 Comment(1)
You should invert the test condition: if (myDropzone.files[0].status != Dropzone.SUCCESS ) THEN alert('cry baby'); ELSE alert('yeah baby');Kurtzig
H
0

The accepted answer is not necessarily correct. queuecomplete will be called even when the selected file is larger than the max file size.

The proper event to use is successmultiple or completemultiple.

Reference: http://www.dropzonejs.com/#event-successmultiple

Honesty answered 30/5, 2018 at 4:11 Comment(2)
At the time the accepted answer was selected, the queuecomplete event did not exist yet.Pause
@Pause I meant though that queuecompleted is not the the most proper event.Honesty

© 2022 - 2024 — McMap. All rights reserved.