DropZonejs: Submit form without files
Asked Answered
I

8

28

I've successfully integrated dropzone.js inside an existing form. This form posts the attachments and other inputs like checkboxes, etc.

When I submit the form with attachments, all the inputs post properly. However, I want to make it possible for the user to submit the form without any attachments. Dropzone doesn't allow the form submission unless there is an attachment.

Does anybody know how I can override this default behavior and submit the dropzone.js form without any attachments? Thank you!

   $( document ).ready(function () {
    Dropzone.options.fileUpload = { // The camelized version of the ID of the form element

      // The configuration we've talked about above
      autoProcessQueue: false,
      uploadMultiple: true,
      parallelUploads: 50,
      maxFiles: 50,
      addRemoveLinks: true,
      clickable: "#clickable",
      previewsContainer: ".dropzone-previews",
      acceptedFiles: "image/*,application/pdf, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.openxmlformats-officedocument.spreadsheetml.template, application/vnd.openxmlformats-officedocument.presentationml.template, application/vnd.openxmlformats-officedocument.presentationml.slideshow, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.openxmlformats-officedocument.presentationml.slide, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.openxmlformats-officedocument.wordprocessingml.template, application/vnd.ms-excel.addin.macroEnabled.12, application/vnd.ms-excel.sheet.binary.macroEnabled.12,text/rtf,text/plain,audio/*,video/*,.csv,.doc,.xls,.ppt,application/vnd.ms-powerpoint,.pptx",



        // The setting up of the dropzone
      init: function() {
        var myDropzone = this;

        // First change the button to actually tell Dropzone to process the queue.
        this.element.querySelector("button[type=submit]").addEventListener("click", function(e) {
          // Make sure that the form isn't actually being sent.
          e.preventDefault();
          e.stopPropagation();
          myDropzone.processQueue();
        });

        // Listen to the sendingmultiple event. In this case, it's the sendingmultiple event instead
        // of the sending event because uploadMultiple is set to true.
        this.on("sendingmultiple", function() {
          // Gets triggered when the form is actually being sent.
          // Hide the success button or the complete form.
        });
        this.on("successmultiple", function(files, response) {
            window.location.replace(response.redirect);
            exit();
        });
        this.on("errormultiple", function(files, response) {
          $("#notifications").before('<div class="alert alert-error" id="alert-error"><button type="button" class="close" data-dismiss="alert">×</button><i class="icon-exclamation-sign"></i> There is a problem with the files being uploaded. Please check the form below.</div>');
          exit();
        });

      }

    }
  });
Insignia answered 3/1, 2014 at 18:42 Comment(0)
R
24

Use the following:

$('input[type="submit"]').on("click", function (e) {

                    e.preventDefault();
                    e.stopPropagation();

                    var form = $(this).closest('#dropzone-form');
                    if (form.valid() == true) { 
                        if (myDropzone.getQueuedFiles().length > 0) {                        
                            myDropzone.processQueue();  
                        } else {                       
                            myDropzone.uploadFiles([]); //send empty 
                        }                                    
                    }               
                });

Reference: https://github.com/enyo/dropzone/issues/418

Rojo answered 19/1, 2014 at 19:13 Comment(5)
I get the error Uncaught TypeError: Cannot read property 'status' of undefined dropzone.js?body=1:1447 when submitting without files. have you tested this?Sanhedrin
apparently this requires a source code modification(see reference) to avoid the error I was getting.Sanhedrin
@Sanhedrin Glad you figured it out. That's what the reference is for, so you can get the whole context of the solution.Rojo
There is an open issue. Please upvote so this gets fixed. github.com/enyo/dropzone/issues/687Trudi
myDropzone.uploadFile([]) does not send request.Kibe
D
17

You should check if there are files in the queue. If the queue is empty call directly dropzone.uploadFile(). This method requires you to pass in a file. As stated on [caniuse][1], the File constructor isn't supported on IE/Edge, so just use Blob API, as File API is based on that.

The formData.append() method used in dropzone.uploadFile() requires you to pass an object which implements the Blob interface. That's the reason why you cannot pass in a normal object.

dropzone version 5.2.0 requires the upload.chunked option

if (this.dropzone.getQueuedFiles().length === 0) {
    var blob = new Blob();
    blob.upload = { 'chunked': this.dropzone.defaultOptions.chunking };
    this.dropzone.uploadFile(blob);
} else {
    this.dropzone.processQueue();
}
Diaphane answered 15/1, 2018 at 13:31 Comment(5)
This answer should be on top ! ThanksAllegedly
Yes, this is only what worked for me. Here is the reference: github.com/enyo/dropzone/issues/687Kalman
Only solution that worked for me with version 5.7.0. All other answers are valid for version 4.x.Outclass
Thank you for your solution! In case of undefined defaultOptions, you can also use this.dropzone.options.chunking.Triazine
I tried this way, but server side request not being sent with this.dropzone.uploadFile(blob)Kibe
S
16

