26

I'm trying to add an existing image to my dropzone programmatically, using the dropzone.js FAQ as a guide:

// Add the existing image if it's there.
// headerDropzone is my dropzone (debug shows it as existing and initialized at this point.
var on_load_header = $( '[name="on_load_header_image"]' ).val();
var on_load_header_path = $( '[name="on_load_header_image_path"]' ).val();

if ( on_load_header ) {

    // Hardcoded size value is just for testing, see my second question below.
    var on_load_header_data = { name: on_load_header, size: 12345 };

    // Call the default addedfile event handler
    headerDropzone.options.addedfile.call( headerDropzone, on_load_header_data );

    // And optionally show the thumbnail of the file:
    headerDropzone.options. thumbnail.call( headerDropzone, on_load_header_data, on_load_header_path);

}

My first problem is that this is just not working. The addedfile event doesn't fire (or at least the addedfile handler in headerDropzone never fires), same goes for thumbnail.

My second problem/question is: do I have to provide the file size? I could get it server side, but I'd rather not do it if I don't actually need to.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Jesse Rosato
  • 288
  • 1
  • 3
  • 7

11 Answers11

28

If you need to add multiple existing files into Dropzone, declare your existing files as array and then add it into Dropzone programmatically inside a loop like so...

        Dropzone.autoDiscover = false;
        var myDropzone = new Dropzone("#myDropzone", {
            url: "/file/post",
            maxFileSize: 50,
            acceptedFiles: ".pdf",
            addRemoveLinks: true,
            //more dropzone options here
        });

        //Add existing files into dropzone
        var existingFiles = [
            { name: "Filename 1.pdf", size: 12345678 },
            { name: "Filename 2.pdf", size: 12345678 },
            { name: "Filename 3.pdf", size: 12345678 },
            { name: "Filename 4.pdf", size: 12345678 },
            { name: "Filename 5.pdf", size: 12345678 }
        ];

        for (i = 0; i < existingFiles.length; i++) {
            myDropzone.emit("addedfile", existingFiles[i]);
            //myDropzone.emit("thumbnail", existingFiles[i], "/image/url");
            myDropzone.emit("complete", existingFiles[i]);                
        }
Rosdi Kasim
  • 24,267
  • 23
  • 130
  • 154
25

The Dropzone FAQ leaves out important settings required to properly preload a dropzone with (an) existing file(s).

My init method for my dropzone:

