DEV Community

CMarghin
CMarghin

Posted on

vanilla Js beginners projects #2 : calculate items price

continuing our beginners projects to practice some Js basics
in this one we will make something similar to this on codepen

it's so easy you but before we start let's divide the main idea to small problems to solve then start coding.
first let's start by the html and css, you can create your own styles .. focus on the js part.

if you want to follow me this is my code you can also check codepen above for the rest

<body>
  <div class="container">
    <div class="product">
      <!-- add an image here or whatever -->
    </div>
    <div class="pricing">
      <p>
        <span class="price">100</span>
        <span class="currency">$</span>
      </p>
      <div class="custom">
        <button class="btn add">&plus;</button>
        <button class="btn remove">&minus;</button>
      </div>
      <div class="add-to-cart">
        <p>
          <span class="quantity">1</span>
            item to buy
          </p>
        <button class="buy-btn">Add To Card</button>
      </div>
    </div>
  </div>
</body>
Enter fullscreen mode Exit fullscreen mode

simple hah, make container to contain product and pricing divs
product for the image and pricing for other stuff
for the styles it your choice ...

let's start

so the first thing we need to do is selecting the elements.
oh Sh*t 😑 thinking of writing all the document.querySelect.... is so silly, let's build a function to do that for us and re-use it whenever we want
let's call it _ or $(jQuery) or whatever you want to call it but make it shorter because that's the reason why we creating it xD

function _s(element, all) { //_ used for private functions but don't think of that now just keep it simple
  if(all) {
    return document.querySelectorAll(element)
  }
  return document.querySelector(element);
}
Enter fullscreen mode Exit fullscreen mode

this function takes two arguments, the first one is a string (class, id, tag, ...), the second argument is optional, you can use a truthy value if you want to use the querySelectorAll() function, else ... leave it;
the difference between them
the querySelector() function returns a single html element and you can use all the methods directly on it, the querySelectorAll() returns an array (nodeList) so you can only use arrays methods on it,to access the elements you have to loop through it,

so now let's select the html elements using this _s() function

let price = _s(".price").textContent,
    //the text that shows how mush money we need spend

    buttons = _s(".btn", true),
    //array of buttons with the class .btn [add and remove buttons]

    quantity = _s(".quantity"),
    //the number of items that we will buy (string)

    items = parseInt(quantity.textContent);
    //transfer the quantity using the parseInt function
    //with a single parameter it returns an integer number type
    //if it can't transfer it it returns NaN     
Enter fullscreen mode Exit fullscreen mode

so now we have to loop through the buttons and add an event to each one and create the function that will change the html with the new numbers.
I'll use the forEach() methode to loop over the numbers learn more about it here ... you can use any other methods

buttons.forEach(button => {
  button.addEventListener("click", function(e) {

  })
})
Enter fullscreen mode Exit fullscreen mode

but how could know what button we clicked on ... hmmm good question
we can access to that item by adding a parameter to the function inside the addEventListener;
in the code above It's (e), this is the event object it has many methods that will help you, one of them is the e.target, this will return the html element after the event finished,
ok now we have the target but how we will know if the user is clicking on the + or - button.
for me I'm not that creative so I will give each button a unique class and check the class of that target element (look at the html)
so to access a class of an element I will use the classList method that return an array of element's classes then check if it contains add or remove class to know what to do in each case.

function _s(element, all) { 
  if(all) {
    return document.querySelectorAll(element)
  }
  return document.querySelector(element);
}

let price = _s(".price").textContent,
    buttons = _s(".btn", true),
    quantity = _s(".quantity"),
    items = parseInt(quantity.textContent);


buttons.forEach(button => {
  button.addEventListener("click", function(e) {
    if(e.target.classList.contains("add")) {

    } else { //we have only two buttons so if it's not "add" it will be "remove"

    }
  })
})
Enter fullscreen mode Exit fullscreen mode

everything is good let's finish it
the total price is the the price of one item multiple by how many items
the price of one item is stored in the price variable as a string
if we click on the add button it will increase the items by one, and if we click on the remove button it will decrease the items by one
in the end it will show the total price that is price * items, since the price is a textContent (string) we have to convert it to a valid number, we can use the parseInt() as we learned before or 😎 use this trick(Idk why I wrote the emoji but I just learned it too), using + before a string number will convert it to a number
so the total price is +price * items
then we have to show the items in the html too
and also we have to add a condition to decrease the items only if it is bigger that 1, to avoid buying negative items
so the result is

function _s(element, all) { 
  if(all) {
    return document.querySelectorAll(element)
  }
  return document.querySelector(element);
}

let price = _s(".price").textContent,
    buttons = _s(".btn", true),
    quantity = _s(".quantity"),
    items = parseInt(quantity.textContent);

buttons.forEach(button => {
  button.addEventListener("click", function(e) {
    if(e.target.classList.contains("add")) {
      items++
    } else {
      if(items > 1) items--
    }

    _s(".price").textContent = +price * items;
    quantity.textContent = items;
  })
})
Enter fullscreen mode Exit fullscreen mode

I hope you learned something and sorry for writing a lot of lines but it should be understandable for beginners and if I had any mistake please correct it in the comments and good luck

Discussion (0)