34

upload all files with a single button click.
HTML:

<button id="submit-all">Submit all files</button>
<form action="/target" class="dropzone" id="my-dropzone"></form>

JS:

Dropzone.options.myDropzone = {

  // Prevents Dropzone from uploading dropped files immediately
  autoProcessQueue: false,

  init: function() {
    var submitButton = document.querySelector("#submit-all")
        myDropzone = this; // closure

    submitButton.addEventListener("click", function() {
      myDropzone.processQueue(); // Tell Dropzone to process all queued files.
    });

    // You might want to show the submit button only when 
    // files are dropped here:
    this.on("addedfile", function() {
      // Show submit button here and/or inform user to click it.
    });

  }
};

But the file is upload after drag and drop..

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
Steve Bals
  • 1,949
  • 6
  • 22
  • 32

6 Answers6

55

use simple code

Dropzone.autoDiscover = false;

var myDropzone = new Dropzone(element, {
  url: "/upload.php",                        
  autoProcessQueue: false,
});

$('#imgsubbutt').click(function(){           
  myDropzone.processQueue();
});
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
Behnam
  • 6,244
  • 1
  • 39
  • 36
  • 3
    This is very clean approach of doing this. But you missed following line before this code. Dropzone.autoDiscover = false; If we don't add this, we will get error, something like "Dropzone already attached" – Riz Sep 09 '14 at 21:23
  • What's `element` in the `new Dropzone...` line? – gokul_uf Dec 19 '16 at 11:23
  • 1
    gokul_uf element is DOM – Behnam Feb 14 '17 at 11:30
  • 1
    For anyone stumped by the DOM element bit - jQuery doesn't return native DOM elements by default so you need to tell it to by adding `get(0)` like so: `$('#myDropzone').get(0)` - see here for more info: https://learn.jquery.com/using-jquery-core/faq/how-do-i-pull-a-native-dom-element-from-a-jquery-object/ – Bananaapple Nov 20 '18 at 12:13
21

I accomplished this by placing my dropzone in a div instead of a form, thereby removing the ability for dropzone to automatically POST the uploads to a given URL. The URL I passed to the dropzone instance when I created it is literally 'dummy' since it will never be called. For example, HTML

<button id="submit-all">Submit all files</button>
<div class="dropzone" id="my-dropzone"></div>

JavaScript

$('#submit-all').on('click', function() {
    var files = $('#my-dropzone').get(0).dropzone.getAcceptedFiles();
    // Do something with the files.
});
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
eeuser
  • 251
  • 2
  • 3
3

Here how i implement delayed uploading (initiated by click on any button, for an example):

Dropzone implementation

var count = 0;
var addedFilesHash = {};
var myDropzone = new Dropzone("#file_upload-form", {
    paramName: "file", // The name that will be used to transfer the file
    addRemoveLinks: true,
    maxFilesize: 5, // MB
    parallelUploads: 5,
    uploadMultiple: true,
    acceptedFiles: "image/*,.xlsx,.xls,.pdf,.doc,.docx",
    maxFiles: 10,
    init: function() {
        this.on("removedfile", function (file) {
            // delete from our dict removed file
            delete addedFilesHash[file];
        });
    },
    accept: function(file, done) {
        var _id = count++;
        file._id = _id;
        addedFilesHash[_id] = done;
    }
});

Somewhere else

    // get all uploaded files in array
    var addedFiles = Object.keys(addedFilesHash);
    // iterate them
    for (var i = 0; i< addedFiles.length; i++) {
        // get file obj
        var addedFile = addedFiles[i];
        // get done function
        var doneFile = addedFilesHash[addedFile];
        // call done function to upload file to server
        doneFile();
    }

We override accept and removedFile functions. In accept function we collect file objects and done functions in dict where key is file and value is done function. Later in time, when we are ready to upload added files, we are iterating all done functions for all files in dict addedFilesHash which launches upload progress with progress bar and etc.

dikkini
  • 1,184
  • 1
  • 23
  • 52
2

I got just finished messing around with this myself- I wanted to add information about the image to a database at the same time as uploading it. Dropping a file opens the input form for the extra info and then the queue needs sending after the form button is pressed.

I finally achieved this by putting a jquery click event handler inside the init 'on add file' function event:

