How to Build a JavaScript Search

Being able to search and/or filter through your website’s data is a great feature to implement for your users and setting it up isn’t as hard as you may think. It just requires a little bit of JavaScript. Today, I have a website that hosts many authors and we’ll walk through adding a feature to this page that will allow us to find authors based on our search query. So if you’re ready to follow along, lets get started!

You can find the GitHub repository associated with this project below:

https://github.com/treehouse/javascript-search
Make sure to download/clone the project to your machine to start following along.

HTML Input Element

The first thing we’ll want to do is locate our input element that we’ll use to search/filter authors. If you’re following along with me, you’ll see this input on line 14 of the index.html file.

<input type="text" id="authorSearch" class="author-search">

You’ll notice this input element contains an id of authorSearch. We can use this in our JavaScript to reference it.

JavaScript

Go ahead and create a new JavaScript file and link it in your HTML file. The first thing we should do is declare a variable for our search input:

const authorSearch = document.getElementById('authorSearch');

Next, we’ll want to run an event listener on this input. We want to run some logic everytime a letter is typed in this field. We can do this by using the keyup event listener on our authorSearch. We also want to grab the event.

authorSearch.addEventListener('keyup', event => { });

Next, let’s test that this is working by logging the value to the console. We can setup a variable named currentValue and then set it equal to the event.target.textContent.

authorSearch.addEventListener('keyup', event => { let currentValue = event.target.textContent; console.log(currentValue);
});

Hit save and head on over to the browser. You should see the console logging everything you type into your input field.

Perfect! Now that that’s wired up correctly, we can remove our console.log() method but keep our currentValue variable as we’ll need this. Let’s chain on .toLowerCase() so that our value will always be in lowercase. This will make sense later.

authorSearch.addEventListener('keyup', event => { let currentValue = event.target.textContent.toLowerCase();
});

Next we should figure out what we would like to search/filter by. The best way to figure this out is to find what is the most unique way to identify our data. This one is easy, we can search/filter by author name as that’s unique for each author. If we inspect the index.html file, we’ll notice that all the author names are being used as h1 tags with the class of title. Let’s grab all instances of this in our JavaScript.

We’ll create a variable just underneath our currentValue variable and name it authors.

let authors = document.querySelectorAll('h1.title');

We’ll need to loop over each of these with every letter typed into our input field. What we are wanting to do is test if the author’s name includes the letters in our input value and if so, show that author’s card, otherwise, hide that author’s card. A conditional will be perfect for this.

Let’s use the forEach array method on our authors variable since it returns an array of elements. We can write:

authors.forEach(author => { });

If you’re new to the forEach method, basically we are saying, for each author, run this code. As mentioned above we will want to run a conditional.

We are checking that the author’s name includes the value of our input. In code, that will look like this:

if (author.textContent.toLowerCase().includes(currentValue)) { // do this
} else { // do this
}

You’ll noticed I added the .toLowerCase() method to our author’s name. This is so that it will always match the value of what is in our input field since the value of that also uses the .toLowerCase() method.

Now that we have our conditional setup, we’ll need to write the logic to show or hide the author’s card. This is really easy. We can take our author variable since it returns the <h1 class="title"></h1> and use .parentNode on it until we reach the div with the class of author-card. ( <div class="author-card"></div> )

If that is hard to understand, take a look at the HTML for an author’s card:

<div class="author-card"> <div class="card-header"> <img src="" alt=""> </div> <div class="card-content"> <h1 class="title"></h1> <p></p> </div>
</div>

The h1‘s parent is <div class="card-content"></div> and the parent of that is our <div class="author-card"></div>. So we’ll need to add .parentNode twice. Then we will want to show the author’s card in the first part of our condition. This is what that will look like:

if (author.textContent.toLowerCase().includes(currentValue)) { author.parentNode.parentNode.style.display = 'block';
} else { // do this
}

For the else portion of our conditional, we’ll just do the opposite and hide the author’s card:

if (author.textContent.toLowerCase().includes(currentValue)) { author.parentNode.parentNode.style.display = 'block';
} else { author.parentNode.parentNode.style.display = 'none';
}

Hit save and check your browser. If everything was written correctly, you should now be able to search/filter authors from our input field. Try typing in “ja” and you’ll notice two authors remain on the webpage; James Kirby & Leslie Jacobs since both names include “ja”.

I hope this guide helps you understand the relationship between your HTML and JavaScript and how we can setup a search/filtering feature to our website! Until next time, have fun and happy coding!