User_3535
User_3535

Reputation: 862

Multiple filter using jQuery

Select 1

`<select class="form-control" id="technology">
 <option name="sort" value="2g" id="2g">2G</option>
 <option name="sort" value="3g" id="3g">3G</option></select>`

Select 2

 <select class="form-control" id="use">
     <option name="sort2" value="vehicle" id="vehicle"> Vehicle </option>
     <option name="sort2" value="asset" id="asset"> Asset </option>
     <option name="sort2" value="personal" id="personal"> Personal</option>
 </select>

checkbox filter

 <input type="checkbox" value="standard">
 <input type="checkbox" value="one way">
 <input type="checkbox" value="two way">

My HTML

<div class="flower 2g vehicle standard">
  2g vehicle
</div>
<div class="flower 3g vehicle one way">
  3g vehicle one way
</div>
<div class="flower 3g vehicle two way">
  3g vehicle two way
</div>

these are the three filter need to filter them based on class ., i did for checkbox but how to do in combination of three ( two select and checkbox )?

my code for checkbox filter

jQuery($ => {
  let $seasons = $('.flower');
  let $checkboxes = $('input[type="checkbox"]').on('change', function () {
    $seasons.show();
    let selector = $checkboxes.filter(':checked').map((i, el) => '.' + el.value).get().join(''); console.log(selector)
    if (selector.length != 0)
      $('.flower:visible').filter(`:not("${selector}")`).hide();
  });

Upvotes: 1

Views: 750

Answers (3)

shyam
shyam

Reputation: 9368

Since you want to apply multiple filters to the same list of items. It is better that you separate the values using data attributes

HTML

<div class="flower" data-use="vehicle" data-tech="2g" data-type="standard">
  2g vehicle
</div>
<div class="flower" data-use="vehicle" data-tech="3g" data-type="one way">
  3g vehicle one way
</div>
<div class="flower" data-use="vehicle" data-tech="3g" data-type="one way">
  3g vehicle two way
</div>

The filters can remain the same

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Select 1

<select class="form-control" id="technology">
  <option name="sort" value=""></option>
  <option name="sort" value="2g" id="2g">2G</option>
  <option name="sort" value="3g" id="3g">3G</option>
</select>

Select 2

<select class="form-control" id="use">
  <option name="sort2" value=""></option>
  <option name="sort2" value="vehicle" id="vehicle"> Vehicle </option>
  <option name="sort2" value="asset" id="asset"> Asset </option>
  <option name="sort2" value="personal" id="personal"> Personal</option>
</select>

Checkbox Filter

<label><input type="checkbox" value="standard">Standard</label>
<label><input type="checkbox" value="one way">One Way</label>
<label><input type="checkbox" value="two way">Two Way</label>

Add a multiFilter function to filter by multiple values and attach it to all the filters

function filterBy(key, val) {
  return (i, el) =>  Array.isArray(val) 
      ?  val.length == 0 || val.indexOf($(el).data(key)) > -1
      :  val == '' || $(el).data(key) == val
}
function multiFilter() {
   let tech = $('#technology').val()
   let use = $('#use').val()
   let type = $('input[type="checkbox"]').filter(':checked').map((i,el) => el.value).toArray()
   let $seasons = $('.flower')
   $seasons.hide()
   $seasons
     .filter(filterBy('tech', tech))
     .filter(filterBy('use', use))
     .filter(filterBy('type', type))
     .show()
}
jQuery($ => {
  $('#technology,#use,input[type="checkbox"]').on('change', multiFilter)
})

Upvotes: 0

D. Seah
D. Seah

Reputation: 4592

maybe you can try this

let $seasons = $('.flower');
$seasons.hide();

const showDiv = (cb) => {
  const val = $(cb).val();
  const checked = $(cb).is(':checked');
  const technology = $("#technology option:selected").val();
  const use = $("#use option:selected").val();
  $seasons.each((_, season) => {
    const $season = $(season);
    const clazz = $season.attr("class");
    if (clazz.indexOf(val) !== -1) {
      if (checked && ![technology, use].some(opt => clazz.indexOf(opt) === -1)) {
        $season.show();
      } else {
        $season.hide();
      }
    }
  });
}

const invalidate = () => {
  $('input[type="checkbox"]').each((_, cb) => {
    showDiv(cb);
  });
};

$('input[type="checkbox"]').on('change', function() {
  showDiv(this);
});
$('#technology').on('change', function() {
  invalidate();
});
$('#use').on('change', function() {
  invalidate();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="form-control" id="technology">
  <option name="sort" value="2g" id="2g" selected>2G</option>
  <option name="sort" value="3g" id="3g">3G</option>
</select>

<select class="form-control" id="use">
  <option name="sort2" value="vehicle" id="vehicle" selected> Vehicle </option>
  <option name="sort2" value="asset" id="asset"> Asset </option>
  <option name="sort2" value="personal" id="personal"> Personal</option>
</select>

<input type="checkbox" value="standard" selected>Standard
<input type="checkbox" value="one way">One Way
<input type="checkbox" value="two way">Two Ways

<div class="flower 2g vehicle standard">
  2g vehicle
</div>
<div class="flower 3g vehicle one way">
  3g vehicle one way
</div>
<div class="flower 3g vehicle two way">
  3g vehicle two way
</div>

Upvotes: 0

Swati
Swati

Reputation: 28522

You can have only one event handler for both select & checkbox so when any one gets change you can get there value and then show/hide your divs.

Demo Code :

$('select , input[type="checkbox"]').on('change', function() {
  $(".flower").hide(); //hide divs
  //get both select value
  var value1 = $("#use").val()
  var value2 = $("#technology").val()
  var to_find = "." + value1 + "." + value2
  $(`.flower${to_find}`).show() //show that div
  let selector = $('input[type="checkbox"]').filter(':checked').map((i, el) => '.' + el.value).get();
  if (selector.length != 0)
    //loop through selected checkbox
    for (var i = 0; i < selector.length; i++) {
      $('.flower:visible').filter(`:not("${selector[i]}")`).hide();
    }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="form-control" id="technology">
  <option name="sort" value="2g" id="2g">2G</option>
  <option name="sort" value="3g" id="3g">3G</option>
</select>

<select class="form-control" id="use">
  <option name="sort2" value="vehicle" id="vehicle"> Vehicle </option>
  <option name="sort2" value="asset" id="asset"> Asset </option>
  <option name="sort2" value="personal" id="personal"> Personal</option>
</select>


<input type="checkbox" value="standard">standard
<input type="checkbox" value="oneway">oneway
<input type="checkbox" value="twoway">twoway

<div class="flower 2g vehicle standard">
  2g vehicle standard
</div>
<div class="flower 3g asset oneway">
  3g asset one way
</div>
<div class="flower 3g vehicle twoway">
  3g vehicle two way
</div>
<div class="flower 2g vehicle oneway">
  2g vehicle oneway
</div>
<div class="flower 3g asset standard">
  3g asset standard
</div>
<div class="flower 3g vehicle twoway">
  3g vehicle two way
</div>

Upvotes: 1

Related Questions