HTML Scrupt/Function assistance

Soldato
Joined
30 Dec 2004
Posts
4,681
Location
Bromley, Kent
Hi all

Looking for a bit of help here. I have a PHP page that outputs an SQL query to a table dynamically. Within the page is a search box that allows me to dynamically filter the first column in the table - all this is working great, however, ideally I'd like to use the single search box to search each column simultaneously and display matching rows, regardless of column. I can amend the script to search on a column independently but not multiple columns at the same time. So the questions is, can this be done?

HTML:
<script>
function myFunction() {
  var input, filter, table, tr, td, i, txtValue;
  input = document.getElementById("searchquery");
  filter = input.value.toUpperCase();
  table = document.getElementById("reportslist");
  tr = table.getElementsByTagName("tr");
  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";
      }
    }
  }
}
</script>


The other problem is that I have another function that orders the table depending on whatever column is selected. Again this works perfectly fine but struggles when a few hundred+ results are in the table, likley because its massively inefficient! Is there an alternative available?

HTML:
<script>
function sortTable(n) {
  var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
  table = document.getElementById("reportslist");
  switching = true;
  dir = "asc";
  while (switching) {
    switching = false;
    rows = table.rows;
    for (i = 1; i < (rows.length - 1); i++) {
      shouldSwitch = false;
      x = rows[i].getElementsByTagName("TD")[n];
      y = rows[i + 1].getElementsByTagName("TD")[n];
      if (dir == "asc") {
        if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
          shouldSwitch= true;
          break;
        }
      } else if (dir == "desc") {
        if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
          shouldSwitch = true;
          break;
        }
      }
    }
    if (shouldSwitch) {
      rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
      switching = true;
      switchcount ++;
    } else {
      if (switchcount == 0 && dir == "asc") {
        dir = "desc";
        switching = true;
      }
    }
  }
}
</script>

I'm a network guy by trade so dev work is outside of my normal scope, most of this code has been pulled from stack overflow or w3c school and butchered.

- GP
 
Last edited:
If you just want something functional, I'd recommend using the datatables plugin which does everything you want:
https://datatables.net/

If it's a project to help you learn, then you can edit the code to search over multiple columns like this:
Code:
<script>
function myFunction() {
  var input, filter, table, tr, td, i, txtValue;
  input = document.getElementById("searchquery");
  filter = input.value.toUpperCase();
  table = document.getElementById("reportslist");
  tr = table.getElementsByTagName("tr");
  for (i = 0; i < tr.length; i++) {
    td = tr[i].getElementsByTagName("td");
    for (z = 0; z < td.length; z++) {
      txtValue = td[z].textContent || td[z].innerText;
      if (txtValue.toUpperCase().indexOf(filter) > -1) {
        tr[i].style.display = "";
      } else {
        tr[i].style.display = "none";
      }
    }
  }
}
</script>

I've added another for loop inside the original to check through each column.
 
I always like (when learning) to write the code out as english.

Here is your original


Get the search query
Get the table
Get the rows belonging to the table
For every row
Get the first cell in this row
Check if its contents match the search query
If they do not match, hide the cell​

Solution as provided above

Get the search query
Get the table
Get the rows belonging to the table
For every row
Get the cells belonging to that row
For every cell

Check if its contents match the search query
If they do not match, hide the cell​
 
Back
Top Bottom