Search code examples
javascriptjquerytablesorter

Applying a persistent filter to a tablesorter table


I would like to apply a persistent filter to a tablesorter table.

By this, I mean I would like to apply a filter in addition to the filters seen by the user. In other words, I want to make certain rows disappear as far as tablesorter is concerned, but I can't outright delete them as I need to be able to re-add them later.

The following demonstrates an attempt. While it appears to work, the hidden rows become visible when a filter becomes less restrictive. (e.g. Check the box, enter "B1" in the filter for column "B", then delete the "1".)

$(function() {
   var $table = $('#table').tablesorter({
      theme: 'blue',
      widgets: [ "zebra", "filter" ],
      widgetOptions : {
      },
   });

   $('#hide_spoilers').change(function(){
      if (this.checked) {
         $table.find("tr.spoiler").hide();
         $table.trigger('applyWidgetId', 'zebra');
      } else {
         $table.find("tr.spoiler").show();
         // And somehow refresh the search here.
         $table.trigger('applyWidgetId', 'zebra');
      }
   });
});
tr.spoiler td { color: rgba(0, 0, 0, 0.1) }
<link rel="stylesheet" type="text/css" href="https://mottie.github.io/tablesorter/dist/css/theme.blue.css">

<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="https://mottie.github.io/tablesorter/dist/js/jquery.tablesorter.min.js"></script>
<script type="text/javascript" src="https://mottie.github.io/tablesorter/dist/js//jquery.tablesorter.widgets.min.js"></script>

<p><label for="hide_spoilers">Hide Spoilers</label><input id="hide_spoilers" type="checkbox"></p>

<table id="table">
   <thead>
      <tr><th>A</th><th>B</th><th>C</th></tr>
   </thead>
   <tbody>
      <tr><td>A1</td><td>B1</td><td>C1</td></tr>
      <tr><td>A2</td><td>B2</td><td>C2</td></tr>
      <tr class="spoiler"><td>A3</td><td>B3</td><td>C3</td></tr>
      <tr><td>A4</td><td>B4</td><td>C4</td></tr>
   </tbody>
</table>

I also tried adding the filtered class to the rows, but it's no surprise that this doesn't work either.

This can be done using a hidden column, but that could mess with other features (such as filter_reset). Is there a native way?


Solution

  • The css specificity needs to be increased on the spoiler row:

    I modified the following (demo):

    HTML

    <input id="hide_spoilers" type="checkbox" checked>
    ...
    <tr class="spoiler hide"><td>A3</td><td>B3</td><td>C3</td></tr>
    

    CSS

    tr.spoiler td { color: rgba(0, 0, 0, 0.1) }
    tr.spoiler.hide { display: none; }
    

    JS

    $('#hide_spoilers').change(function(){
       if (this.checked) {
          $table.find("tr.spoiler").addClass('hide');
          $table.trigger('applyWidgetId', 'zebra');
       } else {
          $table.find("tr.spoiler").removeClass('hide');
          // And somehow refresh the search here.
          $table.trigger('applyWidgetId', 'zebra');
       }
    });