1

I have a table with some values and a filter option where the user can select multiple values and filter the table. What I am trying to achieve is to have a filter with numbers from 1 to 10, and table tr with class names filter_1, filter_2, filter_3 etc. when I choose number 1 from filter and click on it, it will show only tr with class filter_1. My code is below.

HTML:

<select multiple id="filterNumber">
<option value="1">1</option><option value="1">2</option><option value="1">3</option>
</select>
<button class="filterBtn">Filter</button>

Table:

<table>
<thead><tr><th>Name</th></tr></thead>
<tbody>
<tr class="filter_1"><td>A</td></tr>
<tr class="filter_5"><td>B</td></tr>
<tr class="filter_1"><td>C</td></tr>
</thead>
</table>

jQuery:

$(document).on('click','.filterBtn',function(){
let filterNumber = $('#filterNumber).val();

//loop through this numbers and hide tr without this class name 
});

I know how to pass these values through AJAX into DB and display the result, but I am trying to learn more like doing from the front-end only that makes my app more faster. But I don't know how to filter this using JavaScript or jQuery.

Kate Orlova
  • 3,225
  • 5
  • 11
  • 35
Jasir
  • 57
  • 6

4 Answers4

0

Add hideable or similar so you don't select the wrong thing.

<table>
<thead><tr><th>Name</th></tr></thead>
<tbody>
<tr class="filter_1 hideable"><td>A</td></tr>
<tr class="filter_5 hideable"><td>B</td></tr>
<tr class="filter_1 hideable"><td>C</td></tr>
</thead>
</table>

Hide them all, then show the visible one(s):

$(document).on('click','.filterBtn',function(){
  const filterNumbers = $('#filterNumber').val().toArray().map(item => item.value);

   $('.hideable').addClass( "hidden" ); 

  filterNumbers.forEach(num => 
    $(`.filter_${number}`).each(function() {
      $(this).removeClass("hidden"); 
    })
  )
}

You need to add a class to your CSS with display:none for .hidden

Multi-select values: https://stackoverflow.com/a/55929605/1758461

jQuery each(): https://api.jquery.com/each/#each-function

Josh Wulf
  • 4,727
  • 2
  • 20
  • 34
0

On the click of your button, you take the desired value, as you did. After that, you can use jQuery to add hide class to each tr that does not have the filtered class, with tr:not(.className), as shown in the example below:

$(document).on('click', '.filterBtn', function(){
 let filterNumber = $('#filterNumber').val();
 let className = 'filter_' + filterNumber;
 $('table tbody tr:not(.'+className+')').addClass('hide');
});

Note that if you filter more than once, you will also need to include a way to remove the hide class if you've previously filtered something else. So you would just add

$('table tr.'+className+'').removeClass('hide');

to remove hide class if the filter element has been previously filtered out.

Edit:

Since this is a multiple select, I would first apply hide class to each element, then loop through selected values and remove hide from the ones whose class matches the selected number.

$(document).on('click', '.filterBtn', function(){
   $('table tbody').find('tr').addClass('hide');
   let filterNumbersArray = $('#filterNumber').val();
   for(i=0; i<filterNumbersArray.length; i++){
      let className = 'filter_' + filterNumbersArray[i];
      $('table tbody tr.'+className+'').removeClass('hide');
   }
});
Mahatmasamatman
  • 1,537
  • 2
  • 6
  • 20
0

Select all the thdboy rows and hide them. Select all the rows with the class and show them

$(document).on("click", '.filterBtn', function() {

  const filterNumber = $('#filterNumber').val();

  // create a comma seperated list of the class names to show
  var filters = filterNumber.map(function (num) {
    return '.filter_' + num
  }).join()
  
  var trs = $('table tbody tr') // select all the rows

  // if we have filters run the code
  if (filters.length) {
    trs
      .hide() // hide them
      .filter(filters) // find the rows with the class[es]
        .show() // show them
   } else {
     // no filters, just show everything
     trs.show()
   }

})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select multiple id="filterNumber">
  <option value="1">Option 1</option>
  <option value="3">Option 3</option>
  <option value="5">Option 5</option>
</select>
<button type="button" class="filterBtn">Filter</button>


<table>
  <thead>
    <tr>
      <th>Name</th>
    </tr>
  </thead>
  <tbody>
    <tr class="filter_1">
      <td>A1</td>
    </tr>
    <tr class="filter_1">
      <td>A2</td>
    </tr>
    <tr class="filter_5">
      <td>B</td>
    </tr>
    <tr class="filter_3">
      <td>C</td>
    </tr>
    </tbody>
</table>
epascarello
  • 204,599
  • 20
  • 195
  • 236
0

If your rows have classes associated with the selection values, then you can use classes to select which rows to hide and show. Notice how I select all the rows first to remove the class hide. Then, I add hide to all rows that do not share the glass selected.

     jQuery("#c_selector").change(function(){
        jQuery('table tbody tr').removeClass('hide');
        var cat_id = jQuery("#c_selector option:selected").val();
        console.log(cat_id)
        jQuery('table tbody tr:not(.itemtext.c_id'+cat_id+')').addClass('hide');
    })

Maybe this is helpful to someone!

David Weisser
  • 117
  • 1
  • 10