this.on("addedfile", function(file){
  var myDropzone = this;
  $('#imageinfoCont').animate({left:'4.5%'});//brings form in
  $('#imgsubbutt').click(function(){
    $('#imageinfoCont').animate({left:'-10000px'}); //hides the form again
    myDropzone.processQueue(); //processes the queue
  });
});

I am then adding the extra data in a separate 'on sending' function event (could probably do it in the above code but baby steps I think).

Seems to work like a charm.

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
  • If you add multiple files, you are re-attaching `click` to each one. If you add two files, you will call myDropzone.processQueue twice. Write a `console.log` within the click method and see if it attaches twice. – dansch Feb 20 '17 at 15:16
1

Although this has been answered, I ran into a situation where I only wanted to submit the queue IF it was a certain type of file. The bug I ran into was it was ignoring processQueue.

  this.dropzone = new Dropzone('#my-dropzone', {
    autoProcessQueue: false,
  });
  return this.dropzone.on('addedfile', (function(_this) {
    return function(file) {

      var IMAGE_EXTENSIONS, ext;
      IMAGE_EXTENSIONS = 'png jpg jpeg gif'.split(' ');
      ext = (_.last(file.name.split('.'))).toLowerCase();

      if (_.include(IMAGE_EXTENSIONS, ext)) {
        return console.log('IMAGE!');
      } else {

        return setTimeout(function() { // HERE!!!!!!!!!!!!!!!!!!!!
          return _this.dropzone.processQueue();
        }, 10);
      }
    };
  })(this));

I had to use the setTimeout seen above because processQueue did nothing if I didn't defer it in this manner.

dansch
  • 6,059
  • 4
  • 43
  • 59
0

Working example

Dropzone.autoDiscover = false;

var myDropzone = new Dropzone('.dropzone-file', {
url: "https://keenthemes.com/scripts/void.php", // Set the url for your upload script location
paramName: "file", // The name that will be used to transfer the file
addRemoveLinks: true,
uploadMultiple: true,
autoProcessQueue: false,
});

