I am trying to make a filter/search table and I am using the JavaScript from this site.
Here's the script:
function myFunction() {
// Declare variables
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
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";
}
}
}
}
You can change which column to be used as the filter by changing the index in "td = tr[i].getElementsByTagName("td")[0];"
0 means the first column will be used, 1 means the second column, etc.
Using the same script, how can I use multiple columns to be the filter?
EDIT:
This is the tableinside my 'exampletable.php':
<input type="text" id="myInput" onKeyUp="myFunction()" placeholder="Search"
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
<?php
include 'connection.php'; //to connect to my database, "database"
$data = mysqli_query($con, "SELECT*FROM database;");
while($d = mysqli_fetch_array($data)){
?>
<table class="table table-bordered" id="myTable" width="100%" cellspacing="0">
<thead>
<tr>
<th class="text-center">Name</th>
<th class="text-center">Age</th>
<th class="text-center">Hobby</th>
</tr>
</thead>
<tr>
<td class="text-center"><?php echo $d['name']; ?></td>
<td><?php echo $d['age']; ?></td>
<td><?php echo $d['hobby']; ?></td>
</tr>
</table>
<?php } ?>
As you can see, I have the column "Name, Age, and Hobby" using the function inside the JavaScript, if the index is 0 (the index for the filter column) then the first column (Name) will be used as the filter.
For example, when I type "Catherine" in the search bar, then the page will only show the data with "Catherine" inside the Name column.
What I wanted to do is to use say both Name and Hobby column as the filter. So, say when I type "Cat" in the search bar, then the page will only show the data with "Cat" inside the Name and also Hobby column.
CodePudding user response:
Adding another for loop to evaluate all tds (columns) will help you with that.
This might be helpful:
// This variable switch if the filter catch any result
var isset = false;
//This loop evalaute all rows
for (i = 0; i < tr.length; i ) {
//Here we search for all columns in this row
//note that we get rid of [0] at the end because we're looking for all
//tds, not just the first one
let tds = tr[i].getElementsByTagName("td");
//Here we evaluate each column for this row
for (let td of tds) {
//If td has a value
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
//If the filter catch any result, we show the row
isset = true;
}
}
}
//The decision of show or hide the row is made here because
//the loop has to evaluate all columns before decide if show or hide the entire row
if (isset) {
//If the filter catch any result, we show the row
tr[i].style.display = "";
} else {
//If the filter catch no result, we hide the row
tr[i].style.display = "none";
}
//This is to reset the variable for the next loop
isset = false;
}
Your entire function will be something like this:
function myFunction() {
// Declare variables
var input, filter, table, tr, td, i, txtValue;
// This variable switch if the filter catch any result
var isset = false;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// This variable switch if the filter catch any result
var isset = false;
//This loop evalaute all rows
for (i = 0; i < tr.length; i ) {
//Here we search for all columns in this row
//note that we get rid of [0] at the end because we're looking for all
//tds, not just the first one
let tds = tr[i].getElementsByTagName("td");
//Here we evaluate each column for this row
for (let td of tds) {
//If td has a value
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
//If the filter catch any result, we show the row
isset = true;
}
}
}
//The decision of show or hide the row is made here because
//the loop has to evaluate all columns before decide if show or hide the entire row
if (isset) {
//If the filter catch any result, we show the row
tr[i].style.display = "";
} else {
//If the filter catch no result, we hide the row
tr[i].style.display = "none";
}
//This is to reset the variable for the next loop
isset = false;
}
}
I have tested the code with this script
<input type="text" id="myInput" onKeyUp="myFunction()" placeholder="Search">
<table class="table table-bordered" width="100%" cellspacing="0">
<thead>
<tr>
<th class="text-center">Name</th>
<th class="text-center">Age</th>
<th class="text-center">Hobby</th>
</tr>
</thead>
<tbody id="myTable">
<tr>
<td class="text-center">Alejandro</td>
<td>12</td>
<td>Football</td>
</tr>
<tr>
<td class="text-center">Peralta</td>
<td>12</td>
<td>Alejandro</td>
</tr>
<tr>
<td class="text-center">Casemiro</td>
<td>12</td>
<td>Soccer</td>
</tr>
<tr>
<td class="text-center">Moreno</td>
<td>12</td>
<td>Tenis</td>
</tr>
<tr>
<td class="text-center">Alejandro</td>
<td>12</td>
<td>Moreno</td>
</tr>
</tbody>
</table>
<script>
function myFunction() {
// Declare variables
var input, filter, table, tr, td, i, txtValue;
// This variable switch if the filter catch any result
var isset = false;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// This variable switch if the filter catch any result
var isset = false;
//This loop evalaute all rows
for (i = 0; i < tr.length; i ) {
//Here we search for all columns in this row
//note that we get rid of [0] at the end because we're looking for all
//tds, not just the first one
let tds = tr[i].getElementsByTagName("td");
//Here we evaluate each column for this row
for (let td of tds) {
//If td has a value
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
//If the filter catch any result, we show the row
isset = true;
}
}
}
//The decision of show or hide the row is made here because
//the loop has to evaluate all columns before decide if show or hide the entire row
if (isset) {
//If the filter catch any result, we show the row
tr[i].style.display = "";
} else {
//If the filter catch no result, we hide the row
tr[i].style.display = "none";
}
//This is to reset the variable for the next loop
isset = false;
}
}
</script>