Javascript Filter Project for Beginners





Hey, guys in this post, we will create a simple javascript project and we will add the filter to search the items. The project is deployed to the Github pages, you can check the final version of the application here.

Topics covered


This application involves the following topics –

  • DOM Manipulation
  • Control Structures
  • Array.forEach()
  • Javascript CSS Manipulation
  • eventListeners
  • Immediately Invoked Function Expressions

Complete source code


The below image shows you the project structure –

Screenshot-2021-06-01-at-1-50-46-PM

Add styles to the application


Create a style.css file and add the following content

@import url("https://fonts.googleapis.com/css?family=Kaushan+Script");

:root {
  --mainPink: #ef7998;
  --mainYellow: rgb(249, 228, 148);
  --mainWhite: #fff;
  --mainBlack: #000;
  --yellowTrans: rgba(249, 228, 148, 0.5);
  --mainGrey: rgb(238, 238, 238);
}

body {
  font-family: "Kaushan Script", cursive;
  background: var(--mainWhite);
  color: var(--mainBlack);
}
/* nav links */
.navbar-toggler {
  outline: none !important;
}
.toggler-icon {
  font-size: 2.5rem;
  color: var(--mainPink);
}
.nav-link {
  color: var(--mainPink);
  font-size: 1.5rem;
  transition: all 0.5s ease-in-out;
}
.nav-link:hover {
  color: var(--mainBlack);
}
/* end of nav links */
/* info icons */
.cart-info__icon {
  color: var(--mainBlack);
  cursor: pointer;
}

.cart-info {
  border: 0.1rem solid var(--mainBlack);
  color: var(--mainBlack);
  border-radius: 0.25rem;
  padding: 0.4rem 0.6rem;
  cursor: pointer;
}
.cart-info:hover {
  background: var(--mainPink);
  border-color: var(--mainPink);
  color: var(--mainWhite);
}
.cart-info:hover .cart-info__icon {
  color: var(--mainWhite);
}
/* end of info icons */
/* banner */

.max-height {
  min-height: calc(100vh - 76px);
  background: linear-gradient(var(--yellowTrans), var(--yellowTrans)),
    url("../img/headerBcg.jpeg") center/cover fixed no-repeat;
  position: relative;
}
.banner {
  color: var(--mainWhite);
  margin-top: -4rem;
}
.banner-title {
  color: var(--mainPink);
  font-size: 4rem;
}
.banner-link {
  font-size: 1.5rem;
  color: var(--mainBlack);
  border: 0.2rem solid var(--mainBlack);
}
.banner-link:hover {
  background: var(--mainBlack);
  color: var(--mainPink);
}
/* endo of banner */
/* cart  */
.cart {
  position: absolute;
  min-height: 10rem;
  background: var(--mainWhite);
  top: 0;
  right: 0;
  transition: all 0.3s ease-in-out;
  background: rgba(255, 255, 255, 0.5);
  width: 0;
  overflow: hidden;
}
.show-cart {
  width: 18rem;
  padding: 2rem 1.5rem;
  transform: rotateY(-360deg);
}
.cart-item {
  transition: all 2s ease-in-out;
}

/* end of cart */
/* cart item */
.cart-item-remove {
  color: var(--mainPink);
  transition: all 1s ease-in-out;
}
.cart-item-remove:hover {
  transform: scale(1.1);
  color: var(--mainBlack);
}
#cart-item-price {
  font-size: 0.8rem;
}
/* cart item */
/* cart buttons */
.btn-pink {
  color: var(--mainPink) !important;
  border-color: var(--mainPink) !important;
}
.btn-black {
  color: var(--mainBlack) !important;
  border-color: var(--mainBlack) !important;
}
.btn-black:hover {
  color: var(--mainPink) !important;
  background: var(--mainBlack) !important;
}
.btn-pink:hover {
  background: var(--mainPink) !important;
  color: var(--mainBlack) !important;
}
/* end of cart buttons */

/* about */
.about-img__container {
  position: relative;
}

