In this article, we will learn how to build a search filter using JavaScript with the following functionalities:
- Display list of item on the screen
- Allow users to enter search query
- Filter list of items based on search query
1. Add Input box for Search Inputs
First, we need to add an HTML input box to allow users to enter the search query.
<div class="search-header">
<div class="search-text">Search:</div>
<input id="search-box" />
</div>
2. Declare a JS Array for item list
We will store the default value of the item list in a JavaScript array. The array is declared as JS constant since the default value is never modified in the JavaScript code.
const itemList = [
"Apple",
"Orange",
"Banana",
"Cherry",
"Milk",
"Peanuts",
"Oil",
"Tomato"
];
3. Add item list in HTML and access from JS DOM
The ordered HTML list is declared using <ol></ol> tag, read more about HTML ordered list from javatpoint.com/html-ordered-list.
<div>
<ol id="item-list"></ol>
</div>
To access the ordered list from JavaScript, we use JS DOM using “document.getElementById()“.
const itemContainer = document.getElementById("item-list");
4. JS Function to render the filtered list
Next, we will create a JS Function to display the filtered list on the screen by following the steps below:
- Generate the HTML code every item of the list and concatenate it with renderHTML.
- Append HTML string to DOM container using element.innerHTML.
// String to render HTML list item
const itemHTML = (item) => `<li>${item}</li>`;
// Function to render filtered list
const filterBySearch = (query = "") => {
var renderHTML = ``;
// Generate HTML for filtered List
itemList.forEach((item) => {
if (item.toLowerCase().indexOf(query.toLowerCase()) !== -1) {
renderHTML += itemHTML(item);
}
});
// Display updated HTML on screen
itemContainer.innerHTML = renderHTML;
};
5. Trigger filterBySearch() when user enter search query
Similar to item list, we access the search input box in JavaScript using document.getElementById() . We update the filter list every time search text is changed by triggering the filterBySearch() function with input value.
const searchInput = document.getElementById("search-box");
// Trigger function every time search text is changed
searchInput.onkeyup = (event) => {
filterBySearch(event.target.value);
};
6. Render item list on load
Finally, we need to display all items on the list initially on page load. The code “filterBySearch()” displays the item list with query = “” which includes every item in the list.
filterBySearch();
Final Solution Code
index.html
<!DOCTYPE html>
<html>
<head>
<title>JS search filter</title>
<script src="main.js" defer></script>
</head>
<body>
<div id="app">
<div class="search-header">
<div class="search-text">Search:</div>
<input id="search-box" />
</div>
<div>
<ol id="item-list"></ol>
</div>
</div>
</body>
</html>
main.js
import "./styles.css";
const itemList = [
"Apple",
"Orange",
"Banana",
"Cherry",
"Milk",
"Peanuts",
"Oil",
"Tomato"
];
const itemContainer = document.getElementById("item-list");
const searchInput = document.getElementById("search-box");
// Trigger function every time search text is changed
searchInput.onkeyup = (event) => {
filterBySearch(event.target.value);
};
// String to render HTML list item
const itemHTML = (item) => `<li>${item}</li>`;
// Function to render filtered list
const filterBySearch = (query = "") => {
var renderHTML = ``;
// Generate HTML for filtered List
itemList.forEach((item) => {
if (item.toLowerCase().indexOf(query.toLowerCase()) !== -1) {
renderHTML += itemHTML(item);
}
});
// Display updated HTML on screen
itemContainer.innerHTML = renderHTML;
};
// Load the list of items
filterBySearch();
styles.css
#app {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
font-size: 22px;
}
.search-header {
display: flex;
}
#item-list {
min-height: 200px;
}
.search-text {
margin-right: 10px;
font-size: 22px;
display: flex;
align-items: center;
justify-content: center;
}
#search-box {
height: 25px;
}
#search-box[placeholder] {
line-height: 25px;
font-size: 25px;
}