1

I am working with tables, I want to perform search by match in all columns. Following code only matches first column data of the table. But I want it should search by all column data. If you have any idea how I can do this, please share with me. Thanks in Advance!

JsFiddle: https://jsfiddle.net/hbrjy04m/

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* {
  box-sizing: border-box;
}

#myInput {
  background-image: url('/css/searchicon.png');
  background-position: 10px 10px;
  background-repeat: no-repeat;
  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 tr {
  border-bottom: 1px solid #ddd;
}

#myTable tr.header, #myTable tr:hover {
  background-color: #f1f1f1;
}
</style>
</head>
<body>

<h2>My Customers</h2>

<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">

    <table id="myTable">
      <tr class="header">
        <th style="width:60%;">Name</th>
        <th style="width:40%;">Country</th>
      </tr>
      <tr>
        <td>Alfreds Futterkiste</td>
        <td>Germany</td>
      </tr>
      <tr>
        <td>Berglunds snabbkop</td>
        <td>Sweden</td>
      </tr>
      <tr>
        <td>Island Trading</td>
        <td>UK</td>
      </tr>
      <tr>
        <td>Koniglich Essen</td>
        <td>Germany</td>
      </tr>
      <tr>
        <td><a href="https://teluguhitflopmovieslist.blogspot.com/">Laughing Bacchus Winecellars</a></td>
        <td>Canada</td>
      </tr>
      <tr>
        <td>Magazzini Alimentari Riuniti</td>
        <td>Italy</td>
      </tr>
      <tr>
        <td>North/South</td>
        <td><a href="https://lyricxona.blogspot.com/">UK</a></td>
      </tr>
      <tr>
        <td>Paris specialites</td>
        <td><a href="https://castxona.blogspot.com/">France</a></td>
      </tr>
    </table>
    
    <script>
    function myFunction() {
      var input, filter, table, tr, td, i, txtValue;
      input = document.getElementById("myInput");
      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) {
          txtValue = td.textContent || td.innerText;
          if (txtValue.toUpperCase().indexOf(filter) > -1) {
            tr[i].style.display = "";
          } else {
            tr[i].style.display = "none";
          }
        }       
      }
    }
    </script>
    
    </body>
    </html>
1
  • Also, take a look at my updated answer Commented Jun 28, 2020 at 11:09

5 Answers 5

3

const search = document.querySelector("input[name=search]");
const table = document.querySelector("#myTable");
const rows = table.querySelectorAll("tr");

search.addEventListener("input", () => {
  rows.forEach(row => {
    const matches = row.textContent
      .toLowerCase()
      .includes(search.value.toLowerCase())

    matches ? row.classList.remove("hide") : row.classList.add("hide");
  });
});
* {
  box-sizing: border-box;
}

.hide {
  display: none !important;
}

input[name=search] {
  background-image: url('/css/searchicon.png');
  background-position: 10px 10px;
  background-repeat: no-repeat;
  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 tr {
  border-bottom: 1px solid #ddd;
}

#myTable tr.header,
#myTable tr:hover {
  background-color: #f1f1f1;
}
<h2>My Customers</h2>

<input type="text" name="search" placeholder="Search for names.." title="Type in a name">

<table id="myTable">
  <thead>
    <tr class="header">
      <th style="width:60%;">Name</th>
      <th style="width:40%;">Country</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Alfreds Futterkiste</td>
      <td>Germany</td>
    </tr>
    <tr>
      <td>Berglunds snabbkop</td>
      <td>Sweden</td>
    </tr>
    <tr>
      <td>Island Trading</td>
      <td>UK</td>
    </tr>
    <tr>
      <td>Koniglich Essen</td>
      <td>Germany</td>
    </tr>
    <tr>
      <td><a href="https://teluguhitflopmovieslist.blogspot.com/">Laughing Bacchus Winecellars</a></td>
      <td>Canada</td>
    </tr>
    <tr>
      <td>Magazzini Alimentari Riuniti</td>
      <td>Italy</td>
    </tr>
    <tr>
      <td>North/South</td>
      <td><a href="https://lyricxona.blogspot.com/">UK</a></td>
    </tr>
    <tr>
      <td>Paris specialites</td>
      <td>France</td>
    </tr>
  </tbody>
</table>

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

Comments

2

You can use a for loop to loop through all the tds in a tr and search the combined text.