.about-img__container::before {
  content: "";
  position: absolute;
  top: -1.5rem;
  left: -1.7rem;
  width: 100%;
  height: 100%;
  outline: 0.5rem solid var(--mainYellow);
  z-index: -1;
  transition: all 1s ease-in-out;
}
.about-img__container:hover:before {
  top: 0;
  left: 0;
}

/*end of  about */

/* store items */
.store {
  background: var(--mainGrey);
}
.img-container {
  position: relative;
  overflow: hidden;
  cursor: pointer;
}
.store-img {
  transition: all 1s ease-in-out;
}
.img-container:hover .store-img {
  transform: scale(1.2);
}
.store-item-icon {
  position: absolute;
  bottom: 0;
  right: 0;
  padding: 0.75rem;
  background: var(--mainYellow);
  border-top-left-radius: 1rem;
  transition: all 1s ease-in-out;
  transform: translate(100%, 100%);
}
.img-container:hover .store-item-icon {
  transform: translate(0, 0);
}
.store-item-icon:hover {
  color: var(--mainWhite);
}
.store-item-value {
  color: --mainYellow;
}
/*end of  store items */
.search-box {
  background: var(--mainPink);
  color: var(--mainBlack);
}

Add scripts to the application


Create an app.js file and add the following content

// Work to get the filter buttons working
(function(){
    // refactor to get rid of DRY code
    const buttons = document.querySelectorAll('.btn')
    const storeItems = document.querySelectorAll('.store-item')

    buttons.forEach((button)=> {
        button.addEventListener('click', (e) => {
            e.preventDefault()
            const filter = e.target.dataset.filter
            
            storeItems.forEach((item)=> {
                if (filter === 'all'){
                    item.style.display = 'block'
                } else {
                    if (item.classList.contains(filter)){
                        item.style.display = 'block'
                    } else {
                        item.style.display = 'none'
                    }
                }
            })
        })
    })

})();

//wire up filter search box
(function(){

    const searchBox = document.querySelector('#search-item')
    const storeItems = document.querySelectorAll('.store-item')

    searchBox.addEventListener('keyup', (e) => {
    
        const searchFilter = e.target.value.toLowerCase().trim()
        //display only items that contain filter input

        storeItems.forEach((item) => {
            if (item.textContent.includes(searchFilter)){
                item.style.display = 'block'
            } else {
                item.style.display = 'none'
            }
        })
    })

})();

Add HTML to the application


Create an index.html file and add the following content

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <!-- bootstrap css -->
  <link rel="stylesheet" href="css/bootstrap.min.css">
  <!-- main css -->
  <link rel="stylesheet" href="css/style.css">

  <!-- font awesome -->
  <link rel="stylesheet" href="css/all.css">
  <title>Starter Template</title>
  <style>
  </style>
</head>

<body>
  <!-- header -->
  <header>
    <!-- navbar  -->
    <!-- 
