Carje
Carje

Reputation: 25

Hide rows with multiple checkboxes

I have a HTML table in which I want to hide/show rows based on multiple checkboxes.

When a checkbox is checked, (based on a text criterion) some rows are hiding, if it's unchecked, all rows are shown. If 2 or more checkboxes are checked, all rows are hiden, except those which met the criteria from all selected checkboxes. But if I uncheck any of the checboxes, all rows are shown.

My question is, when I uncheck one of the checkboxes, how can I show ONLY the rows that met the criteria from all current selected checkboxes?

For better understanding, I need to check which rows are already hidden by the other checkboxes and not show them when a checkbox is unchecked.

Example of working case: checkbox1 and checkbox2 are selected: only row1 is shown, if I uncheck checkbox2, only row1 and row3 must be shown

HTML:

<label><input type="checkbox" id="checkbox1">Teacher</label>
<label><input type="checkbox" id="checkbox2">Tennis</label>
<label><input type="checkbox" id="checkbox3">Married</label>

    <table id="table" border="1">
    <thead>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Profession</th>
        <th>Hobby</th>
        <th>Married</th>
    </thead>
    <tbody>
    <tr id="row1">
      <td>John</td>
      <td>Doe</td>
      <td>Teacher</td>
      <td>Tennis</td>
      <td>Yes</td>
    </tr>
    <tr id="row2">
      <td>Eve</td>
      <td>Jackson</td>
      <td>Doctor</td>
      <td>Darts</td>
      <td>No</td>
    </tr>
    <tr id="row3">
      <td>Adam</td>
      <td>Johnson</td>
      <td>Teacher</td>
      <td>Skydiving</td>
      <td>Yes</td>
    </tr>
     <tr id="row4">
      <td>Nina</td>
      <td>Pursuit</td>
      <td>Lawyer</td>
      <td>Tennis</td>
      <td>Yes</td>
    </tr>
    </tbody>
    </table> 

jQuery:

$(document).ready(function () {
    $('#checkbox1').change(function () {
            for (var i = 0; i < 5; i++) {
                if ((this.checked) && $("#table #row"+i+" td:nth-child(3):not(:contains('Teacher'))").length){
                    $('#row'+i).fadeOut('slow');
                } 
                if (!this.checked) $('#row'+i).fadeIn('slow');
                }
    });

    $('#checkbox2').change(function () {
            for (var i = 0; i < 5; i++) {
                if ((this.checked) && $("#table #row"+i+" td:nth-child(4):not(:contains('Tennis'))").length){
                    $('#row'+i).fadeOut('slow');
                } 
                if (!this.checked) $('#row'+i).fadeIn('slow');
                }
    });

    $('#checkbox3').change(function () {
            for (var i = 0; i < 5; i++) {
                if ((this.checked) && $("#table #row"+i+" td:nth-child(5):not(:contains('Yes'))").length){
                    $('#row'+i).fadeOut('slow');
                } 
                if (!this.checked) $('#row'+i).fadeIn('slow');
                }
    });
});

JSFiddle DEMO

Upvotes: 0

Views: 534

Answers (4)

conste
conste

Reputation: 410

To achieve your desired behavior you need to store the actual status of each element when this gets hidden. This uses one event listener for all checkboxes.

The logic is pretty easy: Iterate over all rows and hide the current when the following criteria is met:

  1. The checkbox is checked
  2. The row isn't hidden yet
  3. The row does contain the specific element

Each hiding involves an update to the state object and in the end all rows get shown that are not in this state object.

$(document).ready(function () {
  $('input[type="checkbox"]').click(function() {

    var checkbox_1 = $('#checkbox1')[0].checked
    var checkbox_2 = $('#checkbox2')[0].checked
    var checkbox_3 = $('#checkbox3')[0].checked
    var state = {}

    for (var i = 0; i < 5; i++) {
      if (checkbox_1 && !state[i] && $("#table #row"+i+" td:nth-child(3):not(:contains('Teacher'))").length){
        $('#row'+i).fadeOut('slow');
        state[i] = "hidden"
      }
      if (checkbox_2 && !state[i] && $("#table #row"+i+" td:nth-child(4):not(:contains('Tennis'))").length){
        $('#row'+i).fadeOut('slow');
        state[i] = "hidden"
      }
      if (checkbox_3 && !state[i] && $("#table #row"+i+" td:nth-child(5):not(:contains('Yes'))").length){
        $('#row'+i).fadeOut('slow');
        state[i] = "hidden"
      }
      if (!state[i]) {
        $('#row'+i).fadeIn('slow');
      }
    }
  });
});

Upvotes: 0

Bhavesh Gupta
Bhavesh Gupta

Reputation: 176

