Показать элементы, соответствующие нескольким выбранным атрибутам данных

Я создаю набор фильтров, и после их выбора соответствующие элементы div должны отображаться на основе ВСЕХ выбранных атрибутов.

Я могу заставить это работать по одному, но моя проблема заключается в том, чтобы заставить их работать вместе. Я чувствую, что, вероятно, есть лучший подход к этому в целом?

Вот мои избранные меню:

<div class = "filters">
 <select class = "filter-location">
   <option value = "" disabled = "" selected = "">Location</option>
   <option data-location = "Remote">Remote – United States</option>
   <option data-location = "Portland, OR">Portland, OR</option>
   <option data-location = "Seattle, WA">Seattle, WA</option>
 </select>
 <select class = "filter-team">
   <option value = "" disabled = "" selected = "">Team</option>
   <option data-team = "Sales">Sales</option>
   <option data-team = "Support">Support</option>
   <option data-team = "Management">Management</option>
 </select>
 <select class = "filter-type">
   <option value = "" disabled = "" selected = "">Type</option>
   <option data-type = "Full-Time">Full-Time</option>
   <option data-type = "Contract">Contract</option>
 </select>
</div>

Вот упрощенная версия моей HTML-разметки:

<div class = "job" data-team = "Sales" data-location = "Remote" data-type = "Full-Time">
  <p>Job Content Here</p>
</div>
<div class = "job" data-team = "Management" data-location = "Portland, OR" data-type = "Contract">
  <p>Job Content Here</p>
</div>
<div class = "job" data-team = "Sales" data-location = "Seattle, WA" data-type = "Full-Time">
  <p>Job Content Here</p>
</div>

Вот мой jQuery, который работает для отображения одного фильтра за раз:

<script type = "text/javascript">
  jQuery(document).ready(function($) {
    $('.filters select').on('change', function() {

      var location_value = $(':selected', this).data('location');
      var team_value = $(':selected', this).data('team');
      var type_value = $(':selected', this).data('type');

      $('.job').hide();

      $(".job").each(function( index ) {
        if ($(this).data('location') == location_value) {
          $(this).show();
        }
        if ($(this).data('team') == team_value) {
          $(this).show();
        }
        if ($(this).data('work_type') == type_value) {
          $(this).show();
        }
      });

    });
  }); 
</script>

Ваша главная проблема в том, что вам нужна && логика, чтобы убедиться, что каждое условие соответствует

charlietfl 11.12.2020 03:10
Как конвертировать HTML в PDF с помощью jsPDF
Как конвертировать HTML в PDF с помощью jsPDF
В этой статье мы рассмотрим, как конвертировать HTML в PDF с помощью jsPDF. Здесь мы узнаем, как конвертировать HTML в PDF с помощью javascript.
0
1
183
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Далее создается массив объектов фильтра для каждого <select> со значением, которое выглядит следующим образом:

[
  {
    "filter": "location",
    "value": "Remote"
  },
  {
    "filter": "team",
    "value": "Sales"
  }
]

Затем он использует Array#every(), чтобы убедиться, что каждый фильтр соответствует data- атрибутам задания, чтобы определить, показывать его или нет.

Обратите внимание, что я сделал элементы <select> немного более общими, добавил атрибут data-filter к каждому из них и просто использовал value для элементов <option>.

const $sels = $('.filters select'),
      $jobs = $('.job')

$sels.change(function(){
    const filters = $sels.filter(function(){
        return !!this.value
    }).map(function(){
       return {filter: $(this).data('filter'), value : this.value} 
    }).get();
    //console.info('Filters', filters)    
    
    // hide all jobs then filter the ones to show
    const $filterJobs = $jobs.hide().filter(function(){
        const data = $(this).data()
        return filters.every(function(obj){
           return data[obj.filter] === obj.value 
        });
    }).show(); 

    // toggle "no-match" depending on length of filter jobs collection
    $('#no-match').toggle( !$filterJobs.length )

});
.job, #no-match {
  display: none
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class = "filters">
  <select data-filter = "location">
    <option value = "">Location</option>
    <option value = "Remote">Remote – United States</option>
    <option value = "Portland, OR">Portland, OR</option>
    <option value = "Seattle, WA">Seattle, WA</option>
  </select>
  <select data-filter = "team">
    <option value = "">Team</option>
    <option value = "Sales">Sales</option>
    <option value = "Support">Support</option>
    <option value = "Management">Management</option>
  </select>
  <select data-filter = "type">
    <option value = "">Type</option>
    <option value = "Full-Time">Full-Time</option>
    <option value = "Contract">Contract</option>
  </select>
</div>
<div id = "no-match">
   <h3>No Match</h3>
</div>

<div class = "job" data-team = "Sales" data-location = "Remote" data-type = "Full-Time">
  <p>Sales Remote Full Time</p>
</div>
<div class = "job" data-team = "Management" data-location = "Portland, OR" data-type = "Contract">
  <p>Management Portland Contract</p>
</div>
<div class = "job" data-team = "Sales" data-location = "Seattle, WA" data-type = "Full-Time">
  <p>Sales Seattle Full Time</p>
</div>

Спасибо! Я знал, что чего-то не хватает. Это работает отлично.

Michelle 11.12.2020 04:09

Другие вопросы по теме