Hi i have a search filter in my application. I would like to optimize this code, because it has too much lines of code. How change it so,it will work the same but with less code?
function myFunction() {
var input, filter, table, tr, th, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
th = tr[i].getElementsByTagName("th")[0]; // for column one
th1 = tr[i].getElementsByTagName("th")[1];
th2 = tr[i].getElementsByTagName("th")[2];
th3 = tr[i].getElementsByTagName("th")[3];
th4 = tr[i].getElementsByTagName("th")[4];
th5 = tr[i].getElementsByTagName("th")[5];
th6 = tr[i].getElementsByTagName("th")[6];
th7 = tr[i].getElementsByTagName("th")[7];
th8 = tr[i].getElementsByTagName("th")[8];
th9 = tr[i].getElementsByTagName("th")[9];// for column two
/* columns for search*/
if (th) {
if ( (th.innerHTML.toUpperCase().indexOf(filter) > -1) || (th1.innerHTML.toUpperCase().indexOf(filter) > -1) || (th2.innerHTML.toUpperCase().indexOf(filter) > -1) || (th3.innerHTML.toUpperCase().indexOf(filter) > -1) || (th4.innerHTML.toUpperCase().indexOf(filter) > -1) || (th5.innerHTML.toUpperCase().indexOf(filter) > -1) || (th6.innerHTML.toUpperCase().indexOf(filter) > -1) || (th7.innerHTML.toUpperCase().indexOf(filter) > -1) || (th8.innerHTML.toUpperCase().indexOf(filter) > -1) || (th9.innerHTML.toUpperCase().indexOf(filter) > -1) ) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
Using hidden and find will be much shorter
I use find instead of some for semantic reasons.
document.getElementById("myInput").addEventListener("input", function() {
const filter = this.value.toUpperCase();
const trs = document.querySelectorAll("#MyTable tbody tr")
trs.forEach(tr => {
const hide = filter &&
![...tr.querySelectorAll("th")] // none of the cells
.find(th => th.textContent.toUpperCase().includes(filter));// contains filter
tr.hidden = hide;
})
})
Example
document.getElementById("myInput").addEventListener("input", function() {
const filter = this.value.toUpperCase();
const trs = document.querySelectorAll("#myTable tbody tr")
trs.forEach(tr => {
const hide = filter && ![...tr.querySelectorAll("td")].find(td => td.textContent.toUpperCase().includes(filter))
tr.hidden = hide;
})
})
* {
box-sizing: border-box;
}
#myInput {
background-image: url('/css/searchicon.png');
background-position: 10px 10px;
background-repeat: no-repeat;
width: 100%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
}
#myTable {
border-collapse: collapse;
width: 100%;
border: 1px solid #ddd;
font-size: 18px;
}
#myTable th,
#myTable td {
text-align: left;
padding: 12px;
}
#myTable tr {
border-bottom: 1px solid #ddd;
}
#myTable tr.header,
#myTable tr:hover {
background-color: #f1f1f1;
}
<input type="text" id="myInput" placeholder="Filter" title="Filter text" autocomplete="off" />
<table id="myTable">
<thead>
<tr class="header">
<th>Id</th>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>One</td>
<td>Two</td>
<td>Three</td>
<td>Four</td>
</tr>
<tr>
<td>2</td>
<td>Five</td>
<td>Six</td>
<td>Seven</td>
<td>Eight</td>
</tr>
<tr>
<td>3</td>
<td>Nine</td>
<td>Ten</td>
<td>Eleven</td>
<td>Twelve</td>
</tr>
</tbody>
</table>
You can also search in table by this way:
//search input id
$("#search").on("keyup", function() {
var value = $(this).val().toLowerCase();
//tableStudentbody table id
$("#tableStudentbody tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});