7

I am trying to figure out how to make all 5 columns and rows searchable. At the moment it only searches via the first column (DATE). Could someone please assist me with possibly making it search all the columns and rows please? I have included the HTML, CSS and javascript to try to provide as much information as possible.

function myFunction() {
  // Declare variables 
  var input, filter, table, tr, td, i;
  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) {
      if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
        tr[i].style.display = "";
      } else {
        tr[i].style.display = "none";
      }
    } 
  }
}
#myInput {
    background-image: url('/css/searchicon.png'); /* Add a search icon to input */
    background-position: 10px 12px; /* Position the search icon */
    background-repeat: no-repeat; /* Do not repeat the icon image */
    width: 100%; /* Full-width */
    font-size: 16px; /* Increase font-size */
    padding: 12px 20px 12px 40px; /* Add some padding */
    border: 1px solid #ddd; /* Add a grey border */
    margin-bottom: 12px; /* Add some space below the input */
}

#myTable {
    border-collapse: collapse; /* Collapse borders */
    width: 100%; /* Full-width */
    border: 1px solid #ddd; /* Add a grey border */
    font-size: 18px; /* Increase font-size */
}

#myTable th, #myTable td {
    text-align: left; /* Left-align text */
    padding: 12px; /* Add padding */
}

#myTable tr {
    /* Add a bottom border to all table rows */
    border-bottom: 1px solid #ddd; 
}

#myTable tr.header, #myTable tr:hover {
    /* Add a grey background color to the table header and on hover */
    background-color: #f1f1f1;
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">

<table id="myTable">
  <tr class="header">
    <th style="width:20%;">Date</th>
    <th style="width:20%;">Home</th>
    <th style="width:20%;">Time</th>
    <th style="width:20%;">Away</th>
    <th style="width:20%;">City</th>
    
  </tr>
  <tr>
    <td>08/01/2018</td>
    <td>SPAIN</td>
    <td>16:30 ET</td>
    <td>USA</td>
    <td>BARCELONA</td>
  </tr>
    <tr>
    <td>08/02/2018</td>
    <td>BOLIVIA</td>
    <td>18:30 ET</td>
    <td>PORTUAL</td>
    <td>MADRID</td>
  </tr>
      <tr>
    <td>08/03/2018</td>
    <td>PUERTO RICO</td>
    <td>18:30 ET</td>
    <td>CANADA</td>
    <td>CHICAGO</td>
  </tr>
      <tr>
    <td>08/04/2018</td>
    <td>MEXICO</td>
    <td>19:30 ET</td>
    <td>ENGLAND</td>
    <td>LONDON</td>
  </tr>
</table>

1
  • 1
    I believe you mean "Javascript", not "Java". They're completely different languages. 🖖🏻 Commented Jan 4, 2018 at 20:31

4 Answers 4

15

Using your existing code, loop through the table cells just as you loop through the table rows.

Below, I hide each row. For each row, if text in a cell matches the search term, that row is shown and the loop continues to the next row.

I'm also ignoring the table header by using tBodies to limit the search to <tr> elements that are within the first <tbody>. Alternatively, you could check that <td> elements exist in the row before searching; something like: if (tds.length) > 0.

function performSearch() {

  // Declare search string 
  var filter = searchBox.value.toUpperCase();

  // Loop through first tbody's rows
  for (var rowI = 0; rowI < trs.length; rowI++) {

    // define the row's cells
    var tds = trs[rowI].getElementsByTagName("td");

    // hide the row
    trs[rowI].style.display = "none";

    // loop through row cells
    for (var cellI = 0; cellI < tds.length; cellI++) {

      // if there's a match
      if (tds[cellI].innerHTML.toUpperCase().indexOf(filter) > -1) {

        // show the row
        trs[rowI].style.display = "";

        // skip to the next row
        continue;

      }
    }
  }

}

// declare elements
const searchBox = document.getElementById('searchBox');
const table = document.getElementById("myTable");
const trs = table.tBodies[0].getElementsByTagName("tr");

// add event listener to search box
searchBox.addEventListener('keyup', performSearch);
#searchBox {
  box-sizing: border-box;
  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 th {
  width: 20%;
}

