Product Search

shopping bag logo

Setting up the filtered products

The project has a search bar at the top of the home and dashboard pages:

<input type="text" id="search" placeholder="Search products..." />

When the user types into this we will filter the products to match the search term. At the top of the script.js file, add the filteredProducts variable:

let products = [];
// add filteredProducts:
let filteredProducts = [];

This is initially an empty array. Update this array with the products we receive from the API:

async function fetchProducts() {
    const response = await fetch(API_URL);
    const data = await response.json();
    products = data.data;
  // set filteredProducts:
    filteredProducts = products;
    createPaginationButtons();
    renderProducts();
}

This filteredProducts variable will now be used going forward to generate products, meaning we need to update the project where it currently uses the products variable.

Change products to be filteredProducts in two locations:

function renderProducts() {
    const productList = document.getElementById("product-list");
    const productTable = document.getElementById("product-table");

    const start = (currentPage - 1) * ITEMS_PER_PAGE;
    const end = start + ITEMS_PER_PAGE;
    // 1.
    const currentProducts = filteredProducts.slice(start, end);
  // ...
function createPaginationButtons() {
    //  2.
    const totalPages = Math.ceil(filteredProducts.length / ITEMS_PER_PAGE);

Filtering by search term

magnifying glass

Earlier we looked at the click event to react to a button being clicked. This section will focus on the input event which is fired when a search term is typed into the <input>:

// Search products
document.getElementById("search").addEventListener("input", function (e) {

});
  • document.getElementById("search"): Select the search input by the ID.
  • addEventListener: Will listen for any user input in the search.
  • function (e) {}: A function will run once user input is detected. The function will also be passed information relating to the event, we are storing this into a variable named e.

The first step is to extract the search term the user types in, we get this from the event information (e). The target is the object which caused the event to fire, if we console.log(e.target) you will see the <input> element. The value is the term the user types into the search:

document.getElementById("search")?.addEventListener("input", function (e) {
    const searchTerm = e.target.value.toLowerCase();
});

The toLowerCase() method will return the string as lower case. This means we can match the text regardless of the casing used.

The filter() and includes() methods

Next we will use the filter() method to create a filtered copy of the products array, updating filteredProducts with the result. This method runs a function for each item in the array:

document.getElementById("search")?.addEventListener("input", function (e) {
  const searchTerm = e.target.value.toLowerCase();

  filteredProducts = products.filter(function (product) {

  });

});

Then add the condition which must be passed to include the value in the new filtered array. This makes use of the JavaScript includes method:

document.getElementById("search")?.addEventListener("input", function (e) {
  const searchTerm = e.target.value.toLowerCase();

  filteredProducts = products.filter(function (product) {
    return product.name.toLowerCase().includes(searchTerm);
  });

});

Conditions which are true will make it into the new, filtered array. Let's break it down:

  • product.name.toLowerCase(): We select the product name for each item in the array, and also convert to lower case. This name and the search term are now lower case so we can check for matches regardless of if upper or lower case is used.
  • .includes(searchTerm): Will return true or false. Here we are checking if the product name includes the search term the user enters. If a match is found, the result is true and the matching products are returned.

Complete this function by re-rendering the products and pagination buttons:

document.getElementById("search")?.addEventListener("input", function (e) {
    const searchTerm = e.target.value.toLowerCase();

    filteredProducts = products.filter(function (product) {
    return product.name.toLowerCase().includes(searchTerm);
  });
  // render the updated products and pagination buttons
    renderProducts();
    createPaginationButtons();
});

Give this a try, it should work on both the home and dashboard pages.