JavaScript

Build a Typeahead with JavaScript

Typeahead search helps users quickly find results as they type. In this tutorial, we'll build a simple typeahead feature using vanilla JavaScript.

April 6th, 2023 10 min min read
Blog Post - Build a Typeahead with JavaScript - Thumbnail
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:

View CodePen