Filter machine with vanilla Javascript
In this article, we will be building a search bar that filters and responds to your search input in real-time using vanilla Javascript. <!--more-->
Goal
By the end of the article, we should have an application that has a functional search bar as illustrated below:
This is the live demo of the app and the full code.
Prerequisites
To follow along with this tutorial, you should know:
- HTML.
- CSS.
- Javascript.
This project was developed on the repl website using the html/css/js
stack. Feel free to use it to follow along with the article.
Our code will be split into three distinct files:
HTML file (index.html)
: This contains all our HTML code.CSS file (style.css)
: This contains all our CSS code.SCRIPT file (script.js)
: This contains all the Javascript code.
HTML
The HTML code below consists of the default html boilerplate
to which our css
and Javascript
files are linked.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>workshop filter search bar</title>
</head>
<body>
<main>
<header>
<h2>This is Filter Machine written in Vanilla Js</h2>
<div class="form-area">
<form>
<input
type="search"
placeholder="Type Here to filter the List"
autofocus
/>
</form>
</div>
</header>
<div class="content">
<div class="card">
<p>A</p>
</div>
<div class="card">
<p>B</p>
</div>
<div class="card">
<p>C</p>
</div>
<div class="card">
<p>D</p>
</div>
<div class="card">
<p>E</p>
</div>
<div class="card">
<p>F</p>
</div>
<div class="card">
<p>G</p>
</div>
<div class="card">
<p>H</p>
</div>
<div class="card">
<p>I</p>
</div>
<div class="card">
<p>I</p>
</div>
<div class="card" id="not-found">
<p>Not in the List</p>
</div>
</div>
</main>
<script src="script.js"></script>
</body>
</html>
The code above contains:
- The
head
tag houses thetitle
andCSS
file links. - The
title
that displays on our browser indicating the title of the page. - The CSS link that points directly to our CSS file and helps pass the set of rules in the CSS file that are to be applied to the HTML content.
- The
main
tag contains the main content of our HTML page. - The
header
tag contains the header of our application. - The
h2
tag describes our Application with the form that contains our search bar. - The
divs
with class attributes ofcard
that are duplicated for every letter. - The
script
link that points to our Javascript code included just before the closing</body>
tag.
CSS
First, we clear the default margin
, padding
and box-sizing
styling:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
We do this to prevent the default addition of margins and paddings to the width and height of elements; and to set the box-sizing to border-box, which controls the behavioral activities of every element on the page in relation to the box model.
We then style the main content area:
main {
width: 100vw;
display: flex;
flex-direction: column;
align-items: center;
}
We set the width to the view width of the viewing device. We then use Flexbox to achieve a responsive layout.
We then style the header:
header {
width: 100%;
height: 200px;
background: darkslategray;
border-radius: 0 0 100% 100%;
padding: 50px;
margin: 0 0 20px;
color: white;
font-family: "Trebuchet MS", "Lucida Sans Unicode", "Lucida Grande",
"Lucida Sans", Arial, sans-serif;
text-align: center;
}
We set the width and height, and the background color using the background
property; the background
property can take multiple options eg. an image, color, etc. If you wish to, you can use an image, any other pattern, or even the background-color
property, which will do the same thing.
Now, let us decorate the search bar's input element:
input {
width: 70%;
height: 50px;
margin-top: 10px;
outline: none;
border: none;
border-radius: 5px;
font-size: 25px;
padding-left: 20px;
}
We set the width to 70% of the header width. We add a margin to push it away from the (<h2>)
tag above it. We add the rounded corner using the border-radius
property.
Then, let's style the cards:
.card {
width: 200px;
height: 200px;
border-radius: 50%;
background-color: darkslategray;
margin: 10px 0;
display: flex;
justify-content: center;
align-items: center;
color: white;
font-size: 56px;
font-family: monospace;
}
These are the circular cards containing the English letters. We set border-radius: 50%
which makes the cards circular. The other properties follow the same pattern as before.
We then style the error card:
.card:last-child {
font-size: 30px;
text-align: center;
display: none;
}
The :last-child
is a CSS
pseudo-class selector which helps select the last child element contained within a parent element. We will display this card when nothing matches our user's search. The implementation will be done in the javascript code.
Making the CSS responsive
Developing a web-based app that is accessible through mobile and tablet is important as mobile devices are everywhere.
There are many ways of doing this; we will be implementing responsiveness using a media query
:
@media screen and (min-width: 768px) {
header {
height: 500px;
display: flex;
flex-direction: column;
justify-content: center;
font-size: 30px;
}
input {
height: 80px;
}
}
We will only control the important sections of our application. The header will automatically increase in height at the point where the user's screen is greater than 768px
and the search bar height was increased too.
Another important property is the flex property flex-direction
which we set to column
to make the flex items contained in the header to be displayed vertically.
Javascript code
const input = document.querySelector("input");
const notFound = document.getElementById("not-found");
const filterFunction = () => {
const cards = document.querySelectorAll(".card");
cards.forEach((item) => {
let whatToSearch = item.querySelector("p");
if (
whatToSearch.innerHTML.toUpperCase().indexOf(input.value.toUpperCase()) >
-1
) {
item.style.display = "";
} else {
item.style.display = "none";
// Not found logic
notFound.style.display = "flex";
}
});
};
input.addEventListener("keyup", filterFunction);
Above is all the required Javascript code. In the following steps, I will be explaining what the code does.
- Line 1
const input = document.querySelector("input");
We create a variable called input
. This variable holds the content of the search bar we created in our HTML. The querySelector
method returns a list of every HTML element with the tag input. Here, we only have one.
Later on, the user input can be obtained by using Javascript's .value
method on the input
variable.
- Line 3 - 4
const filterFunction = () => {
We create a new arrow function, filterFunction
using ES6 (ECMAScript 2015) syntax. Inside the function, we create another variable that holds every card
div. The filterFunction
function will contain all the logic to filter everything on the page as we wish.
const cards = document.querySelectorAll(".card");
We use querySelector
as explained before; every element with the class attribute of card
will be returned as an item in an array.
- Line 5
cards.forEach((item) => {
We then loop through the array returned using the forEach
method.
- Line 6
let whatToSearch = item.querySelector("p");
Inside every card, there is a <p>
tag that holds the letters. line 5 creates a variable to hold each <p>
tag using querySelector
on the item returned by the forEach
method.
- Line 7 - 8
if (whatToSearch.innerHTML.toUpperCase().indexOf(input.value.toUpperCase()) >-1)
We then use an if
statement to check if our search input matches any text in the div's we are searching through.
whatToSearch.innerHTML
returns the letter inside the whatToSearch
variable, which is the letter in the <p>
tag.
We use toUpperCase()
to convert it into a capital letter. We then use indexOf
to check if the user's input value is found within the whatToSearch
values. If the return value is greater than -1
it means the search value matched with something, if not greater than -1
the search value is not in the list.
- Line 9
item.style.display = "";
This sets a CSS property of display
on the item to default the display
property or the property in the CSS file.
- Line 10
item.style.display = "none";
If the type character does not match, it should set display
to none
, that is, nothing should be shown.
- Line 12 -13
notFound.style.display = "flex";
We create a variable to hold the last div using the getElementById
method on line 2
. This returns the element with the ID
passed in. The CSS display
property was set to flex as it was set to none in the CSS file.
- Last Line
input.addEventListener("keyup", filterFunction);
We set a keyup
event listener on the input which responds when a user releases their hand from the keyboard and the function created in line 3 is called.
Conclusion
Below is what we just built, isn't amazing?
What you just built can be implemented in various real-life projects and can be improved by:
- The search bar can be modified by adding more styles to be more outstanding and give a better look.
- On a shopping cart application, users need to filter out the products to get their choices. This app can be integrated to give access.
- Creativity is the limit of this app as it can be implemented on any application that needs a filter to its elements.
Further reading
- Creating a Responsive Navigation bar Using Tailwind CSS and Javascript
- Documenting JavaScript Code With JSDocs
- DOM Manipulation with JavaScript
Peer Review Contributions by: Adrian Murage