Rails3とjQueryでAjax更新
セレクトボックスを選択したら非同期通信でDBを更新する
セレクトボックスを変更した時点で非同期通信でDB更新、最新の状態を表示する。
formの:remote => true のようにボタンを用いないAjaxの実装。
一覧画面でステータスのみを更新したり、フィルター機能をボタンを押下せずに実現する。
View1 index.html.erb
<h1>注文リスト</h1> <div id="order_list" style="display: inline;"> <%= render :partial => 'list_body' %> </div>
View2 部分テンプレート _list_body.html.erb
option:中身はモデルに定義。
onchange:セレクトボックスの値を変更すると指定したJSが呼び出される。
<table> <thead> <tr><th>状態</th><th>お届け先住所</th></tr> </thead> <tbody> <% @orders.each do |order| %> <tr> <td><%= select(:order, :"status_#{order.id}", Order::ORDER_STATUS, {:selected => order.status}, {:onchange => "update_status(\'#{order.id}\')"}) %></td> <td><%= order.address %></td> </tr> <% end %> </tbody> </table>
JavaScript order.js(viewのonchangeで指定したJSを定義。Ajaxでサーバのアクションを呼び出し。)
dataで変更されたデータのIDと、ステータスの値を定義。&区切り。
element:変更されたセレクトボックスのid
$(element).val():val()で選択されたoptionの値を取得
function update_status(o_id) { var element = "#order_status_" + o_id $.ajax({ url: "/order/update_status", type: "POST", data: 'id=' + o_id + '&status=' + $(element).val() }) }
Controller
JSのdata内で定義された値はparamsで取得可。
def update_status order = Order.find_by_id(params[:id]) order.update_attributes!(:status => params[:status]) @orders = Order.all end
update_status.js.erb (jQueryになってrjsではなくなりました。)
View1の更新する箇所の要素のidとその中身となる部分テンプレートを記述。
escape_javascriptでrender以降が解釈されるようにする。
$("#order_list").html("<%= escape_javascript(render 'list_body', :orders => @orders) %>");