Reputation: 45320
Assume I have a standard HTML table structure like:
<table class="table table-striped table-hover table-bordered table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Added</th>
</tr>
</thead>
<tbody>
<tr id="1a0daa2734" class="item">
<td><a href="/view/1a0daa2734">Item Number 1</a></td>
<td>A</td>
<td>8/1/2012 10:18:34 PM</td>
</tr>
<tr id="b1ff6e0ac" class="item">
<td><a href="/view/b1ff6e0ac">Item Number 2</a></td>
<td>B</td>
<td>8/2/2012 5:48:54 PM</td>
</tr>
<tr id="edd8b70893" class="item">
<td><a href="/view/edd8b70893">Item Number 3</a></td>
<td>A</td>
<td>8/13/2012 3:55:41 PM</td>
</tr>
</tbody>
</table>
I am trying to write client side searching with jQuery. Basically I have a search box with an id of search-items
.
$("#search-items").bind("keyup paste", function() {
var searchText = $("#search-items").val();
$(".item").each(function() {
//???
});
});
What is the best way to take the search value of search-items
and find the NON-MATCHES inside of the tbody? I want the non-matches, because those are the elements I will hide.
It should only search inside the first two td
elements, so the name
and type
columns, not added.
Thanks.
Upvotes: 5
Views: 5394
Reputation: 126042
How about something like this?
function escapeRegex(value) {
return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
}
$(function() {
$("#search-items").bind("keyup paste", function() {
var searchText = $("#search-items").val(),
regex = new RegExp(escapeRegex(searchText), "gi"),
$items = $(".item").show();
if (searchText) {
$items.each(function() {
var $tds = $("td", this).slice(0, 2), // only the first two columns
text = $tds.text();
if (text.search(regex) === -1) {
$(this).hide();
}
});
}
});
});
Example: http://jsfiddle.net/Pc7Nk/1/
The escapeRegex
function was shamelessly stolen from jQueryUI autocomplete's source code.
Upvotes: 3
Reputation: 22329
The following code will try and match the values as you type them to either column1 or 2.
$("#search").on("keyup paste", function() {
var value = $(this).val().toUpperCase();
var $rows = $("table tr");
if(value === ''){
$rows.show();
return false;
}
$rows.each(function(index) {
if (index !== 0) {
$row = $(this);
var column1 = $row.find("td:first a").html().toUpperCase();
var column2 = $row.find("td").eq(1).text().toUpperCase();
if ((column1.indexOf(value) > -1) || (column2.indexOf(value) > -1)) {
$row.show();
}
else {
$row.hide();
}
}
});
});
I'm sure there is a much more efficient way of writing it but this should get you started.
Upvotes: 7
Reputation: 5720
Going row by row, find the first td (you can also add n number of td elements you want to match against if you like. .text() will return a string, using the string object .search method, you are returning the index of the first match, -1 is returned if there was no match, so we hide the row.
$("#search-items").bind("keyup paste", function() {
var searchText = $("#search-items").val();
$(".item").each(function() {
var $this = $(this)
if ($this.find('td:first-child').text().search(searchText) === -1) {
$this.hide()
}
});
});
Upvotes: -1