プログラミングノート

一からものを作ることが好きなエンジニアの開発ブログです。

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>