#myTable tr {
  border-bottom: 1px solid #ddd;
}

#myTable tr.header,
#myTable tr:hover {
  background-color: #f1f1f1;
}
<input type="text" id="searchBox" placeholder="Search for names..">

<table id="myTable">
  <thead>
    <tr class="header">
      <th>Date</th>
      <th>Home</th>
      <th>Time</th>
      <th>Away</th>
      <th>City</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>08/01/2018</td>
      <td>SPAIN</td>
      <td>16:30 ET</td>
      <td>USA</td>
      <td>BARCELONA</td>
    </tr>
    <tr>
      <td>08/02/2018</td>
      <td>BOLIVIA</td>
      <td>18:30 ET</td>
      <td>PORTUAL</td>
      <td>MADRID</td>
    </tr>
    <tr>
      <td>08/03/2018</td>
      <td>PUERTO RICO</td>
      <td>18:30 ET</td>
      <td>CANADA</td>
      <td>CHICAGO</td>
    </tr>
    <tr>
      <td>08/04/2018</td>
      <td>MEXICO</td>
      <td>19:30 ET</td>
      <td>ENGLAND</td>
      <td>LONDON</td>
    </tr>
  </tbody>
</table>

Sign up to request clarification or add additional context in comments.

Comments

2

100% working for unlimited columns !

<input class="form-control" type="text" id="myInput" placeholder="Search ..." onkeyup="searchTableColumns()">

<table id="myTable">
     .....
     .....
     .....
</table
function searchTableColumns() {
      // Declare variables 
      var input, filter, table, tr, i, j, column_length, count_td;
      column_length = document.getElementById('myTable').rows[0].cells.length;
      input = document.getElementById("myInput");
      filter = input.value.toUpperCase();
      table = document.getElementById("myTable");
      tr = table.getElementsByTagName("tr");
      for (i = 1; i < tr.length; i++) { // except first(heading) row
        count_td = 0;
        for(j = 1; j < column_length-1; j++){ // except first column
            td = tr[i].getElementsByTagName("td")[j];
            /* ADD columns here that you want you to filter to be used on */
            if (td) {
              if ( td.innerHTML.toUpperCase().indexOf(filter) > -1)  {            
                count_td++;
              }
            }
        }
        if(count_td > 0){
            tr[i].style.display = "";
        } else {
            tr[i].style.display = "none";
        }
      }
      
    }

Comments

1

When you do tr[i].getElementsByTagName("td")[0];, you only select the date column, wich is why it only search in that one. You are going to have to loop through all the coumn and set a boolean to true if you find it at least once.

Something like that:

var found = false;
var td = tr[i].getElementsByTagName("td");
for(j = 0; j < td.length; j++) {
    if (td[j].innerHTML.toUpperCase().indexOf(filter) > -1) {
        //if found at least once it is set to true
        found = true;
    }
}
//only hides or shows it after checking all columns
if(found){
    tr[i].style.display = "";
} else {
    tr[i].style.display = "none";
}

1 Comment

Thank you for your rapid response it now works as planned. Thank you.
0

a compact version of the above code, credit to #showdev

/**
 * HTML Search for any table
 * 
 * @param element searchBox
 * @param string tableBody
 */
function performSearch(searchBox,tableBody) {
    let trs = $('#'+tableBody).find('tr');
    // Declare search string 
    let filter = searchBox.value.toUpperCase();
    // Loop through first tbody's rows
    for (let rowI = 0; rowI < trs.length; rowI++) {
        // define the row's cells
        let tds = trs[rowI].getElementsByTagName("td");
        // hide the row
        trs[rowI].style.display = "none";

        // loop through row cells
        for (let cellI = 0; cellI < tds.length; cellI++) {
            // if there's a match
            if (tds[cellI].innerHTML.toUpperCase().indexOf(filter) > -1) {
                // show the row
                trs[rowI].style.display = "";
                // skip to the next row
                continue;
            }
        }
    }
}

Use it like onkeyup="performSearch(this,'smsTableBody')"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.