Filter table based on multiple columns’ value with multiple buttons

Tags: ,



What I am trying to achieve:

I currently got two working buttons with a static value which is Yes.

<button type="button" id="foo_btn" value="Yes" class="btn">Foo</button>
<button type="button" id="bar_btn" value="Yes" class="btn">Bar</button>

When clicked it will filter a table based on the column’s value and only show the rows which has the value Yes in that specific column in them.

Currently I use an switch statement to check the id of the button clicked and then set a variable which determines what column to be filtered, but I don’t like this approach as if I include several columns/buttons, it will get rather long and messy. Also I don’t like working with switch statements.

I also tested the performance of each event in Developer Tools in the Perfomance section and noticed that each task takes over a second to perform. Is there any superior solution to this rather than using switch statements?

Working example of what I’ve tried but with an ugly approach:

$('#foo_btn, #bar_btn').on('click', function() {
    var val = $(this).val().toLowerCase();
    switch(this.id) {
    case 'foo_btn': 
      col = 'td:nth-child(1)';
      break;
    case 'bar_btn': 
      col = 'td:nth-child(2)';
      break;
    }
    $(col).filter(function() {
      $('tr:not(:has(th))').show();
      return $(this).text().toLowerCase().indexOf(val);
    }).parent().hide();
});
table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td, th {
  border: 1px solid #dddddd;
  text-align: left;
  padding: 8px;
}

tr:nth-child(even) {
  background-color: #dddddd;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" id="foo_btn" value="Yes" class="btn">Foo</button>
<button type="button" id="bar_btn" value="Yes" class="btn">Bar</button>
<table class="table">
  <tr>
    <th>Foo</th>
    <th>Bar</th>
  </tr>
  <tr>
    <td>Yes</td>
    <td>No</td>
  </tr>
  <tr>
    <td>No</td>
    <td>Yes</td>
  </tr>
  <tr>
    <td>No</td>
    <td>No</td>
  </tr>
  <tr>
    <td>Yes</td>
    <td>Yes</td>
  </tr>
</table>

Comment

I feel like this is a really simple solution to a simple problem which I’ve just gotten my brain tangled in. I appreciate all help I can get.

Answer

Based on the working example in your question you could make use of the html data property and bake the desired column right into the button itself. e.g.

<button type="button" id="foo_btn" value="Yes" data-column="1" class="btn">Foo</button>

and inside the click event listener’s callback function you can get the value of data-colum using

col = 'td:nth-child(' + $(this).data('column') + ')';

Here’s the complete example:

$('#foo_btn, #bar_btn').on('click', function() {
  var val = $(this).val().toLowerCase();
  col = 'td:nth-child(' + $(this).data('column') + ')';
  $(col).filter(function() {
    $('tr:not(:has(th))').show();
    return $(this).text().toLowerCase().indexOf(val);
  }).parent().hide();
});
table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td,
th {
  border: 1px solid #dddddd;
  text-align: left;
  padding: 8px;
}

tr:nth-child(even) {
  background-color: #dddddd;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" id="foo_btn" value="Yes" data-column="1" class="btn">Foo</button>
<button type="button" id="bar_btn" value="Yes" data-column="2" class="btn">Bar</button>
<table class="table">
  <tr>
    <th>Foo</th>
    <th>Bar</th>
  </tr>
  <tr>
    <td>Yes</td>
    <td>No</td>
  </tr>
  <tr>
    <td>No</td>
    <td>Yes</td>
  </tr>
  <tr>
    <td>No</td>
    <td>No</td>
  </tr>
  <tr>
    <td>Yes</td>
    <td>Yes</td>
  </tr>
</table>


Source: stackoverflow