Issue
I'm not a programmer but attempting to create a simple academic website. I have a host of articles in a table and managed to use some javascript and select-html to create a filter that works from W3 Schools. I am attempting to add a second select-html filter to narrow results further, but seems that only the first list will work. I've tried to add additional ids to differentiate the two lists, but likely doing it wrong and not working.
What I would like to be able to do is use the first filter to keep all Author1 instances, and if you choose to use the second filter to narrow down to Category1, it will result in all Author1 and Category1 if any (in example above, just top row would remain).
function myFunction() {
var input, filter, table, tr, td, i;
input = document.getElementById("mylist");
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) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
<select id="mylist" onchange="myFunction()" class='form-control' style="max-width: 250px; min-width: 250px">
<option></option>
<option>Author1</option>
<option>Author2</option>
</select>
<select id="mylist" onchange="myFunction()" class='form-control' style="max-width: 250px; min-width: 250px">
<option></option>
<option>Category1</option>
<option>Category2</option>
</select>
<table id="myTable" height="100%" width="100%">
<tr>
<td>Author1, Category1</td>
</tr>
<tr>
<td>Author1, Category2</td>
</tr>
</table>
Solution
Here is a working version using
- addEventListener
- hidden
- map
It is possibly trickier than what you had hoped for, but it is using modern and recommended methods
const rows = document.querySelectorAll("#myTable tbody tr"); // all rows with data
document.getElementById("filter").addEventListener("change", function() { // any select change
const filters = [...this.querySelectorAll("select")].map(sel => sel.value); // make an array of values
rows.forEach(row => { // loop over all rows
const string = [...row.querySelectorAll("td")].map(td => td.textContent.trim()).join(" "); // join the cell content
const found = filters.every(filter => { // every filter is looked at
if (filter === "") return true; // it could be empty
return string.includes(filter); // if not return true if found
})
row.hidden = filters.join("") != "" && !found; // hide if something was selected and not found
})
})
<div id="filter">
<select class='form-control' style="max-width: 250px; min-width: 250px">
<option></option>
<option>Author1</option>
<option>Author2</option>
</select>
<select class='form-control' style="max-width: 250px; min-width: 250px">
<option></option>
<option>Category1</option>
<option>Category2</option>
</select>
</div>
<table id="myTable" height="100%" width="100%">
<tr>
<td>Author1, Category1</td>
</tr>
<tr>
<td>Author1, Category2</td>
</tr>
</table>
Multiple
const rows = document.querySelectorAll("#myTable tbody tr"); // all rows with data
document.getElementById("filter").addEventListener("change", function() { // any select change
const selected = document.querySelectorAll('select option:checked');
const filters = Array.from(selected).map(el => el.value); // make an array of values
rows.forEach(row => { // loop over all rows
const string = [...row.querySelectorAll("td")].map(td => td.textContent.trim()).join(" "); // join the cell content
const found = filters.some(filter => { // every filter is looked at
if (filter === "") return true; // it could be empty
return string.includes(filter); // if not return true if found
})
row.hidden = filters.join("") != "" && !found; // hide if something was selected and not found
})
})
<div id="filter">
<select class='form-control' style="max-width: 250px; min-width: 250px" multiple>
<option>Author1</option>
<option>Author2</option>
</select>
<select class='form-control' style="max-width: 250px; min-width: 250px" multiple>
<option>Category1</option>
<option>Category2</option>
</select>
</div>
<table id="myTable" height="100%" width="100%">
<tr><td>Author1</td></tr>
<tr><td>Author2</td></tr>
<tr><td>Author3, Category1</td></tr>
<tr><td>Category2</td></tr>
</table>
Answered By - mplungjan Answer Checked By - Willingham (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.