Reputation: 43
I have been struggling with trying to filter a table based on a simple text input. It works on the first column but I also want the user to be able to filter by the second column. So I tried to add the var ts but that didn't. Any help would be much appreciated :-)
function search () {
var field = document.getElementById("searchField");
var filter = field.value.toUpperCase();
var table = document.getElementById('table');
var tr = table.getElementsByTagName('tr');
var i;
var txtValue;
var td;
var ts;
if (filter.length > 0)
{
for (i = 0; i < tr.length; i++)
{
td = tr[i].getElementsByTagName("td")[0];
ts = tr[i].getElementsByTagName("td")[1];
if (td)
{
txtValue = td.textContent || td.innerText || ts.textContent || ts.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1)
{
tr[i].style.display = "";
}
else
{
tr[i].style.display = "none";
}
}
}
}
}
Here's part of the php:
$get_persons = $connection->prepare('SELECT first_name, last_name FROM persons WHERE status = :status ORDER BY first_name ASC');
$get_persons->execute([status=>'success']);
echo '
<input type="text" class="search-field" id="searchField" onkeyup="search()" placeholder="'.$searchPlaceholder.'" />
<table id="table" class="start-list-table">
<thead>
<tr class="start-list-tr">
<th scope="col">'.$titleFirstName.'</th>
<th scope="col">'.$titleLastName.'</th>
</tr>
</thead>
<tbody>
';
$persons = $get_persons->fetchAll();
foreach($persons as $person){
echo '
<tr class="start-list-tr">
<td data-label="'.$titleFirstName.'">'.$person->first_name'</td>
<td data-label="'.$titleLastName.'">'.$person->last_name.'</td>
</tr>';
}
echo '</tbody>
</table>';
Upvotes: 0
Views: 1243
Reputation: 93
txtValue = td.textContent || td.innerText || ts.textContent || ts.innerText;
This statement says txtValue
will be td
's inner text if td
has inner text, so in those cases you're still filter rows by column1 not column2. Use this:
textValue = [td.textContent || td.innerText, ts.textContent || ts.innerText];
if (txtValue.some(txt => txt.toUpperCase().indexOf(filter) > -1))
{
tr[i].style.display = "";
}
else
{
tr[i].style.display = "none";
}
Upvotes: 0
Reputation: 43
@srikanthreddy pointed me to this thread which solved my issue in a much nicer way. Thanks!
Upvotes: 1
Reputation: 11447
You have this line var table = document.getElementById('table');
which I doubt that table
is an id. It is better to use querySelector()
and querySelectorAll()
if you don not require live nodes.
Here is an example with mock table data:
function search(field) {
var filter = field.value.toUpperCase();
var table = document.querySelector('table');
var tr = table.querySelectorAll('tr');
var i;
var txtValue;
var td;
var ts;
if (filter.length > 0) {
for (i = 0; i < tr.length; i++) {
td = tr[i].querySelector("td:first-child");
ts = tr[i].querySelector("td:nth-child(2)");
if (td) {
txtValue = td.textContent || td.innerText || ts.textContent || ts.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
}
<input type='text' id='searchField' oninput='search(this)'>
<table>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td>Austria</td>
</tr>
<tr>
<td>Island Trading</td>
<td>Helen Bennett</td>
<td>UK</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Yoshi Tannamuri</td>
<td>Canada</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti</td>
<td>Giovanni Rovelli</td>
<td>Italy</td>
</tr>
</table>
Upvotes: 0