safoora safu safoora safu - 1 month ago 5
jQuery Question

Modify filter to apply only to the visible rows in the table

I am trying to filter the content in table using

dropdown filter
. Below is my code. It works perfectly alright when this only filter applied. But when it's applied over any other filter, it also takes hidden rows into account. That's how it is incompatible with multiple filters. I am not very much experienced in Jquery. So I will appreciate if any one could give input for the same.

$(document).ready(function() {

function addRemoveClass(theRows) {

theRows.removeClass("odd even");
theRows.filter("tr:visible:odd").addClass("odd");
theRows.filter("tr:visible:even").addClass("even");
}
var rows = $("table#testTable tr:not(:first-child)");

// addRemoveClass(rows);


$("#selectField1").on("change", function() {

var selected = this.value;

if (selected != "All") {

rows.filter("[OHQ=" + selected + "]").show();
rows.not("[OHQ=" + selected + "]").hide();
addRemoveClass(visibleRows);
} else {

rows.show();
addRemoveClass(rows);

}

});
});

Answer

One way to cumulate filters, is to re-apply all filters at each change, so also picking up the value(s) of any other input that defines the combined filter. This can you do by creating one event handler for all filter-input changes, and processing the values of all inputs in that handler to build one combined filter.

Secondly, to color the rows in alternating fashion, even when filtered, you should get the rows by filtering for :visible, and then use the jQuery specific :odd and :even selectors.

See the snippet below for a demo:

var $rows = $("table#testTable tr:not(:first-child)");

function addRemoveClass() {
    var $visibleRows = $rows.filter(':visible');
    $visibleRows.removeClass("odd even");
    $visibleRows.filter(':odd').addClass("odd");
    $visibleRows.filter(':even').addClass("even");
}

$("#selectField, #selectField1").on("change", function() {
    var $filteredRows = $rows;
    // filter by the first input:
    var selected = $('#selectField').val();
    if (selected != "All") {
        $filteredRows = $filteredRows.filter("[position=" + selected + "]");
    }
    // accumulate the second input into the filter:
    selected = $('#selectField1').val();
    if (selected != "All") {
        $filteredRows = $filteredRows.filter("[OHQ=" + selected + "]");
    }
    // hide all rows, and then make the filtered rows visible:
    $rows.hide();
    $filteredRows.show();
    // apply the styles for alternating odd/even rows:
    addRemoveClass();
});

addRemoveClass();
.even { background: #ccc; }
.odd { background: #eee; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
position:
  <select id="selectField">
    <option value="All">All</option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
  </select>&nbsp;
OHQ:
  <select id="selectField1">
    <option value="All">All</option>
    <option value="a">a</option>
    <option value="b">b</option>
    <option value="c">c</option>
  </select>
</p>
<table id="testTable">
  <tr><th>header</th></tr>
  <tr position="1" OHQ="a"><td>row 1, position=1, OHQ=a</td></tr>
  <tr position="2" OHQ="a"><td>row 2, position=2, OHQ=a</td></tr>
  <tr position="2" OHQ="a"><td>row 3, position=2, OHQ=a</td></tr>
  <tr position="2" OHQ="b"><td>row 4, position=2, OHQ=b</td></tr>
  <tr position="3" OHQ="b"><td>row 5, position=3, OHQ=b</td></tr>
  <tr position="3" OHQ="c"><td>row 6, position=3, OHQ=c</td></tr>
</table>

Note that the :odd and :even selectors use the zero-based numbering, so the first (visible) row will be regarded as even. Swap the class names if you want it the other way round.