js チェックボックス 2段階 フィルター

html

<div id="select" class="bl_selectBlock">

    <div class="el_searchResult">
        <span class="el_searchResult_nume js_numerator"></span>件/全<span class="el_searchResult_deno js_denominator"></span>件
    </div>

    <div class="bl_selectBlock_wrapper">

        <div class="bl_selectBlock_wrapper_wrapper">
        <div class="bl_selectBlock_ttl">地域</div>
        <div class="bl_selectBlock_content js_conditions" data-type="type">
            <span class="bl_selectBlock_check">
            <label><input type="checkbox" name="type" value="tokyo">東京
            </label>
            </span>
            <span class="bl_selectBlock_check">
            <label><input type="checkbox" name="type" value="kyoto">京都
            </label>
            </span>
            <span class="bl_selectBlock_check">
            <label><input type="checkbox" name="type" value="no_area">地域不問
            </label>
            </span>
        </div>
        </div>
        <div class="bl_selectBlock_wrapper_wrapper">
        <div class="bl_selectBlock_ttl">職種</div>
        <div class="bl_selectBlock_content js_conditions" data-type="job">
            <span class="bl_selectBlock_check">
            <label><input type="checkbox" name="job" value="プロダクト企画部門">プロダクト企画部門</label>
            </span>
            <span class="bl_selectBlock_check">
            <label><input type="checkbox" name="job" value="開発部門">開発部門</label>
            </span>
            <span class="bl_selectBlock_check">
            <label><input type="checkbox" name="job" value="品質管理部門">品質管理部門</label>
            </span>
            <span class="bl_selectBlock_check">
            <label><input type="checkbox" name="job" value="経営管理部門">経営管理部門</label>
            </span>
            <span class="bl_selectBlock_check">
            <label><input type="checkbox" name="job" value="営業部門">営業部門</label>
            </span>
            <span class="bl_selectBlock_check">
            <label><input type="checkbox" name="job" value="マーケティング部門">マーケティング部門</label>
            </span>
            <span class="bl_selectBlock_check">
            <label><input type="checkbox" name="job" value="人事・採用部門">人事・採用部門</label>
            </span>
        </div>
        </div>

    </div>
    </div>

    <div class="bl_searchResultBlock">
    <div class="bl_searchResultBlock_item js_target" data-type="tokyo" data-job="プロダクト企画部門">東京/プロダクト企画部門</div>
    <div class="bl_searchResultBlock_item js_target" data-type="kyoto" data-job="開発部門">京都/開発部門</div>
    <div class="bl_searchResultBlock_item js_target" data-type="no_area" data-job="品質管理部門">地域不問/品質管理部門</div>
    <div class="bl_searchResultBlock_item js_target" data-type="tokyo" data-job="経営管理部門">東京/経営管理部門</div>
    <div class="bl_searchResultBlock_item js_target" data-type="kyoto" data-job="営業部門">京都/営業部門</div>
    <div class="bl_searchResultBlock_item js_target" data-type="no_area" data-job="マーケティング部門">地域不問/マーケティング部門</div>
    <div class="bl_searchResultBlock_item js_target" data-type="tokyo,kyoto" data-job="人事・採用部門">東京&京都/人事・採用部門</div>
    </div>

    <div class="error"></div>
</div>

js

