Reputation: 15335
I have a table like
<input id="searchText" type="text" placeholder="Search...">
<table>
<thead>
<tr>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
</tr>
</thead>
<tbody id="tableData">
<tr>
<td class="action">Action</td>
<td>something 1</td>
<td>something 2</td>
</tr>
<tr>
<td class="action">Action</td>
<td>else 1</td>
<td>else 2</td>
</tr>
<tr>
<td class="action">Action</td>
<td>action 1</td>
<td>action 2</td>
</tr>
</tbody>
</table>
And I have some jQuery like:
$("#searchText").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#tableData tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1);
});
});
Fiddle here: https://jsfiddle.net/jreljac/4hfn0sqb/1/
I'd like the search to exclude the text in the first cell of each row. If someone were to type "action" it would filter the first two rows out leaving just the third row. Currently, nothing is filtered since "action" is in the first cell of each of the <tbody>
rows.
I've tried several combinations of adding .not(".action")
with no luck. Without using a plugin, is this possible?
Upvotes: 1
Views: 595
Reputation: 337560
To achieve this you can use :gt(0)
to ignore the text of the first column td
cells:
$(this).toggle($(this).find('td:gt(0)').text().toLowerCase().indexOf(value) > -1);
Also note that you should be using each()
, not filter()
, here. This is because the former is used to loop. The latter is used to reduce the collection by a provided function, which you're not quite doing, and is not required here. Here's an updated full example:
$("#searchText").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#tableData tr").each(function() {
var $tr = $(this);
$tr.toggle($tr.find('td:gt(0)').text().toLowerCase().indexOf(value) > -1);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="searchText" type="text" placeholder="Search...">
<table>
<thead>
<tr>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
</tr>
</thead>
<tbody id="tableData">
<tr>
<td>Action</td>
<td>something 1</td>
<td>something 2</td>
</tr>
<tr>
<td>Action</td>
<td>else 1</td>
<td>else 2</td>
</tr>
</tbody>
</table>
If, for whatever reason, you still wanted to use filter()
, then you'd need to restructure your logic like this; note the return
and use of show()
and hide()
:
$("#searchText").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#tableData tr").show().filter(function() {
var $tr = $(this);
return $tr.find('td:gt(0)').text().toLowerCase().indexOf(value) == -1
}).hide();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="searchText" type="text" placeholder="Search...">
<table>
<thead>
<tr>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
</tr>
</thead>
<tbody id="tableData">
<tr>
<td>Action</td>
<td>something 1</td>
<td>something 2</td>
</tr>
<tr>
<td>Action</td>
<td>else 1</td>
<td>else 2</td>
</tr>
</tbody>
</table>
Upvotes: 2