Reputation: 456
I have followed this link on how to create/filter search a table. But I want to filter search for each column in my own table. Currently, it only searches for the First Name column. How can I do this?
This is the code:
myHTML:
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<table id="myTable">
<tr class="header">
<th> First Name </th>
<th> Last Name </th>
<th> Age </th>
<th> Language </th>
</tr>
<tr>
<td>John</td>
<td>Kole</td>
<td>18</td>
<td>English</td>
</tr>
<tr>
<td>Pearl</td>
<td>Shine</td>
<td>50</td>
<td>Hindi</td>
</tr>
<tr>
<td>Jacob</td>
<td>Pool</td>
<td>22</td>
<td>Arabic</td>
</tr>
<tr>
<td>David</td>
<td>Struff</td>
<td>30</td>
<td>German</td>
</tr>
</table>
<script>
function myFunction() {
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
}
else {
tr[i].style.display = "none";
}
}
}
}
</script>
How can I filter all columns for searching? Currently, it searches the First Name column only.
Upvotes: 0
Views: 3846
Reputation:
Get all table rows. Loop through these rows. Put all the innerText
from the <td>s
in each row together into a string. Check the first occurrence of the search value in the string. If the value is not found, hide the row with display: none
else show the row with display: table-row
.
const id = "myTable";
const selector = `#${id} tr:not(.header)`;
// Get all rows
const trs = document.querySelectorAll(selector);
function myFunction(event) {
let search = event.target.value.toLowerCase();
trs.forEach((tr) => {
// Get all cells in a row
let tds = tr.querySelectorAll("td");
// String that contains all td textContent from a row
let str = Array.from(tds).map((td) => {
return td.textContent.toLowerCase();
}).join("");
tr.style.display = (str.indexOf(search) > -1) ? "table-row" : "none";
});
}
<input type="text" id="myInput" onkeyup="myFunction(event)" placeholder="Search for names.." title="Type in a name">
<table id="myTable">
<tr class="header">
<th> First Name </th>
<th> Last Name </th>
<th> Age </th>
<th> Language </th>
</tr>
<tr>
<td>John</td>
<td>Kole</td>
<td>18</td>
<td>English</td>
</tr>
<tr>
<td>Pearl</td>
<td>Shine</td>
<td>50</td>
<td>Hindi</td>
</tr>
<tr>
<td>Jacob</td>
<td>Pool</td>
<td>22</td>
<td>Arabic</td>
</tr>
<tr>
<td>David</td>
<td>Struff</td>
<td>30</td>
<td>German</td>
</tr>
</table>
Upvotes: 0
Reputation: 19986
Check each nodes of the table row instead of just checking tr[i].getElementsByTagName("td")[0]
. The zeroth node corresponds to first name field, that's why the search result restricts to the first name field only.. Search for all the nodes instead.
Leave the tr
node with class name of header
while making the row hidden.
function myFunction() {
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
// td = tr[i].getElementsByTagName("td")[0];
alltags = tr[i].getElementsByTagName("td");
isFound = false;
for(j=0; j< alltags.length; j++) {
td = alltags[j];
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
j = alltags.length;
isFound = true;
}
}
}
if(!isFound && tr[i].className !== "header") {
tr[i].style.display = "none";
}
}
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<table id="myTable">
<tr class="header">
<th> First Name </th>
<th> Last Name </th>
<th> Age </th>
<th> Language </th>
</tr>
<tr>
<td>John</td>
<td>Kole</td>
<td>18</td>
<td>English</td>
</tr>
<tr>
<td>Pearl</td>
<td>Shine</td>
<td>50</td>
<td>Hindi</td>
</tr>
<tr>
<td>Jacob</td>
<td>Pool</td>
<td>22</td>
<td>Arabic</td>
</tr>
<tr>
<td>David</td>
<td>Struff</td>
<td>30</td>
<td>German</td>
</tr>
</table>
Hope this is what you are looking for.
Upvotes: 3
Reputation: 136
This line:
td = tr[i].getElementsByTagName("td")[0];
gets the first td
which is the content for the first column in the table meaning the FirstName column.
Do a loop on all td
tags instead of getting only the first one and you'll get the functionality you need.
Upvotes: 0