mHenderson
mHenderson

Reputation: 132

Filter table with checkboxes

I am filtering a table with checkboxes. The code I have works fine, in some aspects.

I want it to filter results if they meet all the checks, not one.

based on: How can I add to my table filter to allow for multiple checkbox selections, as well as filtering from a dropdown?

My Example

$("input[name='filterStatus'], select.filter").change(function() {
  var classes = [];
  var stateClass = ""

  $("input[name='filterStatus']").each(function() {
    if ($(this).is(":checked")) {
      classes.push('.' + $(this).val());
    }
  });

  if (classes == "" && stateClass == "") {
    // if no filters selected, show all items
    $("#StatusTable tbody tr").show();
  } else {
    // otherwise, hide everything...
    $("#StatusTable tbody tr").hide();

    // then show only the matching items
    rows = $("#StatusTable tr" + stateClass).filter(classes.length ? classes.join(',') : '*');
    if (rows.size() > 0) {
      rows.show();
    }
  }

});
<html>

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
</head>

<body>
  <form name="FilterForm" id="FilterForm" action="" method="">
    <input type="checkbox" name="filterStatus" value="ISO " />
    <label for="filter_1">ISO</label>
    <input type="checkbox" name="filterStatus" value="AMCA" />
    <label for="filter_2">AMCA</label>
    <input type="checkbox" name="filterStatus" value="UL" />
    <label for="filter_3">UL</label>
  </form>

  <table border="1" id="StatusTable">
    <thead>
      <tr>
        <th>Name</th>
        <th>ISO</th>
        <th>AMCA</th>
        <th>UL</th>
      </tr>
      <tbody>
        <tr class="ISO">
          <td class="Name">Name1</td>
          <td class="ISO">&#x2713;</td>
          <td class="AMCA">&nbsp;</td>
          <td class="UL">&nbsp;</td>
        </tr>
        <tr class="ISO AMCA">
          <td class="Name">Name2</td>
          <td class="ISO">&#x2713;</td>
          <td class="AMCA">&#x2713;</td>
          <td class="UL">&nbsp;</td>
        </tr>
        <tr class="ISO AMCA UL">
          <td class="Name">Name3</td>
          <td class="ISO">&#x2713;</td>
          <td class="AMCA">&#x2713;</td>
          <td class="UL">&#x2713;</td>
        </tr>

      </tbody>
  </table>
  <script></script>
</body>

</html>

Upvotes: 8

Views: 21622

Answers (5)

Sohel Rana
Sohel Rana

Reputation: 191

I am doing this, the code will show the selected checkbox rows,

 $('#btnReconcile').click(function () {
            $("#tblReconcilReportDetails>tbody> tr").each(function () {
                var row = $(this);
                var isChecked = $(this).find('td').eq(0).find('input[type="checkbox"].chkReconcil').is(':checked');
                if (isChecked) {
                    row.show();
                } else {
                    row.hide();
                }
            });
        });

Upvotes: 0

Akshay Jain
Akshay Jain

Reputation: 790

Here with the help of this below code. You can filter the table based on checkbox checked and when you didn't select any checkbox then it will display all the records.

$(document).ready(function(){
  $(".name").on("click", function() {
  name_list = []
  $("#myTable tr").hide()
  var flag = 1
  $("input:checkbox[name=name]:checked").each(function(){
  		flag = 0;
    	var value = $(this).val().toLowerCase();
      	$("#myTable tr").filter(function() {
            if($(this).text().toLowerCase().indexOf(value) > -1)
        		$(this).show()
    	});
 	 });
    if(flag == 1)
    	$("#myTable tr").show()
  });
});
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;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>

</script>
<style>
</style>
</head>
<body>

<h2>Filterable Table</h2>

<input type="checkbox" class="name" name="name" value="John" />John
<input type="checkbox" class="name" name="name" value="July" />July
<br><br>

<table>
  <thead>
  <tr>
    <th>Firstname</th>
    <th>Lastname</th>
    <th>Email</th>
  </tr>
  </thead>
  <tbody id="myTable">
  <tr>
    <td>John</td>
    <td>Doe</td>
    <td>[email protected]</td>
  </tr>
  <tr>
    <td>Mary</td>
    <td>Moe</td>
    <td>[email protected]</td>
  </tr>
  <tr>
    <td>July</td>
    <td>Dooley</td>
    <td>[email protected]</td>
  </tr>
  <tr>
    <td>July</td>
    <td>Dooley</td>
    <td>[email protected]</td>
  </tr>
  <tr>
    <td>Anja</td>
    <td>Ravendale</td>
    <td>[email protected]</td>
  </tr>
  </tbody>
</table>
  
<p>Note that we start the search in tbody, to prevent filtering the table headers.</p>

</body>
</html>

Upvotes: 5

Vadzim
Vadzim

Reputation: 26180

jQuery Scrollable, Sortable, Filterable table references DataTables library which under https://datatables.net/news/ has an entry for 8th Feb 2019:

Yevgen Gorbunkov has written a very nice plug-in for DataTables which shows a drop down filtering from the header allowing union searches to be performed. The source is available on GitHub.

I've converted the example from https://jsfiddle.net/ahqso1j5/ to the snippet here:

