Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

post normal form with dropzone

I followed this tutorial in order to include DropZone with traditional form elements :

HTML

<form id="my-awesome-dropzone" class="dropzone">
  <div class="dropzone-previews"></div> <!-- this is were the previews should be shown. -->

  <!-- Now setup your input fields -->
  <input type="email" name="username" />
  <input type="password" name="password" />

  <button type="submit">Submit data and files!</button>
</form>

And JS here

Dropzone.options.myAwesomeDropzone = { // The camelized version of the ID of the form element

  // The configuration we've talked about above
  autoProcessQueue: false,
  uploadMultiple: true,
  parallelUploads: 100,
  maxFiles: 100,

  // 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) {
      // Gets triggered when the files have successfully been sent.
      // Redirect user or notify of success.
    });
    this.on("errormultiple", function(files, response) {
      // Gets triggered when there was an error sending the files.
      // Maybe show form again, and notify user of error
    });
  }

}

It works nice, except when user didn't submit files. In accordance to this post, I have to make some edits:

Replace the simple

myDropzone.processQueue();

by

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

Now, as it's written in the stackoverflow post "DropZonejs: Submit form without files" comment, I get the

Uncaught TypeError: Cannot read property 'status' of undefined

So I checked the dropzone issue 687 that fix this by replacing some content of dropzone.js. This line

ata.append(this._getParamName(i), files[i], files[i].name);

to those lines

if ( typeof files[i] != "undefined" ) {
  formData.append(this._getParamName(i), files[i], files[i].name);
} else {
  formData.append(this._getParamName(i), "");
} 

Now it's working (Controller is called with right data in model) BUT the call that is made is an AJAX Call and I want to make a redirection in the controller of my app so it didn't work. I could make a Json with one URL as return but I have to keep the redirection in back end.

Example of controller:

[HttpPost]
        public ActionResult Create(CustomViewModel model)
        {
            // Here I get Request.IsAjaxRequest() = true when form is submitted
            if (ModelState.IsValid)
            {
                var container = DoSomething();
                if (container.HasErrors)
                {
                    SetError(container.ErrorMessage);
                    return RedirectToAction("Index");
                }
            }
            else
            {
                SetAlert("ErrorMessage");
            }
            return RedirectToAction("Index");
        }

How Can I fix this issue? Thanks in advance for your help

like image 534
clement Avatar asked Oct 31 '22 16:10

clement


1 Answers

I faced the same issue and didn't have much time to fix it. Just needed to make it works asap...

Here is my 2 cents;

You can return something like this from your controller;

return Json(new { ErrorMessage = "", RedirectURL = Url.Action("Get", null, new { id = result.Value.id }, Request.Url.Scheme ) });

and fill this method from JS that you have posted:

this.on("successmultiple", function (files, response) {
                // Gets triggered when the files have successfully been sent.
                // Redirect the user or notify of success.
                var errorMessage = response.ErrorMessage;
                if (errorMessage.length > 0) {
                    alert(errorMessage);
                }
                else {
                    window.location.replace(response.RedirectURL);
                }
};
like image 126
Andrew Avatar answered Nov 12 '22 17:11

Andrew