27

I am using Dropzonejs to add image upload functionality in a Form, as I have various other fields in form so I have set autoProcessQueue to false and Processing it on click on Submit button of Form as shown below.

Dropzone.options.portfolioForm = { 

    url: "/user/portfolio/save",
    previewsContainer: ".dropzone-previews",
    uploadMultiple: true,
    parallelUploads: 8,
    autoProcessQueue: false,
    autoDiscover: false,
    addRemoveLinks: true,
    maxFiles: 8,

    init: function() {

         var myDropzone = this;
         this.element.querySelector("button[type=submit]").addEventListener("click", function(e) {

             e.preventDefault();
             e.stopPropagation();
             myDropzone.processQueue();
         });
     }
 }

This works fine and allows me to process all images sent when form is submitted. However, I also want to be able to see images already uploaded by user when he edits the form again. So I went through following post from Dropzone Wiki. https://github.com/enyo/dropzone/wiki/FAQ#how-to-show-files-already-stored-on-server

Which populates dropzone-preview area with existing images but it does not send existing images with form submit this time. I guess this is because theses images are not added in queue but If it's so then how can update on server side, In case an existing image is removed by user?

Also, what would be the better approach, add already added images in queue again or just send information of removed file?

murilolobato
  • 349
  • 4
  • 14
lalit
  • 3,283
  • 2
  • 19
  • 26

8 Answers8

32

I spent a bit of time trying to add images again, but after battling with it for a while I ended up just sending information about the deleted images back to the server.

When populating dropzone with existing images I attach the image's url to the mockFile object. In the removedfile event I add a hidden input to the form if the file that is being removed is a prepopulated image (determined by testing whether the file that is passed into the event has a url property). I have included the relevant code below:

Dropzone.options.imageDropzone = {
    paramName: 'NewImages',
    autoProcessQueue: false,
    uploadMultiple: true,
    parallelUploads: 100,
    maxFiles: 100,
    init: function () {
        var myDropzone = this;

        //Populate any existing thumbnails
        if (thumbnailUrls) {
            for (var i = 0; i < thumbnailUrls.length; i++) {
                var mockFile = { 
                    name: "myimage.jpg", 
                    size: 12345, 
                    type: 'image/jpeg', 
                    status: Dropzone.ADDED, 
                    url: thumbnailUrls[i] 
                };

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

                // And optionally show the thumbnail of the file:
                myDropzone.emit("thumbnail", mockFile, thumbnailUrls[i]);

                myDropzone.files.push(mockFile);
            }
        }

        this.on("removedfile", function (file) {
            // Only files that have been programmatically added should
            // have a url property.
            if (file.url && file.url.trim().length > 0) {
                $("<input type='hidden'>").attr({
                    id: 'DeletedImageUrls',
                    name: 'DeletedImageUrls'
                }).val(file.url).appendTo('#image-form');
            }
        });
    }
});

Server code (asp mvc controller):

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(ViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        foreach (var url in viewModel.DeletedImageUrls)
        {
            // Code to remove the image
        }

        foreach (var image in viewModel.NewImages)
        {
            // Code to add the image
        }
    }
}

I hope that helps.

Teppic
  • 2,506
  • 20
  • 26
  • Thanks Teppic, Yes I had to do the same. :) – lalit Aug 08 '14 at 08:38
  • 2
    A litte improvement: Add "accepted: true" to mockFile, so Dropzone recognizes the file as correctly uploaded. This enables for example the limit of uploadable files ('maxFiles') – user1825294 Sep 09 '14 at 12:55
  • Thanks :) Worked like a charm – mdev Oct 19 '14 at 12:53
  • Perfect! Thanks for this – John Dorian Jun 25 '15 at 19:54
  • If i add one file and click submit button, dropzone only fetch newly added image and the existing images will be lost, right ? What can i do in this case ? How can i add existing images in queue for using processQueue() method next ? Thanks – Bidzina Aivazashvili Jun 21 '17 at 14:00
  • What if you remove multiple files? This solution will send only one url – Manos Oct 16 '17 at 08:15
  • with `accepted: true` you also have to do `myDropzone.emit("complete", mockFile);` to make it actually set as uploaded, otherwise it will show the upload progress bar which may confuse some! – Anupam Feb 03 '21 at 09:44
17

To extend on Teppic's answer, I found you needed to emit the complete event to remove the progress bar on the preview.

var file = {
    name: value.name,
    size: value.size,
    status: Dropzone.ADDED,
    accepted: true
};
myDropzone.emit("addedfile", file);                                
myDropzone.emit("thumbnail", file, value.path);
myDropzone.emit("complete", file);
myDropzone.files.push(file);
Cloud_Ratha
  • 588
  • 1
  • 6
  • 14
3

just use myDropzone.addFile(file)

from dropzone source code https://github.com/enyo/dropzone/blob/4e20bd4c508179997b4b172eb66e927f9c0c8564/dist/dropzone.js#L978

Fareed Alnamrouti
  • 30,771
  • 4
  • 85
  • 76
  • What exactly data should be passed to this function? – Oleg Shakhov Dec 28 '19 at 15:04
  • I am getting error "Cannot read property 'replace' of undefined" when I try to use addFile(). Is there a special way I need to compose the file object? I'm on Dropzone ver 5.5. – Der Wolf May 18 '20 at 22:20
  • you can pass a javascript File or DropzoneFile, See: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/dropzone/index.d.ts#L182 and https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/dropzone/index.d.ts#L29 Also, see: https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications – Fareed Alnamrouti May 19 '20 at 07:25
3

There's an official FAQ for that here

Benedikt S. Vogler
  • 554
  • 1
  • 5
  • 19
Stefan Gabos
  • 1,345
  • 13
  • 15
2

I solved this using the dropzone's built in "displayExistingFile" method.

in your init: function.

  1. Create the mockfile

    let mockFile = { name: file.title, size: file.size, dataURL:};

  2. Call the displayExistingFile function

    this.displayExistingFile(mockFile, , null, 'anonymous')

Instead of 'null' you can place a callback to respond to the thumbnail load event.

The 'anonymous' is for the cross origin property.

JHRS
  • 367
  • 4
  • 11
1

Originally I was doing this to programmatically upload a pre-existing file:

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

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

myDropzone.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
  • 1
    The first portion of your code is mocking the upload process, not really posting anything to the server. and `myDropzone.uploadFiles([imageFile])` is posting to server, so they are different – Mohamed Mo Kawsara Oct 22 '17 at 00:34
1

If you have the URL of the file, you can add the file with addFile.

fetch("url")
    .then(res => res.blob())
    .then((currentBlob) => {
        const generateFile = new File([currentBlob], "filename.jpg", {
            type: currentBlob.type,
        });
        myDropzone.addFile(generateFile);
    });
0

On click of upload files just clear the files from dropzone. All Files can be cleared using removeAllFiles() or specific file also you can delete by using removeFile(fileName).