Build a search filter with JavaScript

Subscribe to receive the free weekly article

In this tutorial, we are going to build a search filter with just JavaScript. It's a cool functionality that helps to filter a list without reloading the page.

Markup

For this quick post, I will use Taildwind CSS to not waste your time with styling.

So, we can now start with the HTML part. It's relatively simple.

  • In index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link
      href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css"
      rel="stylesheet"
    />
    <title>Filterable List</title>
  </head>

  <body class="antialiased font-sans bg-gray-200">
    <main class="container m-auto max-w-2xl mt-4 p-2 sm:px-8">
      <input
        type="search"
        id="search"
        placeholder="Filter users..."
        class="appearance-none border border-gray-400 border-b block pl-8 pr-6 py-2 w-full bg-white text-sm placeholder-gray-400 rounded-lg text-gray-700 focus:bg-white focus:placeholder-gray-600 focus:text-gray-700 focus:outline-none"
      />
      <div class="my-4 shadow rounded-lg overflow-hidden">
        <table class="items min-w-full leading-normal"></table>
      </div>
    </main>
    <script src="app.js"></script>
  </body>
</html>

Don't let the bunch of classes added by Tailwind CSS confusing you.

Here, there are two important things to retain:

  • The id search held on the input tag which will help us later get the value entered by the user and filter the list with it.
  • The class items held on the table tag which will be used later to append the data with JavaScript.

Now, let's move on and show the data.

Show data with JavaScript

For the data, I will use the github API to fetch users with their avatar, repositories, etc.

We start the JavaScript part by selecting items, and search. Then, we declare the users array which will as you might guess hold our users.

  • In app.js
const items = document.querySelector(".items")
const searchUser = document.querySelector("#search")
let users = []

const fetchImages = () => {
  fetch("https://api.github.com/users")
    .then(res => {
      res
        .json()
        .then(res => {
          users = res
          showUsers(users)
        })
        .catch(err => console.log(err))
    })
    .catch(err => console.log(err))
}

const showUsers = arr => {
  let output = ""

  arr.forEach(
    ({ login, avatar_url }) =>
      (output += `
<tr>
  <td class="py-2 pl-5 border-b border-gray-200 bg-white">
  <div class="flex items-center">
    <div class="flex-shrink-0 w-10 h-10">
      <img class="w-full h-full rounded-full" src=${avatar_url} />
    </div>
    <div class="ml-3">
      <h1 class="capitalize font-semibold text-base text-gray-900 whitespace-no-wrap">
      ${login}
      </h1>
    </div>
  </div>
  </td>
  <td class="py-2 text-center border-b border-gray-200 bg-white text-sm">
    <a class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-1 px-2 border border-blue-700 rounded" 
      href=https://github.com/${login}>See profile
    </a>
  </td>
</tr>
`)
  )
  items.innerHTML = output
}
document.addEventListener("DOMContentLoaded", fetchImages)

Then, we use the Fetch API to get the data and assign them to the variable users.

With that, we can now use the showUsers() function to display them on the screen.

An for the showUsers() method, we just loop through the array of data and show for each user the login and its avatar_url.

Now, the data are successfully displayed on the screen. But, we still can't use the search filter. So, let's make it filterable in the next section.

Make the list filterable

As you have seen earlier in this post, the function showUsers() helps us show the data. And that method will be used again when a change occurs on the search bar.

  • In app.js
searchUser.addEventListener("input", e => {
  const element = e.target.value.toLowerCase()
  const newUser = users.filter(user =>
    user.login.toLowerCase().includes(element)
  )

  showUsers(newUser)
})

And here, we use searchUser (it's the id of the input tag) to listen to the input event. That means, when the user enters something on the search bar, this function will be called.

Then, we store the value entered on element and transform it to lowercase, to well, be able to match users correctly.

And to filter the list, we check if the value entered matches an element of the array or not. Then, we pass the filtered array to display to showUsers().

And that's it, we have our search filter.

Thanks for reading it.

You can check it live here or find the source code here.