<script>
$(function(){
  var box = $('.js_target');//検索対象のDOMを格納する
  var conditions = $('.js_conditions');//現在の条件の選択状況を保持するオブジェクト
  var findConditions;//各data-typeの子要素(input)を格納する
  var currentType;//現在のdata-typeを示す
  var count = 0;//検索ヒット数
  var checkcount = 0;//各data-typeのチェックボックス選択数
  var data_check = 0;//対象項目のデータがどれだけチェック状態と一致しているか
  var error = $('.error');
  
  var condition ={};//チェックボックスの入力状態を保持するオブジェクト
  
  $('.js_denominator').text(box.length);//件数表示の分母をセット
  
  for(var i = 0; i < conditions.length; i++){//ターゲットのdata-typeを参照し、メソッドとしてconditionに個別に代入する
    currentType = conditions[i].getAttribute('data-type');
    condition[currentType] = [];
  }
  
  function setConditions(){//条件設定
  
    count = 0;
    box.removeClass('js_selected');
  
    for(var i = 0; i < conditions.length; i++){//data-typeごとの処理
  
      currentType = conditions[i].getAttribute('data-type');
  
      findConditions = conditions[i].querySelectorAll('input');
  
      for(var n = 0; n< findConditions.length; n++){//inputごとの処理
  
        if(findConditions[n].checked){//現在選択中のインプットが選択されている場合
          condition[currentType][findConditions[n].value] = true;
          checkcount++
        } else {
          condition[currentType][findConditions[n].value] = false;
        }
        if(findConditions.length === n+1){//ループが最後の場合
          if(checkcount === 0){
            for(var t = 0; t < findConditions.length; t++){
              condition[currentType][findConditions[t].value] = true;
            }
          }
          checkcount = 0;
        }
      }
    }
  
  
    for(var m = 0, len = box.length; m< len; ++m){//最初に取得したターゲットの情報と、現在のinputの選択状態を比較して処理を行う
  
      for(var i = 0; i < conditions.length; i++){//ターゲットのdata-typeを参照し、メソッドとしてconditionに個別に代入する
        currentType = conditions[i].getAttribute('data-type');
        //現在のターゲットのtype情報をカンマ区切りで分割し、配列に代入
        var currentBoxTypes = $(box[m]).data(currentType).split(',');
 
        for(var j = 0; j < currentBoxTypes.length; j++){
          if(condition[currentType][currentBoxTypes[j]]){
            data_check++;//選択した条件のうちひとつでもマッチしてたらdata_checkを加算してループを抜ける
            break;
          } else {
          }
        }
 
      }
  
        if(data_check === conditions.length){
          count++;
          $(box[m]).addClass('js_selected');
        }else{
  
        }
        data_check = 0;
  
    }
  
    // エラー表示
    if(count == 0){
        error.text('無し');
    }else{
        error.text('');
    }
  
    $('.js_numerator').text(count);//件数表示の分子をセット
  }
  
  setConditions();
  
  $(document).on('click','input',function(){
  
    setConditions();
  
  });
  

  
});

</script>

css

<style>
.el_searchResult{
text-align: center;
color: #0073aa;
}
.js_target{
display: none;
}
.js_target.js_selected{
display: block;
}
.bl_selectBlock label{
display: inline;
}
.el_searchResult{
margin-bottom: 20px;
}
.bl_selectBlock{
border: 1px solid #0073aa;
padding: 30px;
box-sizing: border-box;
margin-bottom: 30px;
font-size: 14px;
letter-spacing: 0.1em;
}
.bl_selectBlock_wrapper_wrapper{
display: -webkit-flex;
display: -moz-flex;
display: -ms-flex;
display: -o-flex;
display: flex;
flex-wrap: wrap;
align-items: center;
margin-bottom: 30px;
}
.bl_selectBlock_check label{
cursor: pointer;
}
.bl_selectBlock_ttl{
width: 185px;
color: #0073aa;
letter-spacing: 0.1em;
margin-bottom: 20px;
}
@media screen and (max-width: 765px){
.bl_selectBlock_ttl{
width: 100%;
margin-bottom: 20px;
}
}
.bl_selectBlock_content{
width: calc(100% - 185px);
}
@media screen and (max-width: 765px){
.bl_selectBlock_content{
width: 100%;
}
}
.bl_searchResultBlock{
font-size: 14px;
border-top: 1px solid #bdbdbd;
}
.bl_searchResultBlock_item{
padding: 20px 0;
box-sizing: border-box;
border-bottom: 1px solid #bdbdbd;
}
.bl_selectBlock_check{
display: inline-block;
margin-right: 25px;
display: inline-block;
margin-bottom: 20px;
}
.bl_selectBlock_check:last-child{
margin-right: 0;
}
.bl_selectBlock_release{
text-align: center;
color: #fff;
background-color: #bdbdbd;
padding: 15px 0;
}
.js_release{
cursor: pointer;
}

</style>

参考にした記事はこちら

javascriptのみで複数カテゴリの絞り込み検索を実現するコード | Qoocode