LoginSignup
4

More than 5 years have passed since last update.

連動するメニューをJavaScriptで作る方法

Posted at

以下のような大科目の下に小科目があるようなデータがある場合に、大科目を選ぶとそれに対応する小科目が表示されるメニューを作成してみました。ウェブ上では、あらかじめ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);

処理の流れは以下のとおりです。

  1. 大科目のリストをaccount1変数に格納する
  2. HTMLファイルを開いた際に、account1変数の値を「ID:"account1"」のメニューにセット。このとき、小科目の絞り込みに使うためのインデックスもvalue属性にセットしておく。
  3. 小科目のリストをaccount2変数に格納する。大科目のインデックスを使って絞り込みを行うので、大科目の順番に沿った2次元配列にする。
  4. 大科目の値を選んだら、選んだ大科目のインデックスをindex変数に格納する。
  5. 小科目のメニューを空にする
  6. 大科目のインデックスの値を使って該当する小科目のリストをref変数に格納する。
  7. ref変数の要素の数だけforループを回して、「ID:"account2」のメニューに小科目を追加していく。

これで、以下のような連動するメニューができると思います。

displayAnimation.gif

メニューの項目を全て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>")
  @

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4