rest_in_place を使って、テーブルの中でインライン編集する。

rest_in_place を使って、テーブルの中でインライン編集する。

http://github.com/janv/rest_in_place/blob/master/javascripts/rest_in_place.js は prototype バージョンだった。

( script/generate scaffold Test name:string memo:text で作って試した。testという名前が分かりにくかったかも・・)

(1)rest_in_place.js をダウンロードしてjavascriptディレクトリに入れる(他のファイルは要らない!)。

public\javascripts\rest_in_place.js

(2)レイアウトファイル
app\views\layouts\tests.html.erb

  <%= javascript_include_tag :defaults %>
  <%= javascript_include_tag "rest_in_place" %>
  <script type="text/javascript">
    rails_authenticity_token = '<%= form_authenticity_token %>'
  </script>

と入れる。(form_authenticity_token の処理もスマートかも)。

(3)indexテンプレートの
app\views\tests\index.html.erb
のテーブル表示の部分

<% @tests.each do |test| %>
  <tr>
    <td><%=h test.name %></td>
    <td><%=h test.memo %></td>
    <td><%= link_to 'Destroy', test, :confirm => 'Are you sure?', :method => :delete %></td>
    <td><%= link_to 'Show', test %></td>
    <td><%= link_to 'Edit', edit_test_path(test) %></td>
  </tr>
<% end %>

</table>
<% @tests.each do |test| %>
  <tr>
    <td class="rest_in_place" data-url="<%= url_for test %>" data-formtype="input" data-object="test" data-attribute="name"><%= test.name %></td>
    <td class="rest_in_place" data-url="<%= url_for test %>" data-formtype="input" data-object="test" data-attribute="memo"><%= test.memo %></td>
    <td><%= link_to 'Destroy', test, :confirm => 'Are you sure?', :method => :delete %></td>
  </tr>
<% end %>
</table>

とする。(<span>タグで指定するよりも<td>に直接セットした方が良い。ターゲットが大きくなり、内容が空でも反応するようになる)。
共通部分は<tr>タグや<div>タグにまとめてもよい。(ただし、class="rest_in_place" はターゲットの指定になるので<td>タグ(または普通は<span>タグ)に残す必要がある)。

<% @tests.each do |test| %>
  <tr data-url="<%= url_for test %>" data-formtype="input" data-object="test" >
    <td class="rest_in_place" data-attribute="name"><%= test.name %></td>
    <td class="rest_in_place" data-attribute="memo"><%= test.memo %></td>
    <td><%= link_to 'Destroy', test, :confirm => 'Are you sure?', :method => :delete %></td>
  </tr>
<% end %>
</table>

ここでの意味は
# data-url="<%= url_for test %>" は updateアクションへのURLを生成する。
# data-formtype="input" は、textfieldを作成する。
# data-object="test" はモデル、コントローラの指定。
# class="rest_in_place" は、rest_inplace.js が組み込まれたとき(onload)に書き換えを行うターゲットとなる。
# data-attribute="memo" は項目名。

テーブルで処理する場合のポイントは(indexアクションではなく) updateアクションとshowアクションで処理するように、data-url="<%= url_for test %>" を指定すること。

(4)コントローラの showアクションと updateアクションに jsonフォーマットの処理を加える。

  def show
    @test = Test.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @test }
      format.json { render :json => @test}  # ← ★
    end
  end

  def update
    @test = Test.find(params[:id])

    respond_to do |format|
      if @test.update_attributes(params[:test])
        flash[:notice] = 'Test was successfully updated.'
        format.html { redirect_to(@test) }
        format.xml  { head :ok }
        format.json { render :json => @test}  # ← ★
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @test.errors, :status => :unprocessable_entity }
      end
    end
  end

これだけで、テーブルの中でインライン編集ができるようになる。

−−−

なんで、テンプレートに javascriptを書かなくてもよいのかと思ったら、
rest_in_place.js の最後に次のように書いてあった。
rest_in_placeクラスのDOM要素を捜して、その要素にjavascriptのonClickイベントハンドラをセットするonLoadイベントをセットしているのでした。

Event.observe(window, 'load',function() {
  $$(".rest_in_place").each(function(e){
 ・・・