When a value is entered into the input, only the row (or rows) containing that value should be displayed, and it works. To do this, each <td>
has a <p class="x">
tag, but only the first <td>
with that class is taken. Here's an example. The text within the red borders are the only values that work. Ignore class="red"
$("#filter").on("input", function () {
let value = $(this).val().toLowerCase();
$("tbody tr").filter(function () {
$(this).toggle($(this).find(".x").text().toLowerCase().indexOf(value) === 0);
});
})
.red {border: 1px solid red;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<input id="filter" type="text" autocomplete="off">
<table>
<tbody>
<tr>
<td>---</td>
<td>
<p class="x red">text</p>
</td>
<td>
<span></span>
<p class="x">card</p>
</td>
</tr>
<tr>
<td>
<p class="x red">robot</p>
</td>
<td>
<p class="x">game</p>
</td>
<td>
<p></p>
<p class="x">box</p>
</td>
</tr>
</tbody>
</table>
What I'm looking to do is, for example, if I put the word "robot", "game" or "box" in the input
(and not just "robot"), all the tr
that contain any of those words will show the entire row.
Your code correctly identifies the elements in the row with the call to .find(".x")
, but the next chained method .text()
only gets the text of the first match.
Instead you need to iterate all elements that were found and then verify their texts individually:
$("tbody tr").each(function () {
$(this).toggle(
$(this).find(".x").toArray().some(function (item) {
return $(item).text().toLowerCase().includes(value);
})
);
});
Unrelated, but the following remarks were applied in the above code:
Don't use filter
if you don't intend to use the collection returned by that method call. In the jQuery world, use each
instead. But as we want to see if any of the elements in the row has the searched string, the iteration could be done with the native some
Array method.
.indexOf(value) === 0
will identify strings that start with the value
, but your description speaks of "containing". If that is what you need, you can use the .includes(value)
call instead.
$("#filter").on("input", function () {
let value = $(this).val().toLowerCase();
$("tbody tr").each(function () {
$(this).toggle(
$(this).find(".x").toArray().some(function (item) {
return $(item).text().toLowerCase().includes(value);
})
);
});
});
.red {border: 1px solid red;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<input id="filter" type="text" autocomplete="off">
<table>
<tbody>
<tr>
<td>---</td>
<td>
<p class="x red">text</p>
</td>
<td>
<span></span>
<p class="x">card</p>
</td>
</tr>
<tr>
<td>
<p class="x red">robot</p>
</td>
<td>
<p class="x">game</p>
</td>
<td>
<p></p>
<p class="x">box</p>
</td>
</tr>
</tbody>
</table>