3

I'm using the jQuery Form Plugin on a big ass form which includes some file fields. The back end is Ruby on Rails.

I'm having trouble getting Rails to recognize the POST request type to be 'text/javascript' even though I believe I am setting it correctly.

The form looks like:

<form id="listing_form" method="POST" enctype="multipart/form-data" action="/listings">
    <input type="text" size="30" name="listing[venue][phone]" id="listing_venue_phone"/>
    <input type="file" size="30" name="listing[venue][image]" id="listing_venue_image"/>
    ...plus tons of other fields

The js looks like:

$("#listing_form").ajaxForm({ dataType: 'script' });

And I also have declared:

jQuery.ajaxSetup({ 
    'beforeSend': function(xhr) {xhr.setRequestHeader('Accept', 'text/javascript')}
});

The request makes it to the controller, but the Rails respond_to block sees it as a normal html request. Also, Firebug shows a parser error and fails to display the request and response headers in the console.

If I remove the file field and POST the text fields only, the respond_to block handles the request as a js request and properly executes the create.js.erb file.

How can I get Rails to properly respond to the request? Thanks.

2
  • The dataType option of the jQuery form plugin is a proxy to the dataType option of jQuery's ajax method. It means that the XHR is expecting a response with a text/javascript content-type. It has nothing to do with what is being sent. Commented Nov 16, 2009 at 8:10
  • Thanks for your response. That part I get, I've edited my post a bit to clarify my question. Commented Nov 16, 2009 at 8:17

2 Answers 2

4

Due to JavaScript security limitations it is impossible to send forms with (non-empty) file fields via XHR. The usual workaround is to "fake" ajax form submission by posting to a hidden iframe. I believe that is also what jQuery Form plugin does.

One way of making Rails treat these "fake" ajax form submissions as actual XHR requests would be adding a special parameter in jQuery Form plugin's beforeSubmit callback:

// ...
beforeSubmit: function(data) {
    data.push({name: 'accept_js', value: '1'});
}
// ...

Then in your controller use a before filter to set format of the request to :js when posted data contains the special parameter:

before_filter :set_ajax_request

# ...

private
  def set_ajax_request
    request.format = :js if params[:accept_js] == '1'
  end

Your respond_to method should now work as expected.

Sign up to request clarification or add additional context in comments.

2 Comments

Hey thanks for your advice. However, the accept_js parameter disappears between adding it in beforeSubmit and hitting the Rails app. It might have to do with the iframe hack. Tracking it down now...
I followed the screencast: blog.edgecase.com/2009/6/15/…, and got it working. Basically, I added a <$= hidden_field_tag :format, 'js' %> to the form, and installed the plugin. Works perfectly. Thanks for your suggestion, it helped me understand what's going on and sent me in the right direction.
2

If you're using Rails 3, try the Remotipart gem. It makes AJAX style file uploads relatively painless.

http://rubygems.org/gems/remotipart

http://github.com/leppert/remotipart

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.