4
votes

I am using drop zone as part of a form. ie. the form has other elements apart from just the dropzone field. Also, no new view is loaded after form submission, just some js code so remote = true. The form looks like this:

<%= form_tag submit_form_path, method: "POST", "data-abide" => "", 'autocomplete' => 'off', id: "id-of-form", remote: true, multipart: true do %>

<div class="dropzone" id="myDropzone"></div>
<%= text_field_tag "name",     ....
<%= text_field_tag "number", "",  ....
<%= text_field_tag "email", "",   ....
<%= submit_tag "submit", id: "submit-button" ....

<% end %>

JS

Dropzone.options.myDropzone = {
 url: '/submit_form',
 autoProcessQueue: false,
 uploadMultiple: true,
 parallelUploads: 5,
 maxFiles: 5,
 maxFilesize: 1,
 acceptedFiles: 'image/*',
 addRemoveLinks: true,
 init: function() {
    dzClosure = this; 

    // for Dropzone to process the queue (instead of default form behavior):
    document.getElementById("submit-button").addEventListener("click", function(e) {
        // Make sure that the form isn't actually being sent.
        e.preventDefault();
        e.stopPropagation();
        dzClosure.processQueue();
    });

    //send all the form data along with the files:
    this.on("sendingmultiple", function(data, xhr, formData) {
        formData.append("name", jQuery("#name").val());
        *the rest of the form elements*
    });
}

}

On submitting the form I get Can't verify CSRF token authenticity Completed 422 Unprocessable Entity in 2ms ActionController::InvalidAuthenticityToken

UPDATE: Solved invalid authenticity token problem. However, now Im getting an ActionView::MissingTemplate - Missing template error. Before dropzone was added to the form. I was successfully able to submit the form and execute some js code (submit_details.js.erb) without reloading the page.

But now its

Processing by XyzController#submit_details as JSON

and

ActionView::MissingTemplate - Missing template xyz/submit_details, application/submit_enquiry with {:locale=>[:en], :formats=>[:json], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :arb, :jbuilder]}.

Controller :

I commented everything, and the function is just

def submit_enquiry 
   #commented stuff
   puts "checking "
   respond_to do |format|          
    format.html    
    format.js
    format.json { render :json => true } 
   end
end

The logs are :

Started POST "/submit_form" for 127.0.0.1 at 2016-10-05 14:28:00 +0800

14:28:00 web.1 | Processing by XyzController#submit_details as JSON

14:28:00 web.1 | Parameters: {"firstname"=>"something", "lastname"=>"something", "file"=>{"0"=>#, @original_filename="filename.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"file[0]\"; filename=\"filename.png\"\r\nContent-Type: image/png\r\n">}, "language"=>"en"}

14:28:00 web.1 | checking

14:28:00 web.1 | Completed 406 Not Acceptable in 2ms 14:28:00 web.1 | 14:28:00 web.1 | ActionController::UnknownFormat - ActionController::UnknownFormat:

3

3 Answers

9
votes

try adding the header to your Dropzone request

Dropzone.options.myDropzone = {
  url: '/submit_form',
  autoProcessQueue: false,
  ...
  headers: {
    'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
  }
}
3
votes

I wanted all my Dropzones to work with my setup (Rails 5, CSRF token and so on). So I came up with a oneliner to put after $ -> in a coffeescript:

 Dropzone.prototype.defaultOptions['headers'] = 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
0
votes

Got the solution :

In the controller respond only with json.

All the js code you want executed, put it inside Dropzone.options :

this.on("success", function(file, responseText) {
   #js code
});