https://www.iconfinder.com/icons/2427887/dessert_donut_doughnut_fat_sweets_icon
Creative Commons (Attribution 3.0 Unported);
https://www.iconfinder.com/korawan_m
     -->
    <nav class="navbar navbar-expand-lg px-4">
      <a class="navbar-brand" href="#"><img src="img/logo.svg" alt=""></a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#myNav">
        <span class="toggler-icon"><i class="fas fa-bars"></i></span>
      </button>
      <div class="collapse navbar-collapse" id="myNav">
        <ul class="navbar-nav mx-auto text-capitalize">
          <li class="nav-item active">
            <a class="nav-link" href="#">home</a>
          </li>
          <li class="nav-item">
            <a class="nav-link " href="#">about</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">store</a>
          </li>
        </ul>
        <div class="nav-info-items d-none d-lg-flex ">
          <!-- single info -->
          <div class="nav-info align-items-center d-flex justify-content-between mx-lg-5">
            <span class="info-icon mx-lg-3"><i class="fas fa-phone"></i></span>
            <p class="mb-0">+ 123 456 789</p>
          </div>
          <!-- end of single info -->
          <!-- single info -->
          <div id="cart-info" class="nav-info align-items-center cart-info d-flex justify-content-between mx-lg-5">
            <span class="cart-info__icon mr-lg-3"><i class="fas fa-shopping-cart"></i></span>
            <p class="mb-0 text-capitalize"><span id="item-count">2 </span> items - $<span class="item-total">10.49</span></p>
          </div>
          <!-- end of single info -->
        </div>
      </div>
    </nav>
    <!-- end of nav -->
    <!-- banner  -->
    <div class="container-fluid">
      <div class="row max-height justify-content-center align-items-center">
        <div class="col-10 mx-auto banner text-center">
          <h1 class="text-capitalize">welcome to <strong class="banner-title ">grandma's</strong></h1>
          <a href="#store" class="btn banner-link text-uppercase my-2">explore</a>

        </div>
        <div id="cart" class="cart">
          <!-- cart item -->
          <div class="cart-item d-flex justify-content-between text-capitalize my-3">
            <img src="img/z-cake-2.jpeg" class="img-fluid rounded-circle" id="item-img" alt="">
            <div class="item-text">

              <p id="cart-item-title" class="font-weight-bold mb-0">cart item</p>
              <p id="cart-item-price" class="mb-0">10.99</p>
            </div>
            <a href="#" id='cart-item-remove' class="cart-item-remove">
              <i class="fas fa-trash"></i>
            </a>
          </div>
          <!--end of  cart item -->
          <!-- cart item -->
          <div class="cart-item d-flex justify-content-between text-capitalize my-3">
            <img src="img/z-sweets-3.jpeg" class="img-fluid rounded-circle" id="item-img" alt="">
            <div class="cart-item-text">

              <p id="cart-item-title" class="font-weight-bold mb-0">cart item</p>
              <p id="cart-item-price" class="mb-0">10.99</p>
            </div>
            <a href="#" id='cart-item-remove' class="cart-item-remove">
              <i class="fas fa-trash"></i>
            </a>
          </div>
          <!--end of  cart item -->
          <!-- cart total -->
          <div class="cart-total-container d-flex justify-content-around text-capitalize mt-5">
            <h5>total</h5>
            <h5> $ <strong id="cart-total" class="font-weight-bold">10.00</strong> </h5>
          </div>
          <!--end cart total -->
          <!-- cart buttons -->
          <div class="cart-buttons-container mt-3 d-flex justify-content-between">
            <a href="#" id="clear-cart" class="btn btn-outline-secondary btn-black text-uppercase">clear cart</a>
            <a href="#" class="btn btn-outline-secondary text-uppercase btn-pink">checkout</a>
          </div>
          <!--end of  cart buttons -->
          <!--  -->
        </div>
      </div>
    </div>




    <!--end of  banner  -->
  </header>
  <!-- header -->
  <!-- about us -->
  <section class="about py-5" id="about">
    <div class="container">

      <div class="row">
        <div class="col-10 mx-auto col-md-6 my-5">
          <h1 class="text-capitalize">about <strong class="banner-title ">us</strong></h1>
          <p class="my-4 text-muted w-75">Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit, aliquam voluptas
            beatae vitae expedita consectetur nesciunt quia deserunt asperiores facere fuga dicta fugiat corrupti et omnis
            porro at dolorum! Ad!</p>
          <a href="#" class="btn btn-outline-secondary btn-black text-uppercase ">explore</a>

        </div>
        <div class="col-10 mx-auto col-md-6 align-self-center my-5">
          <div class="about-img__container">
            <img src="img/sweets-1.jpeg" class="img-fluid" alt="">
          </div>
        </div>
      </div>
    </div>
  </section>

  <!-- end of about us -->


  <!-- store -->
  <section id="store" class="store py-5">
    <div class="container">
      <!-- section title -->
      <div class="row">
        <div class="col-10 mx-auto col-sm-6 text-center">
          <h1 class="text-capitalize">our <strong class="banner-title ">store</strong></h1>
        </div>
      </div>
      <!-- end of section title -->
      <!--filter buttons -->
      <div class="row">
        <div class=" col-lg-8 mx-auto d-flex justify-content-around my-2 sortBtn flex-wrap">
          <a href="#" class="btn btn-outline-secondary btn-black text-uppercase filter-btn m-2" data-filter="all"> all</a>
          <a href="#" class="btn btn-outline-secondary btn-black text-uppercase filter-btn m-2" data-filter="cakes">cakes</a>
          <a href="#" class="btn btn-outline-secondary btn-black text-uppercase filter-btn m-2" data-filter="cupcakes">cupcakes</a>
          <a href="#" class="btn btn-outline-secondary btn-black text-uppercase filter-btn m-2" data-filter="sweets">sweets</a>
          <a href="#" class="btn btn-outline-secondary btn-black text-uppercase filter-btn m-2" data-filter="doughnuts">doughnuts</a>
        </div>
      </div>
      <!-- search box -->
      <div class="row">

        <div class="col-10 mx-auto col-md-6">
          <form>
            <div class="input-group mb-3">
              <div class="input-group-prepend ">
                <span class="input-group-text search-box" id="search-icon"><i class="fas fa-search"></i></span>
              </div>
              <input type="text" class="form-control" placeholder='item....' id="search-item">
            </div>

          </form>
        </div>
      </div>
      <!--end of filter buttons -->
      <!-- store  items-->
      <div class="row" id="store-items">
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item sweets" data-item="sweets">
          <div class="card ">
            <div class="img-container">
              <img src="img/sweets-1.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">sweet item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">5</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cupcakes" data-item="cupcakes">
          <div class="card ">
            <div class="img-container">
              <img src="img/cupcake-1.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">cupcake item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">5</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cakes" data-item="cakes">
          <div class="card ">
            <div class="img-container">
              <img src="img/cake-1.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">cake item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">5</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item doughnuts" data-item="dougnuts">
          <div class="card ">
            <div class="img-container">
              <img src="img/doughnut-1.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">dougnut item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">5</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item sweets" data-item="sweets">
          <div class="card ">
            <div class="img-container">
              <img src="img/sweets-2.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">sweet item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">10</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cupcakes" data-item="cupcakes">
          <div class="card ">
            <div class="img-container">
              <img src="img/cupcake-2.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">cupcake item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">10</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cakes" data-item="cakes">
          <div class="card ">
            <div class="img-container">
              <img src="img/cake-2.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">cake item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">10</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item doughnuts" data-item="dougnuts">
          <div class="card ">
            <div class="img-container">
              <img src="img/doughnut-2.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">dougnut item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">10</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item sweets" data-item="sweets">
          <div class="card ">
            <div class="img-container">
              <img src="img/sweets-3.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">sweet item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">15</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cupcakes" data-item="cupcakes">
          <div class="card ">
            <div class="img-container">
              <img src="img/cupcake-3.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">cupcake item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">15</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item cakes" data-item="cakes">
          <div class="card ">
            <div class="img-container">
              <img src="img/cake-3.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">cake item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">15</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->
        <!-- single item -->
        <div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item doughnuts" data-item="dougnuts">
          <div class="card ">
            <div class="img-container">
              <img src="img/doughnut-3.jpeg" class="card-img-top store-img" alt="">
              <span class="store-item-icon">
                <i class="fas fa-shopping-cart"></i>
              </span>
            </div>
            <div class="card-body">
              <div class="card-text d-flex justify-content-between text-capitalize">
                <h5 id="store-item-name">dougnut item</h5>
                <h5 class="store-item-value">$ <strong id="store-item-price" class="font-weight-bold">15</strong></h5>

              </div>
            </div>


          </div>
          <!-- end of card-->
        </div>
        <!--end of single store item-->

      </div>
  </section>
  <!--end of store items -->



  <!-- jquery -->
  <script src="js/jquery-3.3.1.min.js"></script>
  <!-- bootstrap js -->
  <script src="js/bootstrap.bundle.min.js"></script>
  <!-- script js -->
  <script src="js/app.js"></script>
</body>

</html>

Note: Make sure to download the bootstrap.css, bootstrap.js, and jquery.js library from the internet add them to the respective folders. You can download the images from the Github repository.

Download the complete source code from github repository




About the author

Bushan Sirgur

Hey guys, I am Bushan Sirgur from Banglore, India. Currently, I am working as an Associate project in an IT company.

View all posts

Leave a Reply

Your email address will not be published. Required fields are marked *