$(document).ready(function() {
  $('#checkbox1').change(function() {
    for (var i = 0; i < 5; i++) {
      if ((this.checked) && $("#table #row" + i + " td:nth-child(3):not(:contains('Teacher'))").length) {
        //				$('#row'+i).fadeOut('slow');
        $('#table #row' + i).addClass('check1');
      }
      if (!this.checked) $('#table #row' + i).removeClass('check1');
    }
  });

  $('#checkbox2').change(function() {
    for (var i = 0; i < 5; i++) {
      if ((this.checked) && $("#table #row" + i + " td:nth-child(4):not(:contains('Tennis'))").length) {
        //					$('#row'+i).fadeOut('slow');
        $('#table #row' + i).addClass('check2');
      }
      if (!this.checked) $('#table #row' + i).removeClass('check2');
    }
  });

  $('#checkbox3').change(function() {
    for (var i = 0; i < 5; i++) {
      if ((this.checked) && $("#table #row" + i + " td:nth-child(5):not(:contains('Yes'))").length) {
        //$('#row'+i).fadeOut('slow');
        $('#table #row' + i).addClass('check3');
      }
      if (!this.checked) $('#table #row' + i).removeClass('check3');
    }
  });
  $('.checkbox').change(function() {
    for (var i = 0; i < 5; i++) {
      if ($("#table #row" + i).hasClass('check1') || $("#table #row" + i).hasClass('check2') || $("#table #row" + i).hasClass('check3')) {
        $('#row' + i).fadeOut('slow');
        //  $('#table #row'+i).addClass('check3');
      } else {
        $('#row' + i).fadeIn('slow');
      }

    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>
  <input type="checkbox" class="checkbox" id="checkbox1">Teacher</label>
<label>
  <input type="checkbox" class="checkbox" id="checkbox2">Tennis</label>
<label>
  <input type="checkbox" class="checkbox" id="checkbox3">Married</label>

<table id="table" border="1">
  <thead>
    <th>First Name</th>
    <th>Last Name</th>
    <th>Profession</th>
    <th>Hobby</th>
    <th>Married</th>
  </thead>
  <tbody>
    <tr id="row1">
      <td>John</td>
      <td>Doe</td>
      <td>Teacher</td>
      <td>Tennis</td>
      <td>Yes</td>
    </tr>
    <tr id="row2">
      <td>Eve</td>
      <td>Jackson</td>
      <td>Doctor</td>
      <td>Darts</td>
      <td>No</td>
    </tr>
    <tr id="row3">
      <td>Adam</td>
      <td>Johnson</td>
      <td>Teacher</td>
      <td>Skydiving</td>
      <td>Yes</td>
    </tr>
    <tr id="row4">
      <td>Nina</td>
      <td>Pursuit</td>
      <td>Lawyer</td>
      <td>Tennis</td>
      <td>Yes</td>
    </tr>
  </tbody>
</table>

You can look this solution.

Upvotes: 0

Ultrazz008
Ultrazz008

Reputation: 1688

You could create a function that checks all and shows/hide rows, and just call it on checkbox change event here's an example:

function show_hide_rows() {
	var checkbox1=($('#checkbox1').is(':checked') ? true : false),
		checkbox2=($('#checkbox2').is(':checked') ? true : false),
		checkbox3=($('#checkbox3').is(':checked') ? true : false);
	
	var passed;
	for (var i = 0; i < 5; i++) {
		passed = false;
		if (checkbox1 && $("#table #row"+i+" td:nth-child(3):not(:contains('Teacher'))").length) passed = true;
		if (checkbox2 && $("#table #row"+i+" td:nth-child(4):not(:contains('Tennis'))").length) passed = true;
		if (checkbox3 && $("#table #row"+i+" td:nth-child(5):not(:contains('Yes'))").length) passed = true;
		
		if (passed) $('#row'+i).fadeOut('slow');
		else $('#row'+i).fadeIn('slow');
		}
}

$(function(){
  $('input[type="checkbox"]').on('change', function(){ show_hide_rows(); });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label><input type="checkbox" id="checkbox1">Teacher</label>
<label><input type="checkbox" id="checkbox2">Tennis</label>
<label><input type="checkbox" id="checkbox3">Married</label>

    <table id="table" border="1">
    <thead>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Profession</th>
        <th>Hobby</th>
        <th>Married</th>
    </thead>
    <tbody>
    <tr id="row1">
      <td>John</td>
      <td>Doe</td>
      <td>Teacher</td>
      <td>Tennis</td>
      <td>Yes</td>
    </tr>
    <tr id="row2">
      <td>Eve</td>
      <td>Jackson</td>
      <td>Doctor</td>
      <td>Darts</td>
      <td>No</td>
    </tr>
    <tr id="row3">
      <td>Adam</td>
      <td>Johnson</td>
      <td>Teacher</td>
      <td>Skydiving</td>
      <td>Yes</td>
    </tr>
     <tr id="row4">
      <td>Nina</td>
      <td>Pursuit</td>
      <td>Lawyer</td>
      <td>Tennis</td>
      <td>Yes</td>
    </tr>
    </tbody>
    </table>

Upvotes: 0

Wikiti
Wikiti

Reputation: 1636

You don't need to track that. Just show all rows, and process the hide criteria to hide the matching rows.

Something like this:

When a checkbox is changed
Show all rows
Check all checkboxes, and hide those rows that match the criteria

Since this will be performer on a single frame, the browser won't flicker, resulting in a clean and fast change.

Upvotes: 0

Related Questions