form_remote_tagの追記
↓前回「RailsのJS機能を使う(表示非表示切り替え)」での続き
http://d.hatena.ne.jp/sakusan_net/20080416/1208309196
前回投稿できるところまでは書きましたが、結果が反映されるところを作りました。
で、よくみるとupdateの値が間違えていたのでここで修正します。
<div id="filter" style="display: none"> <%= form_remote_tag :update => 'filter', :url => {:action => 'add_tags', :id => @charimg.id}%> <%= text_field_tag 'tags', "" , :size => 40 %> <%= submit_tag 'Save' %> </form > </div>
前回こうかいていたとおもうのですが、:updateは投稿後html内容をリロード無しにアップデートするDIV要素のIDを入れるところだったのに自分のDIV要素を指定していました。
<div id="updatediv"> <%= javascript_include_tag :defaults %> <%= link_to_function "<b>[追加]</b>","Element.toggle('filter')"%> #(投稿で更新したい内容)# <div id="filter" style="display: none"> <%= form_remote_tag :update => 'uodatediv', :complete => "Element.toggle('filter')", :url => {:action => 'add_tags', :id => @charimg.id}%> <%= text_field_tag 'tags', "" , :size => 40 %> <%= submit_tag 'Save' %> </form > </div> <div>
こうするのが正解でした。
詳しくは
$prototype->form_remote_tag({ :url => 'url', :update => 'id', :complete => "comp", });
:method
リクエストメソッド
:url
submit先アクションなどを定義
:update
urlのアクションの結果レスポンスを挿入するコンテナを指定
ここで指定したidに対して、prototype.jsで document.getElementById(id).innerHTML = req.responseText; みたいに実行するとのこと
:position(Before,Top,Bottom,After)
挿入位置指定
:type(synchronous,asynchronous)
デフォルトでasynchronous
以下状況によってJS実行などをする方法
:loading
:loaded
:interactive
:complete
:complete => "Element.toggle('DIV要素')"
とかすると実行完了後にDIV要素の表示とかが出来る。
で、さらにここからが他の説明で分かりにくかったので追記
いつもどおりの罠ってやつですね
上記のViewは_tags.html.erbという部分挿入で出来ているわけですが、:updateっていうのは部分リロードと等価ではなく、「コントローラからのレンダリング命令を指定DIV部分と入れ替える」ということで。
部分リロードだと思っていたさくさんはおもいっきり時間を費やしたわけで。
def add_tags @charimg = Charimg.find(params[:id]) @charimg.tag_list.add(params[:tags]) @charimg.save render :partial => 'tags' ←これが罠 end
この場合上のViewはrender:partialで読み込まれた部分テンプレートなので、add_tagsをしたらその部分テンプレート全部をごそっと新しいものに取替えれば完了です。
ちなみに1ページにこの部分テンプレートが多数表示される場合、現在分かりやすいようにupdatedivとかfilterとかなっている要素にオブジェクトIDをくっつけるなどして全部違う要素名になるように工夫してください。