Jabberwocky

snicker-snack!

Uploading Files With jQuery and Rails

| Comments

Update: there are better solutions, it is actually possible to upload a filewithout refreshing the page.

Sometimes you want to upload a file, for instance a picture. At present, it’s not possible to do this with an XMLHttpRequest (aka Ajax).

If you’re not fussed about Ajax, you can just submit your form normally (obviously). Nobody has ever died from a page refresh.

If you really don’t want to leave your current page, but would like to reproduce the modal window effect, you can use (gasp) pop-ups. Pop-ups have gotten a bad reputation, because some uncouth websites swamp your desktop with ugly pop-up ads.

Nifty jQuery plugins to the rescue (again): PopupWindow. It basically opens a window with target to _blank and the style (in the “rel” attribute) set to given parameters, when you click the selected element.

An example: say you want to open a pop-up window on a link with class “picture”:

1
2
3
4
5
6
7
8
9
10
11
12
var profiles =
{
  pictureWindow:
  {
    height:400,
    width:400,
    center:1,
    createnew:0
  }    
}

$(".picture").popupwindow(profiles);

The link destination is used for the pop-up window – this should GET a file upload form.

Once a file upload form is opened, the question is how to get back to the original page after file upload, and apply the necessary changes as well ? This is actually quite easy. Submit the form normally to upload the file, but as a return, use an empty template that just executes some javascript on load. This javascript should apply some changes to the original (opener) window, and then close the pop-up window. For instance: in the head section (in this case an html.erb template):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script type="text/javascript">
  $(function() {
  <% if flash[:error] % >
    window.opener.$("#header").before('
    <div class="flash" id="flash_error">
      <%= escape_javascript(flash.delete(:error)) %>
    </div>
    ');
  <% else %>
    window.opener.$("#image").html( '
      <%= escape_javascript(image_tag @picture.rel_filename, :title => @picture.title) %>
    ');
  <% end %>
  window.close();
});
</script>

What this does: if there’s an error, it displays it before the “header” section (replace by appropriate position). Else it loads the image into the div with id “image” in the original page (window.opener) and then closes the actual pop-up window.

Comments