Want to create multiple dropzones using dropzone.js

I am making a comparison app that has two different drag areas. each of them must act as one drop zone (to replace or delete each image).


var previewaDropzone = new Dropzone("div#previewa",{url:'/url1.json'});
var previewbDropzone = new Dropzone("div#previewb",{url:'/url2.json'});


but the Dropzone throw exception

The dropzone is already attached.

Note: I cannot use the dropzone.js templates because both scopes are in different places.

Is there any way to achieve the above functionality with Dropzone?


source to share

2 answers

From the Dropzone FAQ

I get the error "Dropzone is already attached". when creating a Dropzone.

This is most likely due to the Dropzone auto-detection feature.

When Dropzone starts, it scans the entire document and looks for elements with the dropzone class. It then creates a Dropzone instance for each item it finds. If you later instantiate the Dropzone yourself, you will create a second Dropzone which causes this error.

So you can:

Turn off autoDiscover globally like this: Dropzone.autoDiscover = false;, or
Turn off autoDiscover of specific elements like this: Dropzone.options.myAwesomeDropzone = false;

You don't have to create an instance of Dropzone programmatically in most situations! It recommended to leave autoDiscover enabled,


and configure Dropzone in the init option of your config.

Further down in the FAQ section, you can see an example of a function init()

that you can use like this:

  // previewa is the configuration for the element that has an id attribute
  // with the value previewa
  Dropzone.options.previewa = {
    init: function() {
      Dropzone.options.previewaDropzone = false;




Oof did it! I'll leave it here in case anyone needs it.

Let's say you have your dropzones like these:

<div class="dropzone js-dropzone-upload "></div>
<div class="dropzone js-dropzone-upload "></div>


Define a class for each dropzone, call them whatever you want. In this case, they are named js-dropzone-upload.

Iterate over them through forEach and then pass the "element" parameter to the Dropzone constructor:

// This prevents Dropzone to autodiscover the elements, 
// allowing you to better control it.
Dropzone.autoDiscover = false;

                            .forEach(element => {
                                var myDropzone = new Dropzone(element, {
                                    url: "/Media/AjaxUpload", maxFilesize: 10, addRemoveLinks: true, maxFiles: 1,
//Omit the "headers" in case you don't need it.
                                    headers: { "__RequestVerificationToken": document.getElementsByName("__RequestVerificationToken")[1]).value }
                                myDropzone.on("success", function (response) {
                                    document.getElementById('eMediaID').value = response.xhr.response.replace(/\"/g, "");



Bonus: I did it with Webpack and TypeScript:

 if (document.querySelector('.js-ballot-upload') !== null) {
            (Dropzone) => {

                Dropzone.autoDiscover = false;

                    .forEach(element => {
                        var myDropzone = new Dropzone(element,
                            url: "/Media/AjaxUpload",
                            maxFilesize: 10,
                            addRemoveLinks: true,
                            maxFiles: 1,
                            headers: {
                                "__RequestVerificationToken": (<HTMLInputElement>document
                            function(response) {
                                (<HTMLInputElement>document.getElementById('eMediaID')).value = response.xhr.response
                                    .replace(/\"/g, "");




All Articles