vanilla Js beginners projects #2 : calculate items price
Tags: beginners, javascript, webdev, tutorial
Published: 2021-07-07 21:29:48

continuing our beginners projects to practice some Js basics
in this one we will make something similar to this on codepen
{% codepen https://codepen.io/CH4R4F/pen/yLbeZqO %}
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*
```html
<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>
```
***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
```js
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);
}
```
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
```js
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     
```
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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) ... you can use any other methods
```js
buttons.forEach(button => {
  button.addEventListener("click", function(e) {
    
  })
})
```
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.

```js
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"
      
    }
  })
})
```
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 
```js
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;
  })
})
```

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