DEV Community

Cover image for Vanilla JavaScript live search
Chris Bongers
Chris Bongers

Posted on • Originally published at daily-dev-tips.com

Vanilla JavaScript live search

Today we will be working on a more real-world scenario, a live search!

In our example, we will be using an array of names and countries. We will then have a search bar; on input, it goes and filters the array to showcase only matching results.

The result you can find on this Codepen, try and search for something (e.g. Japan or Abel)

HTML Structure

<h1>JavaScript live search</h1>
<input autocomplete="off" type="search" id="search" placeholder="Search for a country or name!" />
<ul id="results"></ul>
Enter fullscreen mode Exit fullscreen mode

In today's article we are more focussed on the JavaScript part than actual the HTML structure or styling, so a very basic setup.

We use an input field where we will base the results on.
And define an empty <UL> with the ID results

CSS to make it pretty

As for the CSS, we add some basic styling to make it all centered with Flex, and look a little bit nicer.

body {
  display: flex;
  min-height: 100vh;
  align-items: center;
    font-family: Roboto,"Helvetica Neue",Arial,sans-serif;
  flex-direction: column;
}
input {
  width: 250px;
  text-align: center;
}
ul {
  list-style: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0;
}
Enter fullscreen mode Exit fullscreen mode

JavaScript live search

Now on to the magic part, in this example, I prepared a random array of data consisting of the following structure:

const data = [
  { name: "Ryan", country: "Saint Lucia" },
  // 99 more
];
Enter fullscreen mode Exit fullscreen mode

Then we need to define our variables we are going to use.

const search = document.getElementById("search");
const results = document.getElementById("results");
let search_term = "";
Enter fullscreen mode Exit fullscreen mode

Where search is out input element, results is our ul list, and the search_term is whatever we input in our search field.

Now let's create a function to capture the search input.

search.addEventListener("input", (event) => {
  search_term = event.target.value.toLowerCase();
  showList();
});
Enter fullscreen mode Exit fullscreen mode

Here we add an input listener to our search and capture the value (in lowercase), then we call a function called showList which we will build now.

const showList = () => {

};
Enter fullscreen mode Exit fullscreen mode

In there we start with clearing whatever is in the list already.

const showList = () => {
  results.innerHTML = "";
};
Enter fullscreen mode Exit fullscreen mode

Now we want to loop over all our data elements

data
    .filter((item) => {
      // todo
    });
Enter fullscreen mode Exit fullscreen mode

We make use of the filter ES6 function.

In there we want to check if either the name or the country matches our search string.

data
    .filter((item) => {
      return (
        item.country.toLowerCase().includes(search_term) ||
        item.name.toLowerCase().includes(search_term)
      );
    })
Enter fullscreen mode Exit fullscreen mode

As you can see we match either on country OR (||) on the name.
What we do is in the filter we get a single item from our array.
We then check if the value in lowercase matches (includes) our search string.

If so we return this, remember that filter will then modify on it's own.

The last step is then too append a new list item to our ul.

data
    .filter((item) => {
      return (
        item.country.toLowerCase().includes(search_term) ||
        item.name.toLowerCase().includes(search_term)
      );
    })
    .forEach((e) => {
      const li = document.createElement("li");
      li.innerHTML = `<i>Name:</i> ${e.name}  || <i>Country:</i> ${e.country}`;
      results.appendChild(li);
    });
Enter fullscreen mode Exit fullscreen mode

There you go! All that's left is initially call the method.
Place the following at the bottom of your scripts.

showList();
Enter fullscreen mode Exit fullscreen mode

Thank you for reading, and let's connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Top comments (2)

Collapse
 
stexx profile image
Stefan Breitenstein

Hi, nice little example :)
Instead of the forEach loop you could use a map function, so that you don't need the results closure.

const showList = () => {
    results.innerHTML = "";

    const newElements = data
    .filter((item) => {
      return (
        item.country.toLowerCase().includes(search_term) ||
        item.name.toLowerCase().includes(search_term)
      );
    })
    .map((e) => {
      const li = document.createElement("li");
      li.innerHTML = `<i>Name:</i> ${e.name}  || <i>Country:</i> ${e.country}`;
       return li;
    });
  results.append(...newElements);
};
Enter fullscreen mode Exit fullscreen mode
Collapse
 
dailydevtips1 profile image
Chris Bongers

Ah your right, missed that part, thanks for the addition! πŸ’œ