HTML Setup
First, let's create the basic HTML structure for the typeahead component. We'll need a search input for user queries and a table to display matching results.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Simple Typeahead Feature with JavaScript</title>
<style>
/* Add your CSS code here */
</style>
</head>
<body>
<div class="wrapper">
<input
type="search"
id="search-input"
placeholder="Search Products..."
>
<table id="product-table">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Price</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<script>
// Add your JavaScript code here
</script>
</body>
</html>
The input element captures user input, while the table body will be dynamically populated with matching products using JavaScript.
SCSS Styling
Next, let's add some styling to improve the appearance of the search interface. We'll style the search input and results table to create a clean, responsive layout.
$primary: #2d4263;
$body: #f6f6f6;
$search-color: #555;
$search-background: #ffffff;
$search-border-radius: 5px;
body {
background: $body;
margin: 0;
font-family: Arial, Helvetica, sans-serif;
}
.wrapper {
padding: 15px;
position: relative;
#search-input {
width: 100%;
padding: 10px;
font-size: 16px;
color: $search-color;
background: $search-background;
border: 1px solid #d6d6d6;
border-radius: $search-border-radius;
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
}
#product-table {
width: 100%;
margin-top: 20px;
border-collapse: collapse;
background: #ffffff;
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
thead {
background: $primary;
color: #ffffff;
th {
padding: 10px;
text-align: left;
font-weight: bold;
&:first-of-type {
border-top-left-radius: 4px;
}
&:last-of-type {
border-top-right-radius: 4px;
}
}
}
tbody {
td {
padding: 10px;
border-bottom: 1px solid #ddd;
}
}
}
}
These styles give the table a simple card-like appearance while improving readability and spacing. Feel free to customize the colors, typography, and layout to match your project.
JavaScript Functionality
Now it's time to add the search functionality.
We'll listen for changes in the search input, filter the product list based on the user's query, and dynamically render the matching results inside the table.
// Product data
const products = [
{
name: "Product 1",
description: "Description 1",
price: "$10.00"
},
{
name: "Product 2",
description: "Description 2",
price: "$20.00"
},
{
name: "Product 3",
description: "Description 3",
price: "$30.00"
}
];
// DOM elements
const searchInput = document.querySelector("#search-input");
const productTable = document.querySelector("#product-table tbody");
// Render products into the table
const renderProducts = (products) => {
const html = products
.map(
(product) => `
<tr>
<td>${product.name}</td>
<td>${product.description}</td>
<td>${product.price}</td>
</tr>
`
)
.join("");
productTable.innerHTML = html;
};
// Filter products on input
searchInput.addEventListener("input", () => {
const query = searchInput.value.trim().toLowerCase();
const filteredProducts = products.filter((product) =>
product.name.toLowerCase().includes(query)
);
renderProducts(filteredProducts);
});
// Initial render
renderProducts(products);
The input event listener updates the results in real time as the user types. We use filter() to find matching products and map() to generate the table rows dynamically.
Conclusion
Typeahead search is a simple feature that can significantly improve the user experience of a web application. With just a small amount of HTML, SCSS, and JavaScript, you can create fast, responsive search interactions without relying on external libraries.
From here, you could expand this example by:
- Highlighting matching text
- Fetching results from an API
- Adding keyboard navigation
- Displaying search suggestions in a dropdown
Hopefully this tutorial gave you a solid foundation for building your own typeahead components with vanilla JavaScript.
You can find a working example here: