Asad Ali Bhatti
Asad Ali Bhatti

Reputation: 67

want to create multiple dropzones using dropzone.js

i am making a comparison app which have two different drag & drop areas. each one should act like a single drop zone (to replace or remove each image).

issue:

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

but dropzone throw exception

Dropzone already attached.

Note: i cant use templates of dropzone.js because both areas are on different places

any way to achieve given above functionality using Dropzone?

Upvotes: 4

Views: 12844

Answers (2)

Jose A
Jose A

Reputation: 11077

Oof made it! I'll leave this here in case someone needs it.

Let's say that 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 called js-dropzone-upload.

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

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

        Array.prototype.slice.call(document.querySelectorAll('.js-dropzone-upload'))
                            .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, "");
                                });
                            });

    </script>

Bonus: I made this with Webpack and TypeScript:

 if (document.querySelector('.js-ballot-upload') !== null) {
            require(['../dropzone/dropzone-amd-module.min.js'],
            (Dropzone) => {

                Dropzone.autoDiscover = false;

                Array.prototype.slice.call(document.querySelectorAll('.js-ballot-upload'))
                    .forEach(element => {
                        console.log(element);
                        var myDropzone = new Dropzone(element,
                        {
                            url: "/Media/AjaxUpload",
                            maxFilesize: 10,
                            addRemoveLinks: true,
                            maxFiles: 1,
                            headers: {
                                "__RequestVerificationToken": (<HTMLInputElement>document
                                    .getElementsByName("__RequestVerificationToken")[1]).value
                            }
                        });
                        myDropzone.on("success",
                            function(response) {
                                (<HTMLInputElement>document.getElementById('eMediaID')).value = response.xhr.response
                                    .replace(/\"/g, "");
                            });
                    });
            });

Upvotes: 6

Jason Sperske
Jason Sperske

Reputation: 30416

From the Dropzone FAQ

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

This is most likely due to the autoDiscover feature of Dropzone.

When Dropzone starts, it scans the whole document, and looks for elements with the dropzone class. It then creates an instance of Dropzone for every element found. If you, later on, create a Dropzone instance yourself, you'll create a second Dropzone which causes this error.

So you can either:

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's recommended to leave autoDiscover enabled,

and configure your Dropzone in the init option of your configuration.

Further down the FAQ you can see an example of the init() function which you can use like this:

<script>
  // 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;
    }
  };
</script>

Upvotes: 4

Related Questions