jquery-uiのdrag入替時にRails on ajaxで更新したい


jqueryのマウスでグリグリするやつをRails+Ajaxで更新しるのをやってみたいなぁと思い
ちょっと試してみました。
参考サイトの内容が超絶役に立ちました。ありがとうございます。


こんな感じの。

How to

JQuery / JQuery UIを使えるようにします。

(20120107修正:application.html.erbからapplication.jsで読み込むように修正)

#application.js
//= require jquery
//= require jquery-ui
htmlの構造

こんなviewを作ります。
グリグリの単位は2行目のdiv.dragboxです。

div.column
  div.dragbox id="group_<%= group.id %>
    h2
    dl
      dt
      dd


ポイントはグリグリ対象の要素にidを「_」付きで作成します。(id以外の要素でも可能です。参考URL参照)
この例だと、ajax.POST時のデータとして下記のような形式で簡単に操作できます。

group[]=1&group[]=2&group[]=3

Rails側ではpost[:group]で取得できますね。

CSRF用token

POSTなのでCSRFのWARNING(WARNING: Can't verify CSRF token authenticity)が出ないように
view側でtokenを作っています。POST時に合わせて送ります。
(httpのheadに仕込む方法もあるようです。)

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
js

ポイントは3つ。
・sortableによるグリグリ実装
・sortable('serialize') 前述のデータ形式
・authenticity_token

$(function(){
  $('.column').sortable({
    connectWith: '.column',
    handle: 'h2',
    cursor: 'move',
    placeholder: 'placeholder',
    forcePlaceholderSize: true,
    opacity: 0.4,
    update: function() {
      $.ajax({
        url: '/groups/sort',
        type: 'POST',
        dataType: 'text',
        data: $(this).sortable('serialize') + '&authenticity_token=' + $('#authenticity_token').val(),

      })
    }
  })
  .disableSelection();
});

Rails contorller

  def sort
    params[:group].each_with_index{|row, i| Group.update(row, {:ordinal => i + 1})}
    render :nothing => true
  end
scss抜粋
/* ------------------------------
 Drag and Drop
------------------------------ */
.column{
  width:280px;
  margin-right:.5%;
  min-height:300px;
  background:#fff;
  float:left;

  .dragbox{
    margin:5px 2px 20px 0;
    background:#fff;
    position:relative;
    border:1px solid #ddd;
    -moz-border-radius:5px;
    -webkit-border-radius:5px;

    h2{
      margin-bottom:5px;
      padding:5px;
      background:#f0f0f0;
      border-bottom:1px solid #eee;
      cursor:move;
    }
  }

  .placeholder{
    background: #f0f0f0;
    border:1px dashed #ddd;
  }
}

感想

sortable('serialize')とかCSRFの辺りは、少々はまりましたが
こんだけで実装できるなんて
JQueryRailsもすごい。