function myFunction() {
  var input, filter, table, tr, td, i, txtValue;
  input = document.getElementById("myInput");
  filter = input.value.toUpperCase();
  table = document.getElementById("myTable");
  tr = table.getElementsByTagName("tr");
  for (i = 0; i < tr.length; i++) {
    const tableData = tr[i].getElementsByTagName("td");
    let allTextContent = '';
    for (let ind = 0; ind < tableData.length; ind++) {
        allTextContent += tableData[ind].innerText;
    }
    
    if (allTextContent) {
      if (allTextContent.toUpperCase().indexOf(filter) > -1) {
        tr[i].style.display = "";
      } else {
        tr[i].style.display = "none";
      }
    }       
  }
}

Although you can avoid the additional loop and search the entire textContent of a row instead. A few things can be refactored too.

Updated fiddle.

const searchInput = document.querySelector('#myInput');
const tableRows = document.querySelector('#myTable').querySelectorAll('tr');

searchInput.addEventListener('input', (e) => {
  const searchInputValue = e.target.value.toLowerCase();
  tableRows.forEach(row => {
    const doesRowMatch = row.textContent.toLowerCase().includes(searchInputValue);
    if (doesRowMatch) {
      row.style.display = 'table-row';
    } else {
      row.style.display = 'none';
    }
  })
})

Comments

0

This should work even if you increase the number of columns

Basically, you traverse all TD inside TR and if you find one match, you go to the next row.

function myFunction() {
  var input, filter, table, tr, td, i, txtValue;
  input = document.getElementById("myInput");
  filter = input.value.toUpperCase();
  table = document.getElementById("myTable");
  tr = table.getElementsByTagName("tr");
  for (i = 0; i < tr.length; i++) {
    tds = tr[i].getElementsByTagName("td")
    var foundInRow = false
    for(j=0; j<tds.length; j++){
    if(foundInRow)
        continue
    td = tr[i].getElementsByTagName("td")[j];
    if (td) {
      txtValue = td.textContent || td.innerText;
      if (txtValue.toUpperCase().indexOf(filter) > -1) {
        foundInRow = true
        tr[i].style.display = "";
      } else {
        tr[i].style.display = "none";
      }
    }      
    }
  }
}

Comments

0
function myFunction() {
 var input, filter, table, tr, td, i, txtValue;
 input = document.getElementById("myInput");
 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) {
     txtValue = td.textContent || td.innerText;
     if (txtValue.toUpperCase().indexOf(filter) > -1) {
       tr[i].style.display = "";
       i++;
     } else {
       tr[i].style.display = "none";
     }
   }  
   td = tr[i].getElementsByTagName("td")[1];
   if (td) {
     txtValue = td.textContent || td.innerText;
     if (txtValue.toUpperCase().indexOf(filter) > -1) {
       tr[i].style.display = "";
     } else {
       tr[i].style.display = "none";
     }
   }       
 }
}

https://jsfiddle.net/cjb1rx6f/1/

This works, but the other answers are better...

Comments

0

The issue in your code seems to be because of this tr[i].getElementsByTagName("td")[0];. Instead iterate the tr and get the text content from each of the td. Check if the user input is included in the string. Then show the tr else hide it

function myFunction() {
  // get user input
  const userInput = document.getElementById("myInput").value.trim().toUpperCase();
  
  document.querySelectorAll('tr').forEach((item) => {
    const tdTxt = [...item.querySelectorAll('td')].map(elem => elem.textContent.trim().toUpperCase()).join(',');

    if (tdTxt.indexOf(userInput) === -1) {
      item.style.display = "none"
    } else {
      item.style.display = "";
    }

  })
}
* {
  box-sizing: border-box;
}

#myInput {
  background-image: url('/css/searchicon.png');
  background-position: 10px 10px;
  background-repeat: no-repeat;
  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 tr {
  border-bottom: 1px solid #ddd;
}

#myTable tr.header,
#myTable tr:hover {
  background-color: #f1f1f1;
}
<h2>My Customers</h2>

<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">

<table id="myTable">
  <thead class="header">
    <th style="width:60%;">Name</th>
    <th style="width:40%;">Country</th>
  </thead>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Berglunds snabbkop</td>
    <td>Sweden</td>
  </tr>
  <tr>
    <td>Island Trading</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Koniglich Essen</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td><a href="https://teluguhitflopmovieslist.blogspot.com/">Laughing Bacchus Winecellars</a></td>
    <td>Canada</td>
  </tr>
  <tr>
    <td>Magazzini Alimentari Riuniti</td>
    <td>Italy</td>
  </tr>
  <tr>
    <td>North/South</td>
    <td><a href="https://lyricxona.blogspot.com/">UK</a></td>
  </tr>
  <tr>
    <td>Paris specialites</td>
    <td><a href="https://castxona.blogspot.com/">France</a></td>
  </tr>
</table>

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.