Menu

Category

Archive

logo


Ajaxによるページ部分更新 [ Ruby on Rails ]

2013-12-26 03:14:00 +0900
  • このエントリーをはてなブックマークに追加

Ajax を使ってウェブサイトの一部分のみを更新する方法です。Ajaxを使うことにより、ページ遷移をなしで、DBと通信しながらページコンテンツの一部を変更することができます。今回は、<select>の<option>が変更されるたびにページの一部を変更するという機能を実装してみます。実装方法は違うかもしれませんが、http://www.assist.org/web-assist/welcome.html と同じような処理です。

htmlページの準備

まずは、DBとの通信のトリガーになる<select>をページに追加します。ユーザーがページの<select>を変更すると、<select>のonchange()が起動します。onchange()からのちほど作成するカスタム関数を呼び出し、その関数からDBとの通信を発動します。そして、ページのコンテンツを変更します。

1 # test.html.erb
2 <%= collection_select(:major, :id, @majors, :id, :name,  {:prompt => "Please select your major"},{:onchange => "changeMajor()" }) %>

これにより、 @majors に格納されている major モデルの id と name がそれぞれ value と<option></option>に動的に記述されます。valueはサーバーに送信される値で、<option></option>はページに表示される文字列です。ここでは :prompt オプションにより何も表示されていない時には “Please select your major” と表示されるます。onchange() メソッドではこれから自分で作成する changeMajor()メソッドを<select>の<option>が変更されるたびに呼び出されます。また<select>のhtml属性idはmajor_idとなります。

1 # test.html.erb 
2 <div id="classList" style="display: inline;">
3     <%= render :partial => 'classList_body' %>
4 </div>

この箇所がDBとの通信が終わった時に変更される箇所です。のちほど classList_body.html.erb というファイルは作成します。<select>が変更されDBとの通信ごとにclassList_body.html.erb が新しくレンダリングされるということですね。

onchange で呼ばれる Javascript 関数の準備

 1 // test.html.erb 
 2 // onchange メソッド
 3 function changeMajor(){
 4      var select = document.getElementById('major_id');
 5      var options =  document.getElementById('major_id').options;
 6      var value = options.item(select.selectedIndex).value;
 7      var universityID = <%= @student.universities.first.id %>;
 8  
 9      $.ajax({
10           url: "/students/listEachClass",
11           type: "POST",
12           data: 'id=<%= @student.id %>&majorID=' + value + '&universityID=' + universityID
13      })
14 }

これが呼び出されるchangeMajor()メソッドです。ポイントは後半の$.ajaxですね。送信するurlと通信方法の指定、そしてコントローラー側が受け取る値をdataで指定しています。前半のJSはもう少しスマートな方法がありそうですね。。。JSはいつもやっつけになってしまいます。

通信ごとに呼ばれるパーシャルの準備

1 #_classList_body.html.erb  
2 <p><%= @universityID %></p>
3 <p><%= @majorID %></p>

今回はとてもシンプルです。この@universityID と@majorID はコントローラーで作成される変数?です。onchagenメソッドで選択されている<select>の値がサーバーに送信され、コントローラーで作成された変数を後ほど作成するJavascriptファイルからこのパーシャルをレンダリングする際に、それらの値を渡すことで、このパーシャルの中で使うことができます。

Javascriptファイルの準備

1 # listEachClass.js.erb
2 # 上記のtest.html.erbがあるviewフォルダにこのファイルを作成
3 $("#classList").html("<%= escape_javascript(render 'classList_body', :majorID => @majorID, :universityID => @universityID) %>");

ここでは上記の test.html.erb で指定した id=classList <div>に 2 で作成したパーシャルをレンダリングするということを記述しています。render する際に、コントローラーで作成された変数をパーシャルで使えるように渡しています。

コントローラーの準備

1 def listEachClass
2     puts "==== Here is the listEachClass!! ===="
3     @majorID = params[:majorID].to_i
4     @universityID = params[:universityID].to_i
5  
6     puts @majorID
7     puts @universityID
8 end

コントローラーはみなさん思い思いの処理をしていただければいいと思います。params[:majorID] やparams[:universityID] と記述することにより、1で作成したchangeMajor()のdataで渡された値を参照することができます。ここでは単に数値にしてそれをログに表示させているだけです。何もしていませんね。

以上です。