Depending on your situation you could simply submit the form:

if (myDropzone.getQueuedFiles().length > 0) {                        
   myDropzone.processQueue();  
} else {                       
   $("#my_form").submit();
}
Shelton answered 30/12, 2014 at 23:24 Comment(4)
@Limon check that your form is tagged with enctype="multipart/form-data"Shelton
You are right but I'd like to point out that you completely separate event handlers if you don't want a page reload but handle the server response in JavaScript. Dropzone fires several events before/during/after the submission which will not be triggered in your "else" case.Considerable
This assumes that you have a form on the page! Using dzClosure.on('sending', function (data, xhr, formData) can be supplied with Custom form content in which case unfortunately this method won't work.Cushy
Thank you this worked as I was using Dropzone.js combined with an existing form. People who use it without an existing form should find another solution.Maite
R
6

The first approach is kind of too expensive for me, I would not like to dive into the source code and modify it,

If you happen to be like me , use this.

function submitMyFormWithData(url)
    {
        formData = new FormData();
        //formData.append('nameOfInputField', $('input[name="nameOfInputField"]').val() );

        $.ajax({
                url: url,
                data: formData,
                processData: false,
                contentType: false,
                type: 'POST',

                success: function(data){
                alert(data);
                }
        });
    }

And in your dropzone script

$("#submit").on("click", function(e) {
                      // Make sure that the form isn't actually being sent.
                      e.preventDefault();
                      e.stopPropagation();

                        if (myDropzone.getQueuedFiles().length > 0)
                        {                        
                                myDropzone.processQueue();  
                        } else {                 
                                submitMyFormWithData(ajaxURL);
                        }     

                    });
Rhodonite answered 13/9, 2015 at 10:39 Comment(1)
best solution for now since the blob method creates a file that you will need to deal with in server side no to upload itDartmouth
M
4

I tried Matija Grcic's answer and I got the following error:

Uncaught TypeError: Cannot read property 'name' of undefined

And I didn't want to modify the dropzone source code, so I did the following:

        if (myDropzone.getQueuedFiles().length > 0) {                        
            myDropzone.processQueue();  
        } else {                       
            myDropzone.uploadFiles([{name:'nofiles'}]); //send empty 
        }                                    

Note: I'm passing an object inside the array to the uploadFiles function.

Then I check server-side, if name != 'nofiles' do upload stuff.

Myelitis answered 8/12, 2016 at 16:16 Comment(1)
@Agu.nice sollution . myDropzone.uploadFiles([{name:'nofiles'}]); it helped meTouchhole
C
2

Pretty simple, you stop the propagation ONLY if you have files to be submitted via Dropzone:

// First change the button to actually tell Dropzone to process the queue.
this.element.querySelector("button[type=submit]").addEventListener("click", function(e) {
  // Stop the propagation ONLY if you have files to be submitted via Dropzone
  if (myDropzone.getQueuedFiles().length > 0) {
        e.preventDefault();
        e.stopPropagation();
        myDropzone.processQueue();
  }
});
Carrell answered 12/8, 2020 at 1:34 Comment(0)
R
0

I have successfully used :

submitButton.addEventListener("click", function () {  
  if(wrapperThis.files.length){
        error = `Please select a file`; 
    } else {
        wrapperThis.processQueue(); 
    }
}); 
Rainwater answered 31/5, 2017 at 9:25 Comment(0)
C
0

My answer is based on the fact that the other answers don't allow for an Ajax based solution where an actual HTML form isn't actually being used. Additionally you may want the full form contents submitted when sending the Files for upload as well.

As you'll see, my form occurs in a modal outside of any form tag. On completion, the modal is triggered to close.

(FYI getForm returns the form as an object and not directly related to the answer. Also assumes use of jQuery)

init: function() {
    var dzClosure = this;

    // When saving what are we doing?
    $('.saveBtn').off('click').on('click',function(e){
        e.preventDefault();
        e.stopPropagation();

        if (dzClosure.getQueuedFiles().length > 0) {
            dzClosure.processQueue();

            dzClosure.on('queuecomplete',function(){
                $('.modal:visible').modal('hide');
            })
        } else {
            var params = getForm();

            $.post(dzClosure.options.url,params,function(){
                $('.modal:visible').modal('hide');
            })
        }
    });

    dzClosure.on('sending', function (data, xhr, formData) {
        var extra = getForm();

        for (key in extra){
            formData.append(key,extra[key]);
        }
    });
Cushy answered 21/7, 2022 at 10:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.