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){ ・・・