jqueryruby-on-railsajaxbackbone.jsremotipart

AJAX image upload with Rails, Backbone, Remotipart


I've been using Remotipart successfully to upload images via AJAX for a while now, but we've recently decided to go the Backbone route, and now since my forms are rendered via JS templates, I'm no longer able to use the :remote => true syntax to generate the Iframe transport code. I don't want to have to figure out how to do this manually. Any thoughts on how I can get Remotipart to work when using JS templates?


Solution

  • Figured out a solution. I was a little confused on how the JS for Remotipart works. After a little research, here's what I found:

    Remotipart works simply by binding to the ajax:aborted:file event, which is triggered when jQuery UJS (which handles traditional AJAX form submits) detects a file within the form. Since that script (along with the dependent iFrame transport plugin) is already included on the page, all you need to do is manually add

    data-remote="true"
    

    to your form. jQuery has an .on() event bound to forms with such attributes, so if you include that, Remotipart will be triggered.

    Another issue, though, is that if this form is submitted, it will still likely fail to upload the file due to the lack of the CSRF token. The solution is to manually add a hidden input tag with the token.

    Here's the final markup that worked for me (I'm using .eco templates with a little jQuery to grab the value of the CSRF meta tags on the page):

    <form accept-charset="UTF-8" id="image-upload-form" action="/projects/<%= @project.get('id') %>" method="post" enctype="multipart/form-data" data-remote="true">
        <input name="project[cover_photo]" type="file" />
        <input type="hidden" name="<%= $('meta[name="csrf-param"]').attr('content') %>" value="<%= $('meta[name="csrf-token"]').attr('content') %>" />
        <input name="_method" type="hidden" value="put" />
        <button id="add-photo">Save</button>
    </form>
    

    Hope this will help spare someone else the same trouble I had!