开发者

jQuery Form Plugin + Ajax File Upload + Rails

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 othe开发者_开发知识库r 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.


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