ajaxを使って連動したプルダウンをつくる

#親プルダウンから取得したデータで子プルダウンを変更する

親プルダウンで選択された内容を、jQueryとajaxを使ってspringMVCのコントローラに送信し、子プルダウンに表示したいデータを受け取って表示する・・・ということが初心者なりになんとなくわかったので忘れないためのメモ書きです。

* 送信する際のURLの末尾に送りたいデータをくっつけること
* JSON形式の文字列でデータを受け取り、JSONに変換すること
<br />
が個人的にポイントでした。
<br />
<br />
**1. jsp側での記述**<br />
jspで2つのプルダウンを下記のように作っておきます。
初期状態として、コントローラでitemsにプルダウンの中身を入れておいてあります。

```jsp


<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>

```
<br />
**2. jQueryの記述**
jQueryで、親プルダウンの中身が変更されたとき、その選択された内容をコントローラにajaxで送信するようにします。

```js


$(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].キー**などとすれば配列のように取得可能なはずです。

<br />
**3. Controllerの記述** 
コントローラでは、受け取ったデータを使ってDB検索などをかけ必要なデータを取得します。
pulldown_keyはInteger型、pulldown_nameはString型です。

```java

//プルダウンの変更のためのメソッド
@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での記述内の処理でプルダウンが変更されるはずです。たぶん。
<br />
かなりゴリゴリさせている部分やおかしなところがあると思うので、なにかあったらアドバイスください...明らかにおかしい部分は修正しました（7/30）