JqueryでSELECTの選択肢を自由に変化させる

JqueryでHTMLを流動的に書き換えることはよくあります。
実際にエラーメッセージ等を出力する場合等に重宝します。
今回、JqueryでHTMLの書き換えを実装することになったのですが、書き換えるのはSELECTフォームの選択肢です。
具体的には、SELECTフォームが2つあり、一つ目の選択内容によって、2つ目のSELECTフォームの選択肢を変化させるというものです。
EC-CUBEでよくあるやつです。
やればできることですが、どうやればいいの?
状態でした。
いろいろググり、試行錯誤して実装できましたので、備忘録として記録いたします。
今回やりたいこと
サンプルを見ていただければ一目瞭然ですが、大項目の選択によって、小項目の選択肢が変化します。





今回のソースはこちら
<!doctype html><html><head><metacharset="shift_jis"><title>セレクトで値を切り替える</title><scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script><script>
$(document).ready(function()
{
// (2)選択肢テーブル// 色テーブルvar color_table =
[
{value: "red", label: "赤"},
{value: "blue", label: },
{value: "yellow", label: },
{value: "pink", label: },
{value: "green", label: }
]
// サイズテーブルvar size_table =
[
{value: "small", label: },
{value: "normal", label: },
{value: "big", label: "大きい"}
]
// (3)大項目が変化した場合に発火
$("[name=syubetu]").change(function()
{
var select_value = $(this).val();
$("[name=sub]").children().remove();
if (select_value == 1)
{
// (5)選択肢をセット// 色テーブルをセット
color_table.forEach( function(table)
{
$("[name=sub]").append($("<option>").attr({ value: table.value}).text(table.label));
});
}
elseif (select_value == 2)
{
// サイズテーブルをセット
size_table.forEach( function(table)
{
$("[name=sub]").append($("<option>").attr({ value: table.value}).text(table.label));
});
}
});
});
</script><styletype="text/css">.box
{
padding: 20px;
width: 400px;
margin-right: auto;
margin-left: auto;
}
section
{
padding: 10px;
margin-bottom: 20px;
border: 1px solid #ccc;
}
p
{
margin: 0px;
}
select
{
font-size: 18px;
padding: 10px;
}
</style></head><body><divclass="box"><p></p><section><p>大項目</p><selectname="syubetu"><optionvalue="">大項目を選択してください</option><optionvalue="1">色</option><optionvalue="2">大きさ</option></select></section><section><p></p><selectname="sub"></select></section></div></body></html>
Code language:HTML, XML(xml)
例のごとくまとめてみると何のことかわからないので、分解して考えます。
(1)SELECTフォーム部分
<section><p>大項目</p><selectname="syubetu"><optionvalue="">大項目を選択してください</option><optionvalue="1">色</option><optionvalue="2">大きさ</option></select></section><section><p></p><selectname="sub"></select></section>
Code language:HTML, XML(xml)
セレクトフォーム部分は、通常の記載と同じです。
違う部分は、小項目の選択肢(option)が1つも記述がありません。
これは、Jqueryで後から付け足すため記述する必要がないのです。
(2)選択肢テーブル部分
// 色テーブルvar color_table =
[
{value: "red", label: "赤"},
{value: "blue", label: },
{value: "yellow", label: },
{value: "pink", label: },
{value: "green", label: }
]
// サイズテーブルvar size_table =
[
{value: "small", label: },
{value: "normal", label: },
{value: "big", label: "大きい"}
]
Code language:JavaScript(javascript)
選択肢を付け足すには、後述しますがJqueryのappend()を使用します。
ただ、汎用性を高めるため、事前に選択肢を配列化しました。
Javascriptの二次配列については、こちらをご参考ください。
(3)大項目が変化した場合に発火する部分
$("[name=syubetu]").change(function()
{
});
Code language:JavaScript(javascript)
大項目が変化したら、小項目の内容を書き換えるので、大項目が変化したタイミングを検知しなければいけません。
それがこの部分です。
Jqueryの change()関数は、指定項目の値が変化したら発火します。
(4)現在の小項目を初期化する
$("[name=sub]").children().remove();
Code language:JavaScript(javascript)
大項目が確定したら、小項目の中身をいったんクリアする必要があります。
なぜならば、クリアしなければどんどん追加されてしまうからです。
今回は全削除ですが、個別削除も可能です。
例えば「赤」を消す場合は次のように記述します。
$("[name=sub]").children("[value=red]").remove();
Code language:JavaScript(javascript)
(5)選択肢を追加する
// 色テーブルをセット
color_table.forEach( function(table)
{
$("[name=sub]").append($("<option>").attr({ value: table.value}).text(table.label));
});
Code language:JavaScript(javascript)
Jqueryのappend()で小項目に選択肢を追加しています。
今回の最も肝心な部分です。
仕掛けは、(2)のテーブルをループさせ、テーブルの値の数だけ追加しています。
forEachは、配列をループさせる命令です。PHP等にはない記述方法なのでわかりにくいですが、foreach文と似ています。
appendは、タグをダイレクトに記述する方法もありますが、配列の値をセットすることを考えたら、分解してセットするやり方のほうがわかりやすかったです。
append部分は、共通で使えるためサブルーチン化してもOKです。
試しにサブルーチンかしてみたら、うまくいきました。
今回悩んだこと
今回は複数の事象についてどうすればいいのか悩みました。
それがこちらです。
- SELECTの選択肢をその都度書き換えるにはどうすればいいのか?
- その選択肢を配列化しておくことはできるのか?
- 大項目選択時に、どの小項目テーブルを使用すればよいか区別をつけることができるのか?
難問が複数同時に来ると、パニックになってしまいがちです。
なので私は今回は頭からひとつづつ問題点を解決してゆきました。
3回解決したら完成していました。
千里の道も一歩からといいますが、難問も千個に分解すれば簡単な問題の集合体です。
パニックになる前に、地道に一つずつ解決してゆくことが結果的に近道です。