&tag(Rails3/Ajax);
*目次 [#y072c49a]
#contents
*参考情報 [#b923fdee]
-[[Rails3]]
*基本 [#e9cfb3a6]
-複数のファイルが連携するので直感的に分かりづらい。
-ビューの*.html.erbからajaxでコントローラー呼び出し→remote=true→コントローラーで処理→*.js.erb実行という流れになる。最後の*.js.erb実行時にhtmlを組み立てる必要がある場合、部品を部分テンプレートとして外出しにしてくのが基本パターン。
*Ajaxで時刻を書き換える [#n4b91baf]
**index.html.erb [#p4b68182]
-リンククリックで現在時刻のdivの内容を書き換える。簡単なので部分テンプレートなし。
#pre{{
<div id='result'>現在時刻: <%= Time.now %></div>
<%= link_to '更新', {:action => 'upanel'}, :remote=>true %>
}}
** ajax_controller.rb [#jb0512bf]
-@timeに現在時刻を設定。
#pre{{
def upanel
@time = Time.now.to_s
end
}}
**upanel.js.erb [#ucdfd795]
-jQueryを使って(Rails3の場合デフォルト有効)、resultを書き換えている(index.html.erbのdivタグ)。
#pre{{
$('#result').html(
"<%= escape_javascript('現在時刻: ' + @time) %>"
);
}}
*都道府県の絞り込み [#ae1b067e]
**基本 [#t92ba130]
-もう少し実用的な例として、都道府県、市町村セレクトを2つ使った絞り込みのサンプル。都道府県が変われば、市町村セレクトの中身が変わるというイメージ。
**index.html.erb [#m00ffea2]
- 呼び出し元のhtml.erb。jQueryのchangeを使って、都道府県セレクト(pref_id)が変わった時にajaxリクエストを送信するようになっている。
-市町村セレクトはajax処理後に書き換える必要があるので、部分テンプレート(_select_city.html.erb)になっている。
#pre{{
<h1>都道府県の絞り込み</h1>
<%= form_tag({:action => 'result'}) do %>
<%= select_tag "pref_id", options_for_select(@prefectures.map{|obj| [obj.name, obj.id]}, params['pref_id']), :prompt => "選択してください" %>
<%= render :partial => 'select_city' %>
<%= submit_tag '実行' %>
<% end %>
<h1 id="result">結果</h1>
<script type="text/javascript">
$(function(){
$('#pref_id').change(function(){
var pref_id = $("#pref_id").val();
$.get("city_select?pref_id=" + pref_id);
})
});
</script>
}}
**_select_city.html.erb [#v2142ea0]
-構造的には都道府県、市町村セレクトともに同じ。id、nameを持つオブジェクトを使って組み立てている。
#pre{{
<%= select_tag "city_id", options_for_select(@cities.map{|obj| [obj.name, obj.id]}, params['city_id']), :prompt => "選択してください" %>
}}
**ajax_controller.rb [#i9b766da]
-サンプルなのでとりあえず固定でデータは作成。
-selectは、最初に表示したときの処理、 city_selectが都道府県セレクトが変更されたときに呼ばれるajax処理となる。
#pre{{
class Prefecture
def initialize
@cities = []
end
attr_accessor :id, :name
attr_accessor :cities
end
class City
attr_accessor :id, :name
end
def upanel
@time = Time.now.to_s
end
def init(pref_id)
p1 = Prefecture.new
p1.id = 1
p1.name = '東京'
p2 = Prefecture.new
p2.id = 2
p2.name = '埼玉'
p3 = Prefecture.new
p3.id = 3
p3.name = '神奈川'
@prefectures = [p1, p2, p3]
c11 = City.new
c11.id = 11
c11.name = '浅草'
c12 = City.new
c12.id = 12
c12.name = '八王子'
p1.cities = [c11, c12]
c21 = City.new
c21.id = 21
c21.name = '川口'
c22 = City.new
c22.id = 22
c22.name = '所沢'
p2.cities = [c21, c22]
c31 = City.new
c31.id = 31
c31.name = '横浜'
p3.cities = [c31]
pref = @prefectures.find{|pref| pref.id == pref_id}
@cities = pref.cities
params[:pref_id] = pref_id
params[:city_id] = pref.cities[0].id
end
def select
init(1)
end
def city_select
init(params[:pref_id].to_i)
end
}}
**city_select.js.erb [#jacea518]
-コントローラーのcity_selectの後に実行される。
-#resultはデバッグ用。#city_idが市町村セレクト。部分テンプレートを使っている。
#pre{{
$("#result").html("<%= params[:city_id] %>");
$("#city_id").html("<%= escape_javascript(render :partial => 'select_city', :pref_id => params[:pref_id]) %>");
}}