I have a table with several rows and columns and a set of search fields. I would like to be able to show / hide the rows that match / don't match the search fields. Each field is related to a column of the table. I have been partly successful in this task, because the filtering is done correctly (as you can see here). However, I would like to fix two things.
- First is the fact that the jquery script also hides the table head.
- Secondly, I would like to be able to filter the rows as I type. Ex. if I type only 'J' at name box, everything disappears, because there is no row with the name 'J'. However, we have got 'James' and 'Jamie', which are potential match. And I would like to keep them until the name is fully typed. I tried to do it with
s1.localeCompare(s2)
(link here), but it does not work.
By the way, no need to worry about uppercase / lowercase typing. I actually take care of it in the original code, but tried to keep it simple here.
The code here:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
table = $("#MI6"); //set table name
search_field = new Object();
///we create it as an object, initially empty
$('.search-key').on('change keyup paste', function () {
search_field['name'] = $( "#name" ).val();
search_field['lastname'] = $("#lastname").val();
search_field['number'] = $("#number").val();
table.find('tr').each(function () {
current_row = $(this); //keep track of the row being checked, iterate through it's cells
var display = 0;
current_row.show();
$(this).find('td').each(function() {
//when we stumble upon the data used as a search criteria
cell_value = $(this).html(); //gets the value of the cell being checked
if (cell_value == search_field[this.id] || search_field[this.id] == '') {
display++;
}
});
if (display < 3) {
current_row.hide(); //if this cell is a match, or we no longer want to use it as a search criteria, the row is displayed
}
});
});
});
</script>
</head>
<body>
<input type="text" id="name" class="search-key" placeholder="name">
<input type="text" id="lastname" class="search-key" placeholder="lastname">
<input type="number" id="number" class="search-key" placeholder="number">
<p></p>
<table id="MI6">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Number</th>
</tr>
<tr>
<td id="name">James</td>
<td id="lastname">Bond</td>
<td id="number">7</td>
</tr>
<tr>
<td id="name">Vesper</td>
<td id="lastname">Lynd</td>
<td id="number">6</td>
</tr>
<tr>
<td id="name">Rene</td>
<td id="lastname">Mathis</td>
<td id="number">5</td>
</tr>
</table>
</body>
</html>
To answer your first question, simply omit the first row of the table from the collection using
.not(':first')
:In order to do partial string matching, you can use
indexOf()
.I noticed that you can duplicate ids in your markup, they must be unique.
Your script could be rewritten to be more dynamic with a couple of small changes to the markup:
You can then use the
data-input
to target the correspondinginput
. You can combine this with jQuery'sfilter()
method to return matching rows:The above first hides each row, and then filters. Inside of there, each contained
td
is filtered, comparing its text against the value of the correspondinginput
. If a match is found, thetd
is returned. It then checks the number of matchingtd
elements against the number oftd
elements in that row, if they are the same, all fields contain a partial match, and the entire row is returned. Finally, any matching rows are then shown.This way will allow you to add more inputs, and tds without having to modify the code. You'd just have to set the
id
on the input, and add the correspondingdata-input
to thetd
elements.Here's a complete example