0
votes

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).

1

1 Answers

1
votes

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.