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です。
試しにサブルーチンかしてみたら、うまくいきました。

今回悩んだこと

今回は複数の事象についてどうすればいいのか悩みました。
それがこちらです。

  1. SELECTの選択肢をその都度書き換えるにはどうすればいいのか?
  2. その選択肢を配列化しておくことはできるのか?
  3. 大項目選択時に、どの小項目テーブルを使用すればよいか区別をつけることができるのか?

難問が複数同時に来ると、パニックになってしまいがちです。
なので私は今回は頭からひとつづつ問題点を解決してゆきました。

3回解決したら完成していました。

千里の道も一歩からといいますが、難問も千個に分解すれば簡単な問題の集合体です。
パニックになる前に、地道に一つずつ解決してゆくことが結果的に近道です。

今回のレポートは以上です。
読んでいただいてありがとうございました。


ホームページに関するお悩み事やご相談事がございましたら私どもまでご連絡ください。 鋭意ご対応申し上げます。
ホームページのご提案もさせていただいております