$('.upload-files').on('click', function() {
var files = $('.dropzone-file').get(0).dropzone.getAcceptedFiles();

//upload bar
$('.dz-upload').addClass('dz-progress-bar');

// Do something with the files.
console.log(files)
});
.dropzone-file{
border: 1px dashed green;
padding: 1%;
text-align: center;
}
.dropzone-file:hover{
cursor:pointer;
background:whitesmoke;
}
@-webkit-keyframes passing-through {
    0% {
        opacity: 0;
        -webkit-transform: translateY(40px);
        -moz-transform: translateY(40px);
        -ms-transform: translateY(40px);
        -o-transform: translateY(40px);
        transform: translateY(40px);
    }
    30%,
    70% {
        opacity: 1;
        -webkit-transform: translateY(0px);
        -moz-transform: translateY(0px);
        -ms-transform: translateY(0px);
        -o-transform: translateY(0px);
        transform: translateY(0px);
    }
    100% {
        opacity: 0;
        -webkit-transform: translateY(-40px);
        -moz-transform: translateY(-40px);
        -ms-transform: translateY(-40px);
        -o-transform: translateY(-40px);
        transform: translateY(-40px);
    }
}
@-moz-keyframes passing-through {
    0% {
        opacity: 0;
        -webkit-transform: translateY(40px);
        -moz-transform: translateY(40px);
        -ms-transform: translateY(40px);
        -o-transform: translateY(40px);
        transform: translateY(40px);
    }
    30%,
    70% {
        opacity: 1;
        -webkit-transform: translateY(0px);
        -moz-transform: translateY(0px);
        -ms-transform: translateY(0px);
        -o-transform: translateY(0px);
        transform: translateY(0px);
    }
    100% {
        opacity: 0;
        -webkit-transform: translateY(-40px);
        -moz-transform: translateY(-40px);
        -ms-transform: translateY(-40px);
        -o-transform: translateY(-40px);
        transform: translateY(-40px);
    }
}
@keyframes passing-through {
    0% {
        opacity: 0;
        -webkit-transform: translateY(40px);
        -moz-transform: translateY(40px);
        -ms-transform: translateY(40px);
        -o-transform: translateY(40px);
        transform: translateY(40px);
    }
    30%,
    70% {
        opacity: 1;
        -webkit-transform: translateY(0px);
        -moz-transform: translateY(0px);
        -ms-transform: translateY(0px);
        -o-transform: translateY(0px);
        transform: translateY(0px);
    }
    100% {
        opacity: 0;
        -webkit-transform: translateY(-40px);
        -moz-transform: translateY(-40px);
        -ms-transform: translateY(-40px);
        -o-transform: translateY(-40px);
        transform: translateY(-40px);
    }
}
@-webkit-keyframes slide-in {
    0% {
        opacity: 0;
        -webkit-transform: translateY(40px);
        -moz-transform: translateY(40px);
        -ms-transform: translateY(40px);
        -o-transform: translateY(40px);
        transform: translateY(40px);
    }
    30% {
        opacity: 1;
        -webkit-transform: translateY(0px);
        -moz-transform: translateY(0px);
        -ms-transform: translateY(0px);
        -o-transform: translateY(0px);
        transform: translateY(0px);
    }
}
@-moz-keyframes slide-in {
    0% {
        opacity: 0;
        -webkit-transform: translateY(40px);
        -moz-transform: translateY(40px);
        -ms-transform: translateY(40px);
        -o-transform: translateY(40px);
        transform: translateY(40px);
    }
    30% {
        opacity: 1;
        -webkit-transform: translateY(0px);
        -moz-transform: translateY(0px);
        -ms-transform: translateY(0px);
        -o-transform: translateY(0px);
        transform: translateY(0px);
    }
}
@keyframes slide-in {
    0% {
        opacity: 0;
        -webkit-transform: translateY(40px);
        -moz-transform: translateY(40px);
        -ms-transform: translateY(40px);
        -o-transform: translateY(40px);
        transform: translateY(40px);
    }
    30% {
        opacity: 1;
        -webkit-transform: translateY(0px);
        -moz-transform: translateY(0px);
        -ms-transform: translateY(0px);
        -o-transform: translateY(0px);
        transform: translateY(0px);
    }
}
@-webkit-keyframes pulse {
    0% {
        -webkit-transform: scale(1);
        -moz-transform: scale(1);
        -ms-transform: scale(1);
        -o-transform: scale(1);
        transform: scale(1);
    }
    10% {
        -webkit-transform: scale(1.1);
        -moz-transform: scale(1.1);
        -ms-transform: scale(1.1);
        -o-transform: scale(1.1);
        transform: scale(1.1);
    }
    20% {
        -webkit-transform: scale(1);
        -moz-transform: scale(1);
        -ms-transform: scale(1);
        -o-transform: scale(1);
        transform: scale(1);
    }
}
@-moz-keyframes pulse {
    0% {
        -webkit-transform: scale(1);
        -moz-transform: scale(1);
        -ms-transform: scale(1);
        -o-transform: scale(1);
        transform: scale(1);
    }
    10% {
        -webkit-transform: scale(1.1);
        -moz-transform: scale(1.1);
        -ms-transform: scale(1.1);
        -o-transform: scale(1.1);
        transform: scale(1.1);
    }
    20% {
        -webkit-transform: scale(1);
        -moz-transform: scale(1);
        -ms-transform: scale(1);
        -o-transform: scale(1);
        transform: scale(1);
    }
}
@keyframes pulse {
    0% {
        -webkit-transform: scale(1);
        -moz-transform: scale(1);
        -ms-transform: scale(1);
        -o-transform: scale(1);
        transform: scale(1);
    }
    10% {
        -webkit-transform: scale(1.1);
        -moz-transform: scale(1.1);
        -ms-transform: scale(1.1);
        -o-transform: scale(1.1);
        transform: scale(1.1);
    }
    20% {
        -webkit-transform: scale(1);
        -moz-transform: scale(1);
        -ms-transform: scale(1);
        -o-transform: scale(1);
        transform: scale(1);
    }
}
.dropzone-file,
.dropzone-file * {
    box-sizing: border-box;
}
.dropzone-file {
    min-height: 150px;
    border: 2px solid rgba(0, 0, 0, 0.3);
    background: #fff;
    padding: 20px 20px;
}
.dropzone-file.dz-clickable {
    cursor: pointer;
}
.dropzone-file.dz-clickable * {
    cursor: default;
}
.dropzone-file.dz-clickable .dz-message,
.dropzone-file.dz-clickable .dz-message * {
    cursor: pointer;
}
.dropzone-file.dz-started .dz-message {
    display: none;
}
.dropzone-file.dz-drag-hover {
    border-style: solid;
}
.dropzone-file.dz-drag-hover .dz-message {
    opacity: 0.5;
}
.dropzone-file .dz-message {
    text-align: center;
    margin: 2em 0;
}
.dropzone-file .dz-message .dz-button {
    background: none;
    color: inherit;
    border: none;
    padding: 0;
    font: inherit;
    cursor: pointer;
    outline: inherit;
}
.dropzone-file .dz-preview {
    position: relative;
    display: inline-block;
    vertical-align: top;
    margin: 16px;
    min-height: 100px;
}
.dropzone-file .dz-preview:hover {
    z-index: 1000;
}
.dropzone-file .dz-preview:hover .dz-details {
    opacity: 1;
}
.dropzone-file .dz-preview.dz-file-preview .dz-image {
    border-radius: 20px;
    background: #999;
    background: linear-gradient(to bottom, #eee, #ddd);
}
.dropzone-file .dz-preview.dz-file-preview .dz-details {
    opacity: 1;
}
.dropzone-file .dz-preview.dz-image-preview {
    background: #fff;
}
.dropzone-file .dz-preview.dz-image-preview .dz-details {
    -webkit-transition: opacity 0.2s linear;
    -moz-transition: opacity 0.2s linear;
    -ms-transition: opacity 0.2s linear;
    -o-transition: opacity 0.2s linear;
    transition: opacity 0.2s linear;
}
.dropzone-file .dz-preview .dz-remove {
    font-size: 14px;
    text-align: center;
    display: block;
    cursor: pointer;
    border: none;
}
.dropzone-file .dz-preview .dz-remove:hover {
    text-decoration: underline;
}
.dropzone-file .dz-preview:hover .dz-details {
    opacity: 1;
}
.dropzone-file .dz-preview .dz-details {
    z-index: 20;
    position: absolute;
    top: 0;
    left: 0;
    opacity: 0;
    font-size: 13px;
    min-width: 100%;
    max-width: 100%;
    padding: 2em 1em;
    text-align: center;
    color: rgba(0, 0, 0, 0.9);
    line-height: 150%;
}
.dropzone-file .dz-preview .dz-details .dz-size {
    margin-bottom: 1em;
    font-size: 16px;
}
.dropzone-file .dz-preview .dz-details .dz-filename {
    white-space: nowrap;
}
.dropzone-file .dz-preview .dz-details .dz-filename:hover span {
    border: 1px solid rgba(200, 200, 200, 0.8);
    background-color: rgba(255, 255, 255, 0.8);
}
.dropzone-file .dz-preview .dz-details .dz-filename:not(:hover) {
    overflow: hidden;
    text-overflow: ellipsis;
}
.dropzone-file .dz-preview .dz-details .dz-filename:not(:hover) span {
    border: 1px solid transparent;
}
.dropzone-file .dz-preview .dz-details .dz-filename span,
.dropzone-file .dz-preview .dz-details .dz-size span {
    background-color: rgba(255, 255, 255, 0.4);
    padding: 0 0.4em;
    border-radius: 3px;
}
.dropzone-file .dz-preview:hover .dz-image img {
    -webkit-transform: scale(1.05, 1.05);
    -moz-transform: scale(1.05, 1.05);
    -ms-transform: scale(1.05, 1.05);
    -o-transform: scale(1.05, 1.05);
    transform: scale(1.05, 1.05);
    -webkit-filter: blur(8px);
    filter: blur(8px);
}
.dropzone-file .dz-preview .dz-image {
    border-radius: 20px;
    overflow: hidden;
    width: 120px;
    height: 120px;
    position: relative;
    display: block;
    z-index: 10;
}
.dropzone-file .dz-preview .dz-image img {
    display: block;
}
.dropzone-file .dz-preview.dz-success .dz-success-mark {
    -webkit-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
    -moz-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
    -ms-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
    -o-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
    animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
}
.dropzone-file .dz-preview.dz-error .dz-error-mark {
    opacity: 1;
    -webkit-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
    -moz-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
    -ms-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
    -o-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
    animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
}
.dropzone-file .dz-preview .dz-success-mark,
.dropzone-file .dz-preview .dz-error-mark {
    pointer-events: none;
    opacity: 0;
    z-index: 500;
    position: absolute;
    display: block;
    top: 50%;
    left: 50%;
    margin-left: -27px;
    margin-top: -27px;
}
.dropzone-file .dz-preview .dz-success-mark svg,
.dropzone-file .dz-preview .dz-error-mark svg {
    display: block;
    width: 54px;
    height: 54px;
}
.dropzone-file .dz-preview.dz-processing .dz-progress {
    opacity: 1;
    -webkit-transition: all 0.2s linear;
    -moz-transition: all 0.2s linear;
    -ms-transition: all 0.2s linear;
    -o-transition: all 0.2s linear;
    transition: all 0.2s linear;
}
.dropzone-file .dz-preview.dz-complete .dz-progress {
    opacity: 0;
    -webkit-transition: opacity 0.4s ease-in;
    -moz-transition: opacity 0.4s ease-in;
    -ms-transition: opacity 0.4s ease-in;
    -o-transition: opacity 0.4s ease-in;
    transition: opacity 0.4s ease-in;
}
.dropzone-file .dz-preview:not(.dz-processing) .dz-progress {
    -webkit-animation: pulse 6s ease infinite;
    -moz-animation: pulse 6s ease infinite;
    -ms-animation: pulse 6s ease infinite;
    -o-animation: pulse 6s ease infinite;
    animation: pulse 6s ease infinite;
}
.dropzone-file .dz-preview .dz-progress {
    opacity: 1;
    z-index: 1000;
    pointer-events: none;
    position: absolute;
    height: 16px;
    left: 50%;
    top: 50%;
    margin-top: -8px;
    width: 80px;
    margin-left: -40px;
    background: rgba(255, 255, 255, 0.9);
    -webkit-transform: scale(1);
    border-radius: 8px;
    overflow: hidden;
}
.dropzone-file .dz-preview .dz-progress .dz-upload {
    background: #333;
    background: linear-gradient(to bottom, #666, #444);
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    width: 0;
    -webkit-transition: width 300ms ease-in-out;
    -moz-transition: width 300ms ease-in-out;
    -ms-transition: width 300ms ease-in-out;
    -o-transition: width 300ms ease-in-out;
    transition: width 300ms ease-in-out;
}
.dropzone-file .dz-preview.dz-error .dz-error-message {
    display: block;
}
.dropzone-file .dz-preview.dz-error:hover .dz-error-message {
    opacity: 1;
    pointer-events: auto;
}
.dropzone-file .dz-preview .dz-error-message {
    pointer-events: none;
    z-index: 1000;
    position: absolute;
    display: block;
    display: none;
    opacity: 0;
    -webkit-transition: opacity 0.3s ease;
    -moz-transition: opacity 0.3s ease;
    -ms-transition: opacity 0.3s ease;
    -o-transition: opacity 0.3s ease;
    transition: opacity 0.3s ease;
    border-radius: 8px;
    font-size: 13px;
    top: 130px;
    left: -10px;
    width: 140px;
    background: #be2626;
    background: linear-gradient(to bottom, #be2626, #a92222);
    padding: 0.5em 1.2em;
    color: #fff;
}
.dropzone-file .dz-preview .dz-error-message:after {
    content: "";
    position: absolute;
    top: -6px;
    left: 64px;
    width: 0;
    height: 0;
    border-left: 6px solid transparent;
    border-right: 6px solid transparent;
    border-bottom: 6px solid #be2626;
}
.dz-progress-bar {
    width: 0;
    animation: progress 1.5s ease-in-out forwards;
  } 
  
  @keyframes progress {
    from {
      width: 0;
    }
    to {
      width: 100%;
    }
  } 
  @keyframes show  {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://unpkg.com/dropzone@5/dist/min/dropzone.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/dropzone@5/dist/min/dropzone.min.css" type="text/css" />

<!--begin::Dropzone-->
<div class="dropzone-file fileuploader">
<!--begin::Message-->
<div class="dz-message needsclick">
<!--begin::Icon-->
<i class="bi bi-file-earmark-arrow-up text-primary fs-3x"></i>
<!--end::Icon-->

<!--begin::Info-->
<div class="ms-4">
<h3 class="fs-5 fw-bolder text-gray-900 mb-1">Drop files here or click to upload.</h3>
<span class="fs-7 fw-bold text-gray-400">Upload any kind of files</span>
</div>
<!--end::Info-->
</div>
</div>
<!--end::Dropzone-->

<button class='upload-files'>Upload Files</button>
Grogu
  • 2,097
  • 15
  • 36