RailsでAjax
link_to_remote を利用したAjaxな実装メモ。
トリガー作成
標準で付属しているprototype.jsなどをjavascript_include_tagでロードし、link_to_remoteで非同期通信のトリガーとなるリンクを作成。before/success/failure辺りはなくても動作する。
<%= javascript_include_tag :defaults %> <%= link_to_remote "ここをクリック", :url => {:action=>'testJson'}, :before => "$('indicator').show()", :success => "showList(request)", :failure => "alert('failure')", :complete => "$('indicator').hide()" %>
このヘルパーで生成されるJavascriptはこんな感じ。
<a href="#" onclick="$('indicator').show(); new Ajax.Request('/main/test', {asynchronous:true, evalScripts:true, onComplete:function(request){$('indicator').hide()}, onFailure:function(request){alert('failure')}, onSuccess:function(request){showList(request)}, parameters:'authenticity_token=' + encodeURIComponent('400c02e8aa8e3c8fda9f2b58b40d13f55cb7d6ff')}); return false;">test</a>
非同期で実行されるアクション
リンクがクリックされると、:actionで指定したアクションが非同期で実行される。リンクを表示しているviewとは違うcontrollerで処理したければ、:controllerも指定しておけばよい。render :json とするとJSONフォーマットで値を返してくれる(render :xml だとXML、render :text だとテキスト)。
def testJson json = { "todo"=>[ {"title"=>"Railsで何かつくる", "lim"=>"2008/3/31"}, {"title"=>"引っ越したい", "lim"=>"2008/3/31"}, {"title"=>"TOEIC900とる", "lim"=>"2009/3/31"} ] } render :json => json; end
JSONの処理
最後に、コントローラーで生成したJSONを処理するスクリプトを準備して終了。
Javascriptもっと上手く書けるようになりたいなぁ。。
<script> function showList(request){ var json = eval('(' + request.responseText + ')'); var list = ""; for(var i =0; i<json.todo.length; i++){ list += "<li>" + json.todo[i].title + "( "+ json.todo[i].lim +" )</li>"; } $("todo").innerHTML = "<ul>"+ list +"</ul>"; } </script> <div id="indicator" style="display:none">loading..</div> <div id="todo"></div>