How to filter/search/highlight columns in HTML table? I have a problem when highlighting the matches that my search engine finds, the problem is that when deleting some characters they remain marked, could someone help me and explain why that happens, I have an example in which it is done by column and it works fine for me the problem now is that I want to perform the search by row and highlight the matches.
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;
tr[i].style.display = "";
for(j=0; j< alltags.length; j ) {
td = alltags[j];
if (td) {
txtValue = td.textContent || td.innerText;
index = txtValue.toUpperCase().indexOf(filter);
if (index > -1) {
td.innerHTML = txtValue.substring(-1, index) "<mark>" txtValue.substring(index, index filter.length) "</mark>" txtValue.substring(index filter.length);
tr[j].style.display = "";
j = alltags.length;
isFound = true;
}
}
}
if(!isFound && tr[i].className !== "header") {
// tr[i].style.display = "none";
}
}
}
<body>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<table id="myTable">
<tr >
<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>
</body>
CodePudding user response:
You have a problem when the value in the search box is empty string, you don't remove the final highlighted letter of the previous search. I added an else
statement to your code as well as a check for empty string in the search term before adding a mark
tag and it works as intended.
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;
tr[i].style.display = "";
for(j=0; j< alltags.length; j ) {
td = alltags[j];
if (td) {
txtValue = td.textContent || td.innerText;
index = txtValue.toUpperCase().indexOf(filter);
if (index > -1 && filter !== "") {
td.innerHTML = txtValue.substring(-1, index) "<mark>" txtValue.substring(index, index filter.length) "</mark>" txtValue.substring(index filter.length);
tr[j].style.display = "";
j = alltags.length;
isFound = true;
} else {
td.innerHTML = td.textContent;
}
}
}
if(!isFound && tr[i].className !== "header") {
// tr[i].style.display = "none";
}
}
}
<body>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<table id="myTable">
<tr >
<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>
</body>
CodePudding user response:
A quick and dirty solution is to remove the mark from the TD's innerHTML before doing a search in that TD. That way it will always show the current results.
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;
tr[i].style.display = "";
for(j=0; j< alltags.length; j ) {
td = alltags[j];
if (td) {
td.innerHTML = td.innerHTML.replaceAll("<mark>","");
td.innerHTML = td.innerHTML.replaceAll("</mark>","");
txtValue = td.textContent || td.innerText;
index = txtValue.toUpperCase().indexOf(filter);
if (index > -1) {
td.innerHTML = txtValue.substring(-1, index) "<mark>" txtValue.substring(index, index filter.length) "</mark>" txtValue.substring(index filter.length);
tr[j].style.display = "";
j = alltags.length;
isFound = true;
}
}
}
if(!isFound && tr[i].className !== "header") {
// tr[i].style.display = "none";
}
}
}
<body>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<table id="myTable">
<tr >
<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>
</body>