LoginSignup

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

jsでフィルタリング機能を作成しているのですがcheckボタンを押下するとすべて非表示になってしまいます。

解決したいこと

現在pythonのflaskを用いてHP作成をおこなっており、
DBから取得してきた情報を一覧表示するプログラムを作成していて、
追加機能としてjsでフィルタリング(絞り込み)機能を実装したいと考えております。
コードを組んでいるのですがうまく動作せず、作業が止まってしまっています。

発生している問題・エラー

checkboxを押下したら地方ごとに絞り込みを行いたいのですが、
checkboxを押下するとすべての項目が非表示になってしまいます。

.html
<div id="filter">
<h2>地域別情報</h2>
    <div class="select">
        <label for="tohoku_area">東北地方<input type="checkbox" name="area_filter" id="tohoku_area" class="filter" value="東北地方"></label>
        <label for="kanto_area">関東地方<input type="checkbox" name="area_filter" id="kanto_area" class="filter" value="関東地方"></label>
        <label for="hokuriku_chubu_area">北陸・中部地方<input type="checkbox" name="area_filter" id="hokuriku_chubu_area" class="filter" value="北陸・中部地方"></label>
        <label for="kinki_area">近畿地方<input type="checkbox" name="area_filter" id="kinki_area" class="filter" value="近畿地方"></label>
        <label for="chugoku_sikoku_area">中国・四国地方<input type="checkbox" name="area_filter" id="chugoku_sikoku_area" class="filter" value="中国・四国地方"></label>
        <label for="kyushu_area">九州地方<input type="checkbox" name="area_filter" id="kyushu_area" class="filter" value="九州地方"></label>
    </div>
    <div>
    {% if items.get("typeA_items") %}
        {% for typeA_item in premium_items.get("typeA_items") %}
            <div class="typeA">
                <div class="flex_icon">
                    <img src="{{ url_for('static', filename='images/typeA.png') }}"
                    alt="typeA">
                </div>
                <div class="flex_text">
                    <dl>
                        <dt class="ItemTitle">日時</dt>
                        <dd class="ItemDescription">{{typeA_item[3]}}</dd>
                    </dl>
                    <dl class="filter_target">
                        <dt class="ItemTitle">場所</dt>
                        // ※typeA_item[4]にチェックボックスと同じ値の地方名が格納されている個所です。
                        // ※typeA_item[5]に県名が格納されています。
                        <dd class="ItemDescription" filter="{{typeA_item[4]}}">{{typeA_item[5]}}</dd>
                    </dl>
                    <dl>
                        <dt class="ItemTitle">住所</dt>
                        <dd class="ItemDescription">{{typeA_item[6]}}</dd>
                    </dl>
                </div>
                <div class="flex_link">
                    <li><a href="{{typeA_item[7]}}">情報詳細</a></li>
                </div>
            </div>
        {% endfor %}
    {% else %}
        <div class="typeA_nothing">
            <p>開催が見つかりませんでした</p>
        </div>
    {% endif %}
    </div>
</div>

.js
document.addEventListener('DOMContentLoaded', function () {
    var filterContainer = document.getElementById('filter');
    var checkboxes = filterContainer.querySelectorAll('.select input[type="checkbox"]');
    var premiumItems = filterContainer.querySelectorAll('.typeA');

    var applyFilter = function () {
        var checkedValues = Array.from(checkboxes)
            .filter(function (checkbox) { return checkbox.checked; })
            .map(function (checkbox) { return checkbox.value; });

        premiumItems.forEach(function (item) {
            var itemRegion = item.querySelector('.ItemDescription').getAttribute('filter');
            if (checkedValues.includes(itemRegion)) {
                item.style.display = ''; // 選択された地域に対応する要素を表示
            } else {
                item.style.display = 'none'; // それ以外の要素を非表示
            }
        });

        // 何もチェックされていない場合は全ての要素を表示する
        if (checkedValues.length === 0) {
            premiumItems.forEach(function (item) {
                item.style.display = '';
            });
        }
    };

    checkboxes.forEach(function (checkbox) {
        checkbox.addEventListener('change', applyFilter);
    });
});

最後まで読んでいただきありがとうございます
何かわかる方いらっしゃいましたら教えていただけると幸いです。
何卒よろしくお願いします。

0

2Answer

JavaScriptのコードをコピペして動かして見たのですが、正しく動いているようでした。
まずは、表示後のHTMLのfilter属性に正しく地方名が入っているか、開発者ツールで確認してみてください。

また、JavaScriptの動きについて質問する場合は、表示後のHTMLのソースを貼り付けたほうが原因突き止めやすいと思うので、表示後のHTMLも張っていただけるとありがたいです。

See the Pen qiita https://qiita.com/Kobayashi0620/questions/01aaa97594ba788cec33 by yotty (@yotty) on CodePen.

1

