親プルダウンから取得したデータで子プルダウンを変更する
親プルダウンで選択された内容を、jQueryとajaxを使ってspringMVCのコントローラに送信し、子プルダウンに表示したいデータを受け取って表示する・・・ということが初心者なりになんとなくわかったので忘れないためのメモ書きです。
- 送信する際のURLの末尾に送りたいデータをくっつけること
- JSON形式の文字列でデータを受け取り、JSONに変換すること
が個人的にポイントでした。
1. jsp側での記述
jspで2つのプルダウンを下記のように作っておきます。 初期状態として、コントローラでitemsにプルダウンの中身を入れておいてあります。
<form:select id="pulldown1" path="pulldownParent" >
<form:options items="${pulldownList1}" itemValue="pulldown1_key" itemLabel="pulldown1_name" >
</form:options>
</form:select>
<form:select id="pulldown2" path="pulldownChild" >
<form:options items="${pulldownList2}" itemValue="pulldown2_key" itemLabel="pulldown2_name" >
</form:options>
</form:select>
2. jQueryの記述
jQueryで、親プルダウンの中身が変更されたとき、その選択された内容をコントローラにajaxで送信するようにします。
$(function(){
$("#pulldown1").change(function(){
var value = $("#pulldown1 option:selected").val();
$.get("pulldown/" + value ,function(data){
var obj = $.parseJSON(data);
$("#pulldown2").html("");
for(var i=0;i<obj.length;i++){
$("#pulldown2").append("<option value="+obj[i].itemValue+">"+obj[i].itemLabel+"</option>");
}
})
})
})
pulldown1の中身が変更されたとき、pulldown1の選択された内容を変数valueに取得します。
そしてajaxのjQuery.get()メソッドを使ってコントローラにデータを送信します。
第1引数はコントローラに送るためのURLで、formのaction属性の値と同じようにマッピングさせます。今回はGETでデータを送信するため、URLの末尾に送りたいデータ(value)をつなげています。
第2引数にあるのは、非同期通信が成功した際に実行される処理で、ここの引数にdataを入れておくことでコントローラからリターンされたデータをdataで受け取ることができます。おそらく。
この処理内では、コントローラから帰ってきたデータ(後述するJSON形式の文字列)を取得し、JSONに変換します。($.parseJSON(data)
で変換し、objにつめている)
あとは、子プルダウンの<select>
内にfor文でappendすればいいはずです。その際、innerHTMLで毎回<select>
内を空白にさせています。(そうしないとどんどんappendされてしまう)
objにつめたデータはオブジェクト.キーで取得できます。(キーは後述のJSON形式で設定できます)
ひとつのキーに複数の値が存在している際は、オブジェクト[i].キーなどとすれば配列のように取得可能なはずです。
3. Controllerの記述
コントローラでは、受け取ったデータを使ってDB検索などをかけ必要なデータを取得します。
pulldown_keyはInteger型、pulldown_nameはString型です。
//プルダウンの変更のためのメソッド
@RequestMapping(value="/pulldown/{value}",method=RequestMethod.GET,produces="text/plain;charset=UTF-8")
@ResponseBody
public String changePulldown(@PathVariable("value")String value){
//受け取るデータはURLにくっつけるため必ずStringとなってしまうため、数値を送っていたならば変換しておく
Integer val = Integer.parseInt(value);
StringBuilder s = new StringBuilder();
String str="";
s.append("[");
//文字列の中にダブルクォーテーションを入れるため、エスケープさせるのを忘れないこと
for(int i=0; i<{子プルダウンに表示する要素の総数}; i++){
s.append("{\"");
s.append("itemValue");
s.append("\"");
s.append(":");
s.append(子プルダウンに表示させるpulldown2_key);
s.append(",");
s.append("\"");
s.append("itemLabel");
s.append("\"");
s.append(":");
s.append("\"}");
s.append(子プルダウンに表示させるpulldown2_name);
s.append("\"}");
s.append(",");
}
//末尾のカンマを削除し、[{}]でくくった形になるようにしてStringに変換する
s.deleteCharAt(s.lastIndexOf(","));
s.append("]");
str = s.toString();
return str;
}
まず、@RequestMapping
でGETで送られてくるデータを受け取れるようvalue属性を調整し、produces属性も追加します。(これを追加しないとなぜか文字化けしていました)
そして@RequestBody
をつけ、データをそのままリターンできるようにします。
送られてくるデータを、@PathVariable
をつけた引数のvalueで受け取り、送り返すデータを取得しておきます。
JSON形式の文字列で送らないといけないため、取得したデータをJSON形式のひとつのStringに詰め込みます。JSON形式は{"キー1":"値","キー2":"値",...}
という形式となっていて、中身の文字列には必ずダブルクォーテーションをつけないといけないそうです。また、同じキーで複数の値が存在する際は、[{"キー1":"値","キー2":"値"},{"キー1":"値","キー2":"値"},...}]
となります。今回は後者の方を使って、
[{"itemValue":"値1","itemLabel":"値A"},{"itemValue":"値2","itemLabel":"値B"}]
となるようにしています。
これでreturnすればデータを送り返せるはずです。後は2のjQueryでの記述内の処理でプルダウンが変更されるはずです。たぶん。
かなりゴリゴリさせている部分やおかしなところがあると思うので、なにかあったらアドバイスください...明らかにおかしい部分は修正しました(7/30)