rails4 + bootstrap で async 画像アップロード

画像のアップロード時にajax:error/ajax:success/ajax:beforeを指定して、progress-barをそれっぽく表示するようにしたのでメモ。

画像アップロードのたびにページ切り替わると煩わしいのでremotipartを使っています。

Rails jQuery file uploads via standard Rails "remote: true" forms.
https://github.com/JangoSteve/remotipart

remotipart内では以下2つのjsファイルが使われます。

https://github.com/JangoSteve/remotipart/blob/master/vendor/assets/javascripts/jquery.iframe-transport.js
https://github.com/JangoSteve/remotipart/blob/master/vendor/assets/javascripts/jquery.remotipart.js

ajax:error/ajax:success/ajax:beforeの指定については以下を参照。
https://github.com/rails/jquery-ujs/wiki/ajax

bootstrapでprogress-barの表示については以下を参照。
http://getbootstrap.com/components/#progress

ここから実際のコードです。

erb部分のコード。初期状態ではhideして表示しません。

```html+erb

    <div class="hide" id="image-new-progress-message">
      画像の登録中です...
      <div class="progress progress-striped active">
        <div class="progress-bar" role="progressbar" style="width: 0%"></div>
      </div>
    </div>
    
    <div class="alert alert-dismissable alert-danger hide" id="image-new-error-message">
      <button type="button" class="close" data-dismiss="alert">×</button>
      画像の登録に失敗しました。
    </div>

    <div class="alert alert-dismissable alert-success hide" id="image-new-success-message">
      <button type="button" class="close" data-dismiss="alert">×</button>
      画像の登録に成功しました。<%= link_to "ページを更新します。" %>
    </div>

    <%= form_for Image.new, :html => {:multipart => true, :id => "image-new-form"}, :remote => true do |f| %>
      <div class="well">
        <%= f.file_field :image %>
        <%= f.text_field :title %>
        <%= f.text_field :running_title %>
        <%= f.text_field :subtitle %>
        <%= f.text_field :headline %>
        <%= f.text_area :description %>
        <%= f.form_group do %>
          <%= f.submit "更新する" %>
        <% end %>
      </div>
   <% end %>
```

javascriptのコード。表示するときにclassのhideを削除してからshow()します。
progressは時間経過で徐々に伸びていきます。

```js
     $("#image-new-form").on("ajax:error", function() {
       $("#image-new-error-message").removeClass('hide').show();
       $("#image-new-success-message").hide();
       $("#image-new-progress-message").hide();
     }).on("ajax:success", function() {
       $("#image-new-error-message").hide();
       $("#image-new-success-message").removeClass('hide').show();
       $("#image-new-progress-message").hide();
     }).on("ajax:before", function() {
       $("#image-new-error-message").hide();
       $("#image-new-success-message").hide();
       $("#image-new-progress-message").removeClass('hide').show();
       setTimeout(function(){
         var currentPercentage = 0;
         var progress = setInterval(function() {
             if (currentPercentage == 100) {
                 clearInterval(progress);
             } else {
                 currentPercentage +=5;
                 $("#image-new-progress-message .progress-bar").css('width', (currentPercentage) + '%');
             }
             $("#image-new-progress-message .progress-bar").text((currentPercentage) + '%');
         }, 500);
      }, 1000);
     });
```

f.form_groupと書いてあるのはrails-bootstrap-formsを使っているためです。
https://github.com/bootstrap-ruby/rails-bootstrap-forms