実務で住所のプルダウンを実装する機会がありました。
[東京都][中央区][明石町]
みたいにカテゴリーが2〜3あって連動するプルダウンのパターンです。
これを実装するときのポイントですが、新規保存よりも編集の方が難しいです。
編集時には親の値を意識したプルダウンのリストを持っている必要があります。
今回でいうと[中央区]には市区町村のプルダウンが入ります。
このプルダウンは親(今回でいうと東京都、つまりは都道府県)に依存するため、親の値を意識したリストを持っている必要があります。
実装方法としては2つあります。
- 親の値を意識したプルダウンリストをプログラム側で保持しておく
- 画面読み込み時にJavaScriptで親の値を擬似的に選ぶ(changeイベントの発火)
1がスタンダードな方法ですが、項目数が少ない場合には2の方が簡単だったりします。
書き方ですが下記のような方法でいけます。
1 |
$(親セレクタ).val(選択された値).trigger('change') |
上記のような書き方でイベントが発火しますので、画面が読み込まれた時にJSが発動して、連動プルダウンが動きます。
注意点としてはプルダウンの連動の場合、非同期であることを忘れてはいけません。要は
[東京都][中央区][明石町]
のような場合、
都道府県のchangeイベントが発生し、それを受けて次に市区町村のchangeイベントが発生し、最後に町村のchangeイベントが発現します。
この場合、親のイベントが終わったことを受けて、子供がイベントをキャッチしないといけませんが、普通に下記のように書くと非同期のために親が終わらないうちに子の処理が始まってしまいます。
1 2 |
$(親セレクタ).val(選択された値).trigger('change') $(子セレクタ).val(選択された値).trigger('change') |
この場合、親の処理を終えた後に子の処理を動かしたい場合ですが、whenを使って下記のように書くことができます。
1 2 3 4 5 6 |
$.when( $(親セレクタ).val(選択された値).trigger('change') ).then(function(){ $(子セレクタ).val(選択された値).trigger('change') }) //3つ以上の場合はさらに.thenを続けます。 |
詳しい仕様は調べ中ですが、Promiseなどと近い感じで非同期処理をかけるようです。
これだとプログラム側で親の値を意識したプルダウンを書かなくてもいいので楽ですね。
欠点としては画面の項目数が多いとものすごい遅延してしまって、実用には耐えられないことですかね・・・今回の要件では結局10箇所ぐらいに同一のプルダウンがあったため、没になり、プログラム側でリストを作る手法を選びましたが覚えておいて損はなさそうです。
*注意点
上記の処理の場合、同一のイベントが画面内に複数ある場合、when〜以下の処理は関数でひとまとまりにしてあげないとうまく連動しません。(実行順番が保証されないようです。)
このように書いてはダメで、
1 2 3 4 5 |
//要素などを配列に入れてforで回す for(){ // $.when()〜 } |
下記のように書かないといけません。
1 2 3 4 5 6 7 |
for(){ whenTask() } funciton whenTask(){ $.when〜 } |
参考URL
[…] ajaxがらみのイベントの発動とwhenに関して […]