Search code examples
javascriptjqueryfilterjquery-ui-multiselect

Jquery Filter <li> on Multiselect


I tried to create a filter, which displays li-elements, based on the selected options. It works, when I select just one option, the elements show up when selected and disappear when deselected.

But when multiple option are selected, the elements first appear and then disappear again. I guess something in the loop is wrong?

Javascript:

$(document).ready(function() {

  //Hide all li-Elements
  $(".result li").hide();

  //When select-Element is change, do something
  $("select").change(function() {

    //Create array for selected Options 
    var arr = new Array;

    //Add all selected Options to the array
    $("select option:selected").each(function() {
      arr.push($(this).val());
    });
    //Create a Loop to display li-Elements
    for (var i = 0, l = arr.length; i < l; i++) {

      /*slideDown all elements which contain one
          of the selected elements in array*/
      $("li:contains(" + arr[i] + ")").slideDown("slow");
      /*slideUp all elements which do not contain
          the selected elements in array*/
      $('li:not(:contains(' + arr[i] + '))').slideUp("slow");
    }
  });

});

Html:

<select multiple>
  <option value="volvo">volvo</option>
  <option value="saab">saab</option>
  <option value="opel">opel</option>
  <option value="audi">audi</option>
</select>

<div class="result">
  <ul>
    <li>volvo</li>
    <li>volvo coolio</li>
    <li>saab</li>
    <li>opel</li>
    <li>opelino</li>
    <li>opel meier</li>
    <li>audi</li>
  </ul>
</div>

Preview: https://jsfiddle.net/onclesam/2z56oom2/3/


Solution

  • The problem is in each iteration you are resetting the filter, instead you can do

    $(document).ready(function() {
    
      //Hide all li-Elements
      var $lis = $(".result li").hide();
    
      //When select-Element is change, do something
      $("select").change(function() {
    
        //Add all selected Options to the array
        var selectors = $("select option:selected").map(function(i, value) {
          return ':contains("' + this.value + '")'
        }).get();
        var $selected = $lis.stop().filter(selectors.join()).slideDown();
        $lis.not($selected).slideUp();
      });
    
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <select multiple>
      <option value="volvo">volvo</option>
      <option value="saab">saab</option>
      <option value="opel">opel</option>
      <option value="audi">audi</option>
    </select>
    
    <div class="result">
      <ul>
        <li>volvo</li>
        <li>volvo coolio</li>
        <li>saab</li>
        <li>opel</li>
        <li>opelino</li>
        <li>opel meier</li>
        <li>audi</li>
      </ul>
    </div>