How to build a Filter/Search Table with HTML, CSS and JavaScript

How to build a Filter/Search Table with HTML, CSS and JavaScript

Filter table data effortlessly by typing a name in the search box

Hi friends 👋, Today we’re going to learn how to create a search filter inside a table with JavaScript. If you've ever used a search filter before, you know that it's a tool that you can use to filter or find specific data in a table by typing a value in a search box like a name, number, or some other value.

In this article we will be creating a table with a list of names and countries. When you type in a name in the search box, the table will filter the data and display the name you typed. Let's get started.

The first thing we need to do is create our HTML table.

Step 1: Create the search box

<i class="lni lni-search"></i><input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">

Step 2: Create the HTML table

<table id="myTable">
  <tr class="header">
    <th style="width:60%;">Name</th>
    <th style="width:40%;">Country</th>
  </tr>
  <tr>
    <td>Anthony Smith</td>
    <td>United States</td>
  </tr>
  <tr>
    <td>John Jefferson</td>
    <td>Sweden</td>
  </tr>
  <tr>
    <td>Judith Paltro</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Ronald Smith</td>
    <td>London</td>
  </tr>
</table>

Next, we need to style our table by adding our CSS. This will give our table some presentational upgrades.

Step 3: Add CSS


body {
  padding-right: 20%;
  padding-left: 20%;
}

tr:nth-child(even) {
  background-color: #dddddd;
}

.lni-search {
    position: relative;
    top: 33px;
    left: 15px;
}

#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;
}

Finally, we need to make our table interactive by adding our JavaScript.

Step 4: Add JavaScript

<script>
function myFunction() {
  // First, we need to declare our variables
  var input, filter, table, tr, td, i, txtValue;
  input = document.getElementById("myInput");
  filter = input.value.toUpperCase();
  table = document.getElementById("myTable");
  tr = table.getElementsByTagName("tr");

  // Then, we need to 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) {
      txtValue = td.textContent || td.innerText;
      if (txtValue.toUpperCase().indexOf(filter) > -1) {
        tr[i].style.display = "";
      } else {
        tr[i].style.display = "none";
      }
    }
  }
}
</script>

Your table should now be filtered by typing a value in the search box.

table.png

When typing a value in the search box, the table will filter by the value you type. I'm using the textContent property to get the text. I'm going to type Anthony in the search box and the table will filter to show only the rows with Anthony in the name column.

table-search.png

Step 5: Full Code

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.lineicons.com/3.0/lineicons.css" rel="stylesheet">
<style>
* {
  box-sizing: border-box;
}

body {
  padding-right: 20%;
  padding-left: 20%;
}

tr:nth-child(even) {
  background-color: #dddddd;
}

.lni-search {
    position: relative;
    top: 33px;
    left: 15px;
}

#myInput {
  background-image: url('');
  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>

<i class="lni lni-search"></i><input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">

<table id="myTable">
  <tr class="header">
    <th style="width:60%;">Name</th>
    <th style="width:40%;">Country</th>
  </tr>
  <tr>
    <td>Anthony Smith</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>John Jefferson</td>
    <td>Sweden</td>
  </tr>
  <tr>
    <td>Judith Paltro</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Ronald Smith</td>
    <td>United States</td>
  </tr>
  <tr>
    <td>Jeffrey Donald</td>
    <td>Mexico</td>
  </tr>
  <tr>
    <td>Timmy Smith</td>
    <td>United States</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>

Did you find this article valuable?

Support Tony's Tech Blog by becoming a sponsor. Any amount is appreciated!