TECH MEDIA

テックメディア


ノウハウ
ブログ

jQuery:他の要素の値を元にselect要素のoptionを非表示にする

JavaScript

温泉は硫酸塩泉と硫黄泉が好き。エンジニアのしらいしです。

jQueryを使って最近書いたコードをスニペットとして残したいと思います。
(かなり簡略化してあります)

他の要素の入力を元に、select要素の選択肢を削除するコードです。
idとvalueを書き換えればscriptタグに追加するだけで動きます。

今回は2つのselectのうち、1つ目の選択肢によって2つめのselectの選択肢を非表示にします。
ベースのselect要素は下記です。



<select id="parent">
  <option value="apple">りんご</option>
  <option value="watermelon">すいか</option>
  <option value="orange">オレンジ</option>
  <option value="plum">梅</option>
</select>
<select id="child">
  <option value="jelly">ゼリー</option>
  <option value="jam">ジャム</option>
  <option value="tea">茶</option>
</select>

さすがにスイカフレーバーのお茶はないのでは…?ということで、「すいか」を選択したときだけ「茶」を選択肢から消します。
(すいかの種のお茶はあるみたいですね)

ここに下記スクリプトを追加します。



<script type="text/javascript">
  const parentSelect = "parent";
  const childSelect = "child";
  $(function () {
    selectItem();
    $("#" + parentSelect).change(function () {
      selectItem();
    });
  });

  function selectItem() {
    // select要素の中の全てのspan要素を削除
    var spans = $("#" + childSelect + " span");
    for (var i = 0; i < spans.length; i++) {
      spans.eq(i).children().unwrap();
    }

    // 対象のoptionをspan要素で囲む
    var options = $("#" + childSelect + " option");
    for (var i = 0; i < options.length; i++) {
      if (($("#" + parentSelect).val() == "watermelon") && (options.eq(i).val() === "tea")) {
        options.eq(i).wrap("<span>");
      }
      options.eq(i).prop("selected", false);
    }
    options.eq(0).prop("selected", true);
  }
</script>

これで「すいか」を選ぶと「茶」が選択肢に表示されなくなりました!

選択肢を非表示にするところは


options.eq(i).wrap('');

と記述してあります。

display: none;

をstyleに記述してもGoogle Chromeは非表示にできるのですが、Safariでは思った通りに動かなかったためspan要素で囲みました。
(span要素を非表示にしなくても囲むだけで選択肢としては非表示になります)

下記の記述では、id=”child”のselect要素の中でoptionを囲っているspan要素を削除しています。



var spans = $("#" + childSelect + " span");
for (var i = 0; i < spans.length; i++) {
  spans.eq(i).children().unwrap();
}

追加として、表示させる項目を連想配列に持たせてみました。



<script type="text/javascript">
  const parentSelect = "parent";
  const childSelect = "child";
  const settings = {
    apple: { jelly:"on", jam:"on", tea:"on" },
    watermelon: { jelly:"on", jam:"on", tea:"off" },
    orange: { jelly:"on", jam:"on", tea:"on" },
    plum: { jelly:"on", jam:"on", tea:"on" },
  };

  $(function () {
    selectItem();
    $("#" + parentSelect).change(function () {
      selectItem();
    });
  });

  function selectItem() {
    // select要素の中の全てのspan要素を削除
    var spans = $("#" + childSelect + " span");
    for (var i = 0; i < spans.length; i++) {
      spans.eq(i).children().unwrap();
    }

    // 対象のoptionをspan要素で囲む
    var options = $("#" + childSelect + " option");
    for (var i = 0; i < options.length; i++) {
      if (settings[$("#" + parentSelect).val()][options.eq(i).val()] === "off") {
        options.eq(i).wrap('<span>');
      }
      options.eq(i).prop("selected", false);
    }
    options.eq(0).prop("selected", true);
  }
</script>

settingsのon / off を変更することで表示を切り替えることができるようになりました。

ネット検索でも似たような情報は沢山ありますが自分がピンポイントで欲しい情報はなかなか見つけにくかったので、これからも備忘としてスニペットを残していきたいと思いました。

RECRUIT 採用情報

「eビジネスに関わる全ての人を幸せにする」
私達とともに新たな時代をつくりませんか?