Ruby on Rails Ajax でカートを空にする時に blind_up 効果を付ける
Rails によるアジャイルWebアプリケーション開発 第3版 の『第9章 タスク D : Ajax の追加』の自由課題『カートを空にする際に blind_up を使う方法』について。
フォームボタンを Ajax に対応させる
app/views/store/_cart.html.erb ファイルの button_to
で作られるフォームボタンを form_remote_tag
で作られる Ajax 対応のフォームに変更する。
<% form_remote_tag :url => { :action => "empty_cart" } do %> <%= submit_tag "Empty Cart" %> <% end %>
コントローラの返すレスポンスを修正する
app/controllers/store_controller.rb 内の empty_cart
メソッドが呼出された時に返すレスポンスを JavaScript を返すように修正する。
def empty_cart session[:cart] = nil respond_to do |format| format.js if request.xhr? format.html { redirect_to_index } end end
レスポンスとして返す JavaScript を作る
app/views/store/empty_cart.js.rjs にカートを blind_up
して消す処理を記述する。
page[:cart].visual_effect :blind_up page.replace_html("cart", :partial => "cart", :object => @cart)
これで、カートを空にするためにボタンをクリックしてみると画面表示は変化しない。
ブラウザをリロードするとカートは空になるのでセッション・データからはアイテムが削除されている。
エラーの原因は store_controller.rb の empty_cart
メソッドで @cart
インスタンスを設定していなかったので _cart.html.erb の cart
が nil
となっていたため。
そこで、 empty_cart
メソッドに @cart = find_cart
を追加して @cart
インスタンスを設定するが、これだけだとリロードして @cart
インスタンスを作り直さないと @cart
の中身が空にならない。
カート部分の display
が none
になるために、一見消えているように見えるが、HTML タグのソースを見るとしっかりカートの中身が残ってしまっている。
そこで、 app/models/cart.rb の Cart
モデルにカートの中身を空にする(@item
を空にする)メソッド empty
を追加して、コントローラの empty_cart
メソッドでカートの中身を空にする処理を加える。
app/models/cart.rb に empty
メソッドを追加する。
def empty @items.clear end
app/controllers/store_controller.rb の empty_cart
メソッドでカートを空にする。
def empty_cart @cart = find_cart @cart.empty session[:cart] = nil respond_to do |format| format.js if request.xhr? format.html { redirect_to_index } end end
これで、カートは空になった。
ただ、カートを空にする時に、カート部分の HTML を書き換える処理と blind_up
の処理が同時に行なわれるために、一瞬でカートの中身が消えてしまい($0.00 になった合計のみが表示される)、その後 blind_up
の処理が行われるような感じになってしまう。
この部分、上手い解決方法がわからないので処理時間を合せて強引に blind_up
処理が終了するとともにカート部分の HTML 書き換えが行なわれているように見せるようにした。
ちょっといまいちな解決法…
app/views/empty_cart.js.rjs で delay
使って HTML の書き換えを遅らせている。
page[:cart].visual_effect :blind_up, :duration => 1 page.delay(1) do page.replace_html("cart", :partial => "cart", :object => @cart) end
これで、思ったような動作になった。
JavaScript を OFF にすると format.html
でレスポンスが返されてちゃんと動作している。
オーム社
売り上げランキング: 29946