PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Wednesday, August 3, 2022

[FIXED] How to use multiple filter lists (html-select) on one table to narrow down results without the conflicting?

 August 03, 2022     html-select, html-table, javascript     No comments   

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)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

1,208,723

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © 2025 PHPFixing