Skip to content
Advertisement

How to make 3 buttons(same class ,increment on click) that each target individual input fields(number) to work, and not just the last input field?

I am currently working on a webshop, and I’m trying to create a product quantity button. I have three increments and three decrement buttons with the same classes. I’m trying to make them each target their own input field. But what happens to me is that no matter which of the three buttons I click, it only works on the third input field. I am fairly new to javascript and could use any help. Thank you.

My work so far:

Javascript:

 var elem = [].slice.call(document.querySelectorAll('input[type="number"]')).pop()


document.querySelectorAll(".product-quantity-button-up").forEach(function(button){
    button.addEventListener("click",function(){

        elem.value =Number(elem.value) + 1;
    })
})

document.querySelectorAll(".product-quantity-button-down").forEach(function(button){
    button.addEventListener("click",function(){
        elem.value =Number(elem.value) - 1;
        if(elem.value<=0){
            elem.value=0
        }
    })
})

html (same code x 3)

<div class="product-quantity-button-container">
  <div>
    <input type="number" min="1">
  </div>
  <div class="product-quantity-arrow-container">
    <button class="product-quantity-button-up">
      <img class="product-quantity-arrow" src="arrow-up.svg">
    </button>
    <button class="product-quantity-button-down">
      <img class="product-quantity-arrow" src="arrow-down.svg">
    </button>
  </div>
</div>

Advertisement

Answer

I changed the classes to something less verbose and removed unnecessary <div>s. The original layout of OP will still function properly with the example, just be mindful of the classes — they must be changed either in OP or in the example if keep the original HTML.

Details are commented in example

/**
Collect all <button> into a NodeList
On each <button> register the "click" event
Event handler incDec() is called
*/
document.querySelectorAll('button').forEach(btn => btn.onclick = incDec);

/**
Event handler passes the Event object by default
Find the closest <section> then find and reference <input>
Reference <input> value and coherce it into a real number
If the clicked <button> has the class ".up"...
...increment >val<...
...otherwise decrement >val<
If >val< is less than 0...
...assign it as 0...
...otherwise keep it's value
Assign the value of <input> as >val<
*/
function incDec(e) {
  const num = this.closest(".quantity").querySelector("input");
  let val = +num.value;
  if (this.matches(".up")) {
    val++;
  } else {
    val--;
  }
  val = val < 0 ? 0 : val;
  num.value = val;
}
html {
  font: 300 2ch/1.2 Consolas
}

input,
button {
  font: inherit
}

input {
  display: block;
  width: 77px;
  border: 0;
  outline: 0;
  font-size: 1.5rem;
  text-align: center;
}

button {
  border: 0;
  padding: 5px 3px 0;
  background: transparent;
  cursor: pointer
}

button:hover,
button:active {
  background: rgba(193, 211, 233, 0.6);
}
<section class="quantity">
  <input value="0" readonly>
  <button class="up">
      <img src="https://upload.wikimedia.org/wikipedia/commons/7/76/Arrow_%2880554%29_-_The_Noun_Project.svg" width="32" height="32">
    </button>
  <button class="down">
      <img src="https://upload.wikimedia.org/wikipedia/commons/6/63/Arrow_%2880557%29_-_The_Noun_Project.svg" width="32" height="32">
    </button>
</section>

<section class="quantity">
  <input value="0" readonly>
  <button class="up">
      <img src="https://upload.wikimedia.org/wikipedia/commons/7/76/Arrow_%2880554%29_-_The_Noun_Project.svg" width="32" height="32">
    </button>
  <button class="down">
      <img src="https://upload.wikimedia.org/wikipedia/commons/6/63/Arrow_%2880557%29_-_The_Noun_Project.svg" width="32" height="32">
    </button>
</section>

<section class="quantity">
  <input value="0" readonly>
  <button class="up">
      <img src="https://upload.wikimedia.org/wikipedia/commons/7/76/Arrow_%2880554%29_-_The_Noun_Project.svg" width="32" height="32">
    </button>
  <button class="down">
      <img src="https://upload.wikimedia.org/wikipedia/commons/6/63/Arrow_%2880557%29_-_The_Noun_Project.svg" width="32" height="32">
    </button>
</section>
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement