Joshua Bakker
Joshua Bakker

Reputation: 2378

Dropzone.js not working properly

I have a dropzone script which uploads file to a certain directory. I did read a lot of the documentation already but still I'm stuck. I have this JS:

$(document).ready(function () {
    Dropzone.autoDiscover = false;
    var selectorElement = '.fileUploader';
    var selector = $(selectorElement);

    selector.addClass('dropzone');
    selector.dropzone({
        dictInvalidFileType: 'Kan bestand niet uploaden: ongeldige extensie.',
        dictFileTooBig: 'Kan bestand niet uploaden: bestand te groot.',
        dictResponseError: 'SERVER ERROR',
        paramName: 'file[]', // The name that will be used to transfer the file
        maxFilesize: 1000, // MB
        url: 'ajax/uploadFile.php',
        addRemoveLinks: true,
        enqueueForUpload: true,
        uploadMultiple: true,
        sending: function (file, xhr, formdata) {
            formdata.append('uploadPath', $(this)[0].element.dataset.uploadpath);
            $(this).css({width: $(this)[0].element.getAttribute('width'), height: $(this)[0].element.getAttribute('height')});
        },
        init: function ()
        {
            var myDropzone = this;

            this.on('maxfilesexceeded', function (file) {
                this.removeFile(file);
            });

            this.on('removedfile', function (file) {
                if (file.previewTemplate.children[6])
                {
                    var filePath = this.element.dataset.uploadpath + file.previewTemplate.children[6].value;
                    $.post('ajax/deleteFile.php', {file: filePath}, function (response) {
                        CMSnotification(response.message, response.type);
                    }, 'JSON');
                }
            });

            this.on('successmultiple', function (files, response) {
                var responseJSON = JSON.parse(response);
                CMSnotification(responseJSON.melding, responseJSON.type);

                if (responseJSON.type === 'foutmelding')
                {
                    for (var i = 0; i < files.length; i++)
                    {
                        var previewTemplate = $(files[i].previewTemplate);
                        previewTemplate.children('.dz-success-mark').css('display', 'none');
                        previewTemplate.children('.dz-error-mark').css('display', 'block');
                        previewTemplate.removeClass('dz-success').addClass('dz-error');
                    }
                }

                for (var i = 0; i < files.length; i++)
                {
                    var previewTemplate = $(files[i].previewTemplate);

                    if (!responseJSON.files[i])
                    {
                        previewTemplate.children('.dz-success-mark').css('display', 'none');
                        previewTemplate.children('.dz-error-mark').css('display', 'block');
                        previewTemplate.removeClass('dz-success').addClass('dz-error');
                    }
                    else
                    {
                        previewTemplate.append('<input type="hidden" name="fileNames[]" value="' + responseJSON.fileNames[i] + '">');
                        previewTemplate.append('<input type="hidden" name="extensions[]" value="' + responseJSON.extensions[i] + '">');
                    }
                }
            });
        },
        accept: function (file, done) {
            var extension = file.name.split('.').pop();
            extension = extension.toLowerCase();
            if ($.inArray(extension, window.allowedFileDropzoneExtensions) > -1) {
                done();
            }
            else {
                done('Bestands extensie niet toegestaan.');
            }
        }
    });
});

The first problem is, I include this file once and still it gives the error dropzone already attached. But the biggest problem is:

The dropzone is pretty inconsistent. For 3 files, it calls 3 request files. For 8 files, it can call 4 request files. But it should just call 1. The problem is, if I allow the user to give a callback as parameter in the function and call it in the success event of the upload, it will call that callback multiple times (but it should just call it once).

Upvotes: 0

Views: 4436

Answers (1)

wallek876
wallek876

Reputation: 3269

The first problem is because you have the statement Dropzone.autoDiscover = false inside the .ready() function, and this causes to trigger it to late. Move this statement outside the .ready() function.

Dropzone.autoDiscover = false;
$(document).ready(function () {
    .........
})

The second is due to the way dropzone works, by default the option autoProcessQueue is set to true, and dropzone uploads the files immediately after they are added. I think there is no guarantee of how many files will upload at once, but I think that by default will never upload more than two.

A solution is to manually trigger the upload of the files, to do this you need to set autoProcessQueue to false, just to mention an example you can use a button that triggers the upload, inside the init option add an event listener for the button that triggers the processQueue() method. Here an example of this solution:

html:

<button type="button" id="submit-all">Submit All</button>

js:

selector.dropzone({
    autoProcessQueue: false,
    uploadMultiple: true,
    init: function () {
        var submitButton = document.querySelector("#submit-all");
        myDropzone = this; 
        submitButton.addEventListener("click", function () {
            myDropzone.processQueue(); 
        });
    }
})

I just included the relevant part for this to work, you can add this to your existing configuration. This will also solve your problem for the successmultiple event.

Upvotes: 1

Related Questions