Comments

  1. 試せてないですが、以下の変更でうまくいくかもしれないです。

    - <dd class="ItemDescription" filter="{{typeA_item[4]}}">{{typeA_item[5]}}</dd>
    + <dd class="ItemDescription" filter={{typeA_item[4]}}>{{typeA_item[5]}}</dd>
    
  2. @Kobayashi0620

    Questioner

    ご回答ありがとうございます!
    codepenの方で試したら動作したのですが、要素を足すと動かなくなってしまうみたいでそちらの原因が深まってしまいました。
    下記内容にするとすべて非表示になってしまいます

    .html
    <div class="typeA">
      <div class="flex_text">
        <dl>
          <dt class="ItemTitle">日付け</dt>
          <dd class="ItemDescription">2024/04/23</dd>
        </dl>
        <dl class="filter_target">
          <dt class="ItemTitle">場所</dt>
          <dd class="ItemDescription" filter="関東地方">関東地方1</dd>
        </dl>
        <dl>
          <dt class="ItemTitle">会場</dt>
          <dd class="ItemDescription">関東地方1</dd>
        </dl>
      </div>
      <div class="flex_link">
        <li><a href="#申込リンク">申し込む</a></li>
        <li><a href="あ">会場詳細</a></li>
      </div>
    </div>
    
    <div class="typeA">
      <div class="flex_text">
        <dl>
          <dt class="ItemTitle">日付け</dt>
          <dd class="ItemDescription">2024/04/23</dd>
        </dl>
        <dl class="filter_target">
          <dt class="ItemTitle">場所</dt>
          <dd class="ItemDescription" filter="東北地方">東北地方1</dd>
        </dl>
        <dl>
          <dt class="ItemTitle">会場</dt>
          <dd class="ItemDescription">東北地方1</dd>
        </dl>
      </div>
      <div class="flex_link">
        <li><a href="#申込リンク">申し込む</a></li>
        <li><a href="あ">会場詳細</a></li>
      </div>
    </div>
    
    <div class="typeA">
      <div class="flex_text">
        <dl>
          <dt class="ItemTitle">日付け</dt>
          <dd class="ItemDescription">2024/04/23</dd>
        </dl>
        <dl class="filter_target">
          <dt class="ItemTitle">場所</dt>
          <dd class="ItemDescription" filter="関東地方">関東地方2</dd>
        </dl>
        <dl>
          <dt class="ItemTitle">会場</dt>
          <dd class="ItemDescription">関東地方2</dd>
        </dl>
      </div>
      <div class="flex_link">
        <li><a href="#申込リンク">申し込む</a></li>
        <li><a href="あ">会場詳細</a></li>
      </div>
    </div>
    
    <div class="typeA">
      <div class="flex_text">
        <dl>
          <dt class="ItemTitle">日付け</dt>
          <dd class="ItemDescription">2024/04/23</dd>
        </dl>
        <dl class="filter_target">
          <dt class="ItemTitle">場所</dt>
          <dd class="ItemDescription" filter="東北地方">東北地方2</dd>
        </dl>
        <dl>
          <dt class="ItemTitle">会場</dt>
          <dd class="ItemDescription">東北地方2</dd>
        </dl>
      </div>
      <div class="flex_link">
        <li><a href="#申込リンク">申し込む</a></li>
        <li><a href="あ">会場詳細</a></li>
      </div>
    </div>
    
    <div class="typeA">
      <div class="flex_text">
        <dl>
          <dt class="ItemTitle">日付け</dt>
          <dd class="ItemDescription">2024/04/23</dd>
        </dl>
        <dl class="filter_target">
          <dt class="ItemTitle">場所</dt>
          <dd class="ItemDescription" filter="九州地方">九州地方1</dd>
        </dl>
        <dl>
          <dt class="ItemTitle">会場</dt>
          <dd class="ItemDescription">九州地方1</dd>
        </dl>
      </div>
      <div class="flex_link">
        <li><a href="#申込リンク">申し込む</a></li>
        <li><a href="あ">会場詳細</a></li>
      </div>
    </div>
    
  3. @Kobayashi0620

    Questioner

    下記jsで実装完了しました。

    .js
    document.addEventListener('DOMContentLoaded', function () {
        var checkboxes = document.querySelectorAll('.select .filter');
        var filterableItems = document.querySelectorAll('.typeA');
    
        var filterItems = function () {
            var checkedFilters = Array.from(checkboxes)
                .filter(checkbox => checkbox.checked)
                .map(checkbox => checkbox.value);
    
            filterableItems.forEach(function (item) {
                var itemRegion = item.querySelector('.filter_target .ItemDescription').getAttribute('filter');
                if (checkedFilters.length === 0 || checkedFilters.includes(itemRegion)) {
                    item.style.display = ''; // 選択された地域に対応する要素を表示
                } else {
                    item.style.display = 'none'; // それ以外の要素を非表示
                }
            });
        };
    
        checkboxes.forEach(function (checkbox) {
            checkbox.addEventListener('change', filterItems);
        });
    });
    

Comments

  1. @Kobayashi0620

    Questioner

    内容はまた別のものになります。
    回答していただけない、指摘内容もプログラムと関係ないのであればこちらとしても迷惑なので返信いただかなくて結構です。

Your answer might help someone💌