概要
単一選択のセレクトボックスが複数個あって連動させる場合、
ajax通信でn個目の選択状況を反映して~といったことはしたくない。
こういうときなんか楽な方法ってないでしょうか。
以下、optgroupというタグとjQueryを使ってサボる方法。
html のoptgroup
存在を忘れていたけどそういえばこんなタグがあった。
話を分かりやすくするために、セレクトボックス2個の親子関係を例にする。
親の選択が子にも影響するって感じ。
<select name="parent">
<option value="">(指定なし)</option>
<option value="1">hogehoge.jp</option>
<option value="2">Yahoo! Japan</option>
<option value="3">Test</option>
</select>
<select name="child">
<option value="">(指定なし)</option>
<optgroup label="hogehoge.jp">
<option value="1">hogehoge</option>
<option value="3">fugafuga</option>
</optgroup>
<optgroup label="Yahoo! Japan">
<option value="2">Yahoo! Japan</option>
<option value="4">ヤフー知恵遅れ</option>
</optgroup>
<optgroup label="Test">
</optgroup>
</select>
jQuery
jQueryで選択状態の反映を実現する。
ソースコードは…まあ参考までということで。
// 親の選択が変更された場合、子の表示を変更しつつ処理する
$("select[name='parent']").change(function() {
// 子の選択状態を解除
$("select[name='child'] option:selected").attr("selected", false);
$("select[name='child']").val([""]);
// 子を全て非表示で初期化
$("select[name='child'] > optgroup").each(function() {
$(this).attr("hidden", "hidden");
});
// 親の選択済みをループさせて子を処理する
$("select[name='parent'] option:selected").each(function() {
var val = $(this).val();
var text = $(this).text();
// ラベルで比較は気持ち悪いね
if (val != "") {
// 親の選択状態が(指定なし)以外の場合、子も限定させる
$("select[name='child'] > optgroup").each(function() {
if ($(this).attr('label') === text) {
// ラベルが親と一緒の場合、hiddenを消すことで見せる
$(this).removeAttr("hidden");
} else {
// ラベルが親と違うから、hiddenで消す
// 実は上で既にやってるから要らないけど、一応書いておく
$(this).attr("hidden", "hidden");
}
});
} else {
// 親の選択状態が(指定なし)の場合、全部見せる
$("select[name='child'] > optgroup").each(function() {
$(this).removeAttr("hidden");
});
}
});
});