Dropzone.options.MyDropZoneID = {
    ...
    init: function () {
        var mockFile = { name: fileName, size: fileSize, type: fileMimeType, serverID: 0, accepted: true }; // use actual id server uses to identify the file (e.g. DB unique identifier)
        this.emit("addedfile", mockFile);
        this.createThumbnailFromUrl(mockFile, fileUrl);
        this.emit("success", mockFile);
        this.emit("complete", mockFile);
        this.files.push(mockFile);
        ...

I don't know if the above is a perfect implementation, but it is working correctly with the maxFiles setting. Which is very important if you don't want buggy behavior (like the default message displaying when it shouldn't or extra files getting uploaded). You definitely need to set the accepted property to true and add the file to the files property. The only thing that I think is not required is emitting the success. I haven't played around with that enough though to know for sure.

Note: I used the following NuGet package:

  • Created by: Matias Meno
  • Id: dropzone
  • Version: 4.2.0
Jeremy Ray Brown
  • 1,499
  • 19
  • 23
  • 1
    This work perfectly for me in version 5.9. To set "accepted" to "true" was very important in my case, because only than the maxfilesexceeded actually triggers. Tanks! – diealtebremse Sep 07 '21 at 15:59
11

See if the functions headerDropzone.options.addedfile and headerDropzone.options.thumbnail are actually defined. It should work the way you did it, but without further info it's difficult to tell what's wrong.

About the filesize: No, it's not necessary to actually provide the accurate filesize. It's just that Dropzone automatically displays the filesize. If you don't care if some false filesize is displayed then you can just provide some random number or 0. Otherwise you might want to hide the filesize with CSS, or with JS after you add it. (The element in question has the class dz-size.

The JavaScript version of it would look something like this:

var fileSizeElement = on_load_header_data.previewElement.querySelector(".dz-size");
fileSizeElement.parentNode.removeChild(fileSizeElement);
enyo
  • 16,269
  • 9
  • 56
  • 73
  • 2
    Thanks so much for your answer. I went with a different approach that was a better fit for my particular application. Thanks for dropzone, btw, it's a pleasure to work with. – Jesse Rosato Jul 11 '13 at 23:17
  • 4
    Note, code as changed in dropzone and we need to replace `myDropzone.options.addedFile.call(myDropzone, mockFile)` for `myDropzone.emit("addedfile", mockFile)`. See example in the [updated faq](https://github.com/enyo/dropzone/wiki/FAQ#how-to-show-files-already-stored-on-server) – GabLeRoux Oct 16 '14 at 15:51
9

This is now answered in official FAQ

Dropzone.options.myDropzone = {
  init: function() {
    let myDropzone = this;

    // If you only have access to the original image sizes on your server,
    // and want to resize them in the browser:
    let mockFile = { name: "Filename 2", size: 12345 };
    myDropzone.displayExistingFile(mockFile, "https://i.picsum.photos/id/959/600/600.jpg");

    // If the thumbnail is already in the right size on your server:
    let mockFile = { name: "Filename", size: 12345 };
    let callback = null; // Optional callback when it's done
    let crossOrigin = null; // Added to the `img` tag for crossOrigin handling
    let resizeThumbnail = false; // Tells Dropzone whether it should resize the image first
    myDropzone.displayExistingFile(mockFile, "https://i.picsum.photos        /id/959/120/120.jpg", callback, crossOrigin, resizeThumbnail);
    myDropzone.files.push(mockFile); // line missing in official docs

    // If you use the maxFiles option, make sure you adjust it to the
    // correct amount:
    let fileCountOnServer = 2; // The number of files already uploaded
    myDropzone.options.maxFiles = myDropzone.options.maxFiles - fileCountOnServer;
  }
};
Jasom Dotnet
  • 1,225
  • 12
  • 17
Matej Vrzala M4
  • 1,364
  • 2
  • 13
  • 20
7

Originally I was doing something along these lines to programmatically upload a pre-existing file to Dropzone:

headerDropzone.emit("addedfile", imageFile);                                
headerDropzone.emit("thumbnail", imageFile, imageUrl);
headerDropzone.files.push(file);

However, referencing this Dropzone Github Issue I found an easier way to directly upload:

headerDropzone.uploadFiles([imageFile])

Unfortunately there are no references to this uploadFiles method in the Dropzone Documentation, so I figured I'd share some knowledge with all you Dropzone users.

Hope this helps someone

Cumulo Nimbus
  • 8,785
  • 9
  • 47
  • 68
4

I had the same problem and found Dropzone's handleFiles(files) method.

So if you have inputTypeFileRef, you can

// inputTypeFiles.files is an object of type FileList
var fileArray = Object.values(inputTypeFiles.files || {});
myDropZone.handleFiles(fileArray);

That will also trigger all the Dropzone's events and pass file(s) data that it normally would by dragging a file on it - progress, file size, etc.

Hope it helped.

Michael Vashchinsky
  • 2,137
  • 1
  • 17
  • 15
  • This one works with the new chunked upload feature. Although you can just use myDropZone.handleFiles([file]); – Lokiare May 22 '18 at 17:44
2

The latest Dropzone is lack of examples and the documentation is not clear or incomplete. You can use the following to add existing images to Dropzone.

for (var i = 0; i < imagesList.length; i++) {
  let name = imagesList[i];
  name = name.substring(name.lastIndexOf('/') + 1);

  fetch(imagesList[i])
    .then(res => res.blob())
    .then(blob => {
      let file = new File([blob], name, blob);
      myDropzone1.addFile(file);
    });
}

imagesList is a list of images which you want to add to Dropzone.

However, I am still facing a problem: Images are not being added or shown in the order/sequence as in imagesList. They appear rather random. Is there a way to make the images shown in the order/sequence as in imagesList?

J K
  • 519
  • 5
  • 9
  • 28
  • This answer makes a lot of sense. Note that Dropzone accepts loading `blob` directly without creating a file object: `blob.name = name; myDropzone1.addFile(blob);`. Not sure regarding the order of list. – Jacques Gaudin Dec 30 '20 at 22:51
  • `.addFile()` still appears to work as of this comment. By far the easiest way, compared to all the other answers here. – Kurt Jul 21 '21 at 18:30
1

Many of these answers are pretty dated, this is working for me in the latest Dropzone JS at the time of writing (take note of the included comments):

init: function() {
    var dzObj = this;

    // In my template I looped through existing files from the database and created:
    // <div class="existing-image" data-url="/path/to/file.jpg"></div>
    $('.existing-image').each(function() {
        // I didn't have this data - works fine without
        var mockFile = { name: '', size: '', dataURL: $(this).data('url') };

        // Call the default addedfile event handler
        dzObj.emit("addedfile", mockFile);

        // The Dropzone JS FAQ incorrectly references "file" here instead of  mockFile".
        // The other parameters are outdated, dataURL goes in the object above,
        // and you need to pass through other parameters.
        // It DOES NOT WORK without the thumbnail event being triggered.
        dzObj.createThumbnailFromUrl(mockFile, dzObj.options.thumbnailWidth, dzObj.options.thumbnailHeight, dzObj.options.thumbnailMethod, true, function (dataUrl) {
            dzObj.emit("thumbnail", mockFile, dataUrl);
        });

        // Make sure that there is no progress bar, etc...
        dzObj.emit("complete", mockFile);

        dzObj.options.maxFiles = dzObj.options.maxFiles - 1;
    });
}
tjbp
  • 3,427
  • 3
  • 24
  • 35
  • Using this code, I have managed to add existing images to dropzone. But, when I want to resubmit the form (with the dropzone images), the images are not recognized (dzObj.getUploadingFiles().length === 0 && dzObj.getQueuedFiles().length === 0) and so it didn't work. Any solution to this problem? Thanks. – J K Mar 04 '19 at 06:44
  • This is the only example that works with latest version. Internet is full of incorrect answers.. Accepted answer should be updated to this. Also dropzone.js what is this nightmare of adding an image? Expecting addImage() function... – alex toader Oct 09 '19 at 16:00
0

@tjbp's response worked well for me, with the following changes:

  1. I could not delete the programatically added file and then add another. I fixed this by removing this line, which was setting "maxFiles" to 0.

    // If you use the maxFiles option, make sure you adjust it to the
    // correct amount:
    var existingFileCount = 1; // The number of files already uploaded
    myDropzone.options.maxFiles = myDropzone.options.maxFiles - existingFileCount;
    
  2. To make sure the "Delete" button was visible, I had to add the following line:

    if (mockFile.previewElement) {
        mockFile.previewElement.classList.add("dz-success");
    }
    
Stephan
  • 41,764
  • 65
  • 238
  • 329
Michael Wilson
  • 800
  • 8
  • 15
0

Nothing here worked for me with version 5.7.0 but this did:

var myDropzone = new Dropzone(document.body, {
    url: "<?= site_url('site/upload') ?>",
    acceptedFiles: "<?= $uploadFieldAcceptValue ?>",
    maxFilesize: 15,
    maxFiles: 5,
    autoQueue: false,
    thumbnailWidth: 80,
    thumbnailHeight: 80,
    init: function(){
        var that = this;

        that.on("addedfile", function(file) {
            // remove the start button
            var startButton = file.previewElement.querySelector(".start");
            if(startButton){
                startButton.parentNode.removeChild(startButton);
            }
        });

        <?php if(is_array($userUploads) && count($userUploads) > 0) { ?>
            <?php foreach($userUploads as $userUpload) { ?>
                <?php $file = $userUpload['file']; ?>

                var mockFile = {
                    name: '<?= basename($file) ?>', 
                    size: <?= filesize($file) ?>
                };

                var fileUrl = '<?= base_url() . str_replace('\\', '/', preg_replace('~^'. preg_quote(FCPATH) .'~', '', $file)) ?>';
                var callback = null;
                var crossOrigin = null;
                var resizeThumbnail = true;
                that.displayExistingFile(mockFile, fileUrl, callback, crossOrigin, resizeThumbnail);

                that.emit("success", mockFile);
                that.emit('complete', mockFile);

            <?php } ?>

            that.options.maxFiles = that.options.maxFiles - <?= count($userUploads) ?>;

        <?php } ?>
    }
});
aLx13
  • 701
  • 5
  • 16
  • https://gitlab.com/meno/dropzone/-/wikis/FAQ#how-to-show-files-already-stored-on-server – aLx13 Mar 17 '20 at 21:11
0

On Dropzone 5.7.0 there is a "displayExistingFile" function. I called it on init section, works fine.

     /**
     * Called when dropzone initialized
     * You can add event listeners here
     */
    init: function init() {
      var mockFile = { name: "Filename 1.pdf", size: 12345678 }; 
      this.displayExistingFile(mockFile,  "../../assets/site/wp-content/uploads/cropped-ic_credifisco-1-192x192.png");     
    },
Foad
  • 390
  • 3
  • 6