// Plug-in source available at:
// https://github.com/ygorbunkov/datatables-multiple-criteria-filter
$(document).ready(function () {
//Source data definition	
var tableData = [{
		name: 'Clark Kent',
		city: 'Metropolis',
		race: 'cryptonian'
	}, {
		name: 'Bruce Wayne',
		city: 'Gotham',
		race: 'human'
	}, {
		name: 'Steve Rogers',
		city: 'New York',
		race: 'superhuman'
	}, {
		name: 'Peter Parker',
		city: 'New York',
		race: 'superhuman'
	}, {
		name: 'Thor Odinson',
		city: 'Asgard',
		race: 'god'
	}, {
		name: 'Jonathan Osterman',
		city: 'New York',
		race: 'superhuman'
	}, {
		name: 'Walter Kovacs',
		city: 'New Jersey',
		race: 'human'
	}, {
		name: 'Arthur Curry',
		city: 'Atlantis',
		race: 'superhuman'
	}, {
		name: 'Tony Stark',
		city: 'New York',
		race: 'human'
	}, {
		name: 'Scott Lang',
		city: 'Coral Gables',
		race: 'human'
	}, {
		name: 'Bruce Banner',
		city: 'New York',
		race: 'superhuman'
	}
];
//DataTable definition	
window.dataTable = $('#mytable').DataTable({
		sDom: 'tF',
		data: tableData,
		columns: [{
				data: 'name',
				title: 'Name'
			}, {
				data: 'city',
				title: 'City'
			}, {
				data: 'race',
				title: 'Race'
		}]
});
});
<!doctype html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
  <script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
  <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/ygorbunkov/datatables-multiple-criteria-filter@master/js/mFilter.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
  <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/ygorbunkov/datatables-multiple-criteria-filter@master/css/mFilter.css">
</head>
<body>
  <table id="mytable"></table>
</body>
</html>

Upvotes: 1

Modify your jQuery where it loops through each row. Create a tag variable to store whether or not the row is to be shown, and set it to true by default.

Now when you loop through each row, you will also loop through each class you are checking for. If at any point, a loop test fails, set your show variable to false to keep the row hidden.

$("input[name='filterStatus']").change(function () {
    var classes = [];

    $("input[name='filterStatus']").each(function () {
        if ($(this).is(":checked")) { classes.push('.' + $(this).val()); }
    });

    if (classes == "") { // if no filters selected, show all items
        $("#StatusTable tbody tr").show();
    } else { // otherwise, hide everything...
        $("#StatusTable tbody tr").hide();

        $("#StatusTable tr").each(function () {
            var show = true;
            var row = $(this);
            classes.forEach(function (className) {
                if (row.find('td' + className).html() == '&nbsp;') { show = false; }
            });
            if (show) { row.show(); }
        });
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
    
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    </head>
    
    <body>
        <form name="FilterForm" id="FilterForm" action="" method="">
            <input type="checkbox" name="filterStatus" value="ISO " />
            <label for="filter_1">ISO</label>
            <input type="checkbox" name="filterStatus" value="AMCA" />
            <label for="filter_2">AMCA</label>
            <input type="checkbox" name="filterStatus" value="UL" />
            <label for="filter_3">UL</label>
        </form>
        <table border="1" id="StatusTable">
            <thead>
                <tr>
                    <th>Name</th>
                    <th>ISO</th>
                    <th>AMCA</th>
                    <th>UL</th>
                </tr>
                <tbody>
                    <tr class="ISO">
                        <td class="Name">Name1</td>
                        <td class="ISO">&#x2713;</td>
                        <td class="AMCA">&nbsp;</td>
                        <td class="UL">&nbsp;</td>
                    </tr>
                    <tr class="ISO AMCA">
                        <td class="Name">Name2</td>
                        <td class="ISO">&#x2713;</td>
                        <td class="AMCA">&#x2713;</td>
                        <td class="UL">&nbsp;</td>
                    </tr>
                    <tr class="ISO AMCA UL">
                        <td class="Name">Name3</td>
                        <td class="ISO">&#x2713;</td>
                        <td class="AMCA">&#x2713;</td>
                        <td class="UL">&#x2713;</td>
                    </tr>
                </tbody>
        </table>
        <script></script>
    </body>

</html>

Upvotes: 8

renakre
renakre

Reputation: 8291

Demo: https://jsfiddle.net/erkaner/u12te5jb/

Here is my solution

$("input[name='filterStatus']").change(function () {

var count1 = $("input[name='filterStatus']:checked").length;//number of checked items

$("#StatusTable>tbody> tr").each(function () {//for each row
    var count2 = 0;//this is the count of td that has ✓ 
    var row = $(this);//the current row
    $("input[name='filterStatus']:checked").each(function () {//for each checked item
        var inputVal = $(this).val();//get the value, which is class of the corresponding td, see below
        if (row.find('.' + inputVal).html().indexOf("✓") >= 0)//if the td that corresponds to the selected checkbox contains ✓
            count2++;//then increase
    });

    if (count1 == count2) //if counts match
        row.show();//then show
    else 
        row.hide();
    });
});

Upvotes: 3

Related Questions