In-place file upload with Ruby on Rails

Posted by Dmytro Shteflyuk on under Ruby & Rails · Русский (121,963 views)

My friends often asked me how to upload file using AJAX, and usually they got answer “in no way”. Correct answer, but what if I need to upload file without full page reloading? And, of course, I want to use RJS in this case. Here I’ll explain what to do to get effect very similar to AJAX file upload (btw, Gmail uses this technique).

First of all, do you know, that form element has attribute target? If you specify it your form will be submitted into frame with name entered in target attribute. Of course, this frame can be iframe, and it can be hidden! Look at the following chunk of HTML code:

1
2
3
4
5
<form target="upload_frame" action="/test/upload_action" id="upload_form" method="post" enctype="multipart/form-data">
  <input type="file" name="uploaded_file" /><br />
  <input type="submit" />
</form>
<iframe id="upload_frame" name="upload_frame" style="display: none"></iframe>

When you click the “Submit” button, form will be submitted to hidden iframe and controller’s action will be called. But resulting RJS will be returned into the hidden frame! We need to get full respond and execute it in context of whole page (parent window for our frame). There is one interesting technique exists: http://developer.apple.com/internet/webcontent/iframe.html, and it’s implementation as Ruby on Rails plugin here. Example of using:

1
2
3
4
5
6
7
8
9
10
11
class TestController < ActionController::Base
  def upload_action
    # Do stuff with params[:uploaded_file]

    responds_to_parent do
      render :update do |page|
        page.replace_html 'upload_form', :partial => 'upload_form'
      end
    end
  end
end

It’s simple, right?

32 Responses to this entry

Subscribe to comments with RSS

exip
said on November 21, 2008 at 6:31 pm · Permalink

Есть плугин для jQuery, который использует похожую технику.

More comments: 1 2

Comments are closed

Comments for this entry are closed for a while. If you have anything to say – use a contact form. Thank you for your patience.