以下のような大科目の下に小科目があるようなデータがある場合に、大科目を選ぶとそれに対応する小科目が表示されるメニューを作成してみました。ウェブ上では、あらかじめHTMLファイルの<option>
タグに記載するパターンが多かったので、必要な値はJavaScriptの変数に格納する方法でやってみました。
科目
┣食費
┃ ┗生鮮食品,中食,外食,飲料,お菓子,加工品
┣光熱費
┃ ┗電気代,ガス代,水道代,灯油代
┣医療費
┃ ┗治療費,処方箋薬,市販薬
┣娯楽費
┃ ┗パチンコ代,旅行代,お土産代,漫画
┣教育費
┃ ┗授業料,給食費,塾代,教科書代,書籍代
┗その他
┗冠婚葬祭費,タクシー代,家賃,税金,仕送り
まず、以下のHTMLファイルを作成
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>javascript lesson</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row">
<div class="form-group">
<label for="account1">大科目を選択してください</label>
<select class="form-control" id="account1" name="account1">
</select>
</div>
<div class="form-group">
<label for="account2">小科目を選択してください</label>
<select class="form-control" id="account2" name="account2">
</select>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<script src="index.js"></script>
</body>
</html>
次に、以下のJavaScriptファイルを作成
index.js
(function() {
var Acc1, accounts1, i, j, len;
accounts1 = [
"科目を選択",
"食費",
"光熱費",
"医療費",
"娯楽費",
"教育費",
"その他"];
j = 0;
for (i = 0, len = accounts1.length; i < len; i++) {
Acc1 = accounts1[i];
$('#account1').append("<option value=" + j + ">" + Acc1 + "</value>");
j += 1;
}
$('#account1').on('change', function() {
var Acc2, accounts2, index, k, len1, ref;
accounts2 = [
["科目を選択"],
["生鮮食品", "中食", "外食", "飲料", "お菓子", "加工品"],
["電気代", "ガス代", "水道代", "灯油代"],
["治療費", "処方箋薬", "市販薬"],
["パチンコ代", "旅行代", "お土産代", "漫画"],
["授業料", "給食費", "塾代", "教科書代", "書籍代"],
["冠婚葬祭費", "タクシー代", "家賃", "税金", "仕送り"]
];
index = $('#account1').val();
$('#account2').empty();
ref = accounts2[index];
for (k = 0, len1 = ref.length; k < len1; k++) {
Acc2 = ref[k];
$('#account2').append("<option>" + Acc2 + "</option>");
}
return this;
});
}).call(this);
処理の流れは以下のとおりです。
- 大科目のリストをaccount1変数に格納する
- HTMLファイルを開いた際に、account1変数の値を「ID:"account1"」のメニューにセット。このとき、小科目の絞り込みに使うためのインデックスもvalue属性にセットしておく。
- 小科目のリストをaccount2変数に格納する。大科目のインデックスを使って絞り込みを行うので、大科目の順番に沿った2次元配列にする。
- 大科目の値を選んだら、選んだ大科目のインデックスをindex変数に格納する。
- 小科目のメニューを空にする
- 大科目のインデックスの値を使って該当する小科目のリストをref変数に格納する。
- ref変数の要素の数だけforループを回して、「ID:"account2」のメニューに小科目を追加していく。
これで、以下のような連動するメニューができると思います。
メニューの項目を全てJavaScriptで処理しますので、メニューの項目を増減させる場合でも、HTMLファイルは編集する必要がありません。そのため、メニューの項目をHTMLファイルの<option>
タグに記載してJavaScriptで加工する方法よりも、後々のメンテナンスが楽になるんじゃないかと思います。
蛇足
上記のJavaScriptをCoffeeScriptで書いた場合のコードも掲載します。
index.coffee
accounts1 = [
"科目を選択",
"食費",
"光熱費",
"医療費",
"娯楽費",
"教育費",
"その他",
]
j = 0
for Acc1 in accounts1
$('#account1').append("<option value=#{j}>#{Acc1}</value>")
j += 1
$('#account1').on 'change', ->
accounts2 = [
["科目を選択"]
["生鮮食品","中食","外食","飲料","お菓子","加工品",]
["電気代","ガス代","水道代","灯油代",]
["治療費","処方箋薬","市販薬",]
["パチンコ代","旅行代","お土産代","漫画",]
["授業料","給食費","塾代","教科書代","書籍代",]
["冠婚葬祭費","タクシー代","家賃","税金","仕送り",]
]
index = $('#account1').val()
$('#account2').attr disabled: false
$('#account2').empty()
for Acc2 in accounts2[index]
$('#account2').append("<option>#{Acc2}</option>")
@