I can't figure out why the counter works on one button but not the other

Viewed 71

I'm quite new to Javascript and JQuery and i can't seem to figure out why the counter increments for one button but the same code doesn't work for the others. Any help would be greatly appreciated. Thanks!

// JAVASCRIPT/JQUERY (to increment by 1)
let addRoom = document.querySelector(".addRoom");
let subtractRoom = document.querySelector(".subtractRoom");
let input = document.querySelector(".roomsAmmount");

addRoom.addEventListener('click', () => {
  input.value = parseInt(input.value) + 1;
});

subtractRoom.addEventListener('click', () => {
  input.value = parseInt(input.value) - 1;
});
/*.addRoom,.subtractRoom{position:absolute;font-size:1.3em;width:50%;height:45px;z-index:1;display:flex}.roomsAmmount{position:absolute;width:50px;height:45px;right:-60px;border:none;border-bottom:1px solid #f4b494;outline:0;font-size:1.4em;text-align:center;background-color:transparent;color:#fff}
*/
<div class="bedroomsButton">Bedrooms
  <div class="addRoom">
    <span class="plusOne">+</span>
  </div>
  <div class="subtractRoom">
    <span class="subtractOne">-</span>
  </div>
  <input class="roomsAmmount" type="number" value="0">
</div>

<div class="bathroomsButton">Bathrooms
  <div class="addRoom">
    <span class="plusOne">+</span>
  </div>
  <div class="subtractRoom">
    <span class="subtractOne">-</span>
  </div>
  <input class="roomsAmmount" type="number" value="0">
</div>

3 Answers

Document.querySelector()

The Document method querySelector() returns the first Element within the document that matches the specified selector, or group of selectors

You can target all the elements with querySelectorAll(), then loop through them using forEach() to attach the event handler.

// JAVASCRIPT/JQUERY (to increment by 1)
let addRoom = document.querySelectorAll(".addRoom");
let subtractRoom = document.querySelectorAll(".subtractRoom");

addRoom.forEach((el)=>{
  el.addEventListener('click', (e) => {
    let input = e.target.closest('.bedroomsButton,.bathroomsButton').querySelector(".roomsAmmount");
    input.value = parseInt(input.value) + 1;
  });
});

subtractRoom.forEach((el)=>{
  el.addEventListener('click', (e) => {
    let input = e.target.closest('.bedroomsButton,.bathroomsButton').querySelector(".roomsAmmount");
    input.value = parseInt(input.value) - 1;
  });
});
<div class="bedroomsButton">Bedrooms
  <div class="addRoom">
    <span class="plusOne">+</span>
  </div>
  <div class="subtractRoom">
    <span class="subtractOne">-</span>
  </div>
  <input class="roomsAmmount" type="number" value="0">
</div>

<div class="bathroomsButton">Bathrooms
  <div class="addRoom">
    <span class="plusOne">+</span>
  </div>
  <div class="subtractRoom">
    <span class="subtractOne">-</span>
  </div>
  <input class="roomsAmmount" type="number" value="0">
</div>

like the comment says, document.querySelector only returns either first element or null.

Do so:

let addRoom = document.querySelectorAll(".addRoom");
let subtractRoom = document.querySelectorAll(".subtractRoom");

addRoom.forEach(btn => {
    setInputValue(btn, true)
  }
)

subtractRoom.forEach(btn => {
    setInputValue(btn, false)
  }
)

function setInputValue(btn, plus) {
  const input = btn.parentNode.querySelector('input')
  btn.addEventListener('click', () => {
    const originalValue = parseInt(input.value)
    input.value = String(plus ? originalValue + 1 : originalValue - 1)
  });
}

add class clickable to every + and -

select all clickable and add event listener on every element

document.querySelectorAll(`.clickable`).forEach(el => el.addEventListener(`click`, handleClick))

handleClick function look like this

const handleClick = (e) => {

  // selecting a closest input
  const input = e.target.parentElement.parentElement.querySelector(".roomsAmmount");

  // parsing value 
  let newValue = parseInt(input.value);

  // if clicked element has class plusOne
  if (e.target.classList.contains(`plusOne`)) {
    newValue++; // increase
  }

  // if clicked element has class subtractOne
  if (e.target.classList.contains(`subtractOne`)) {
    newValue--; // decrease
  }

  // update value
  input.value = newValue;

}

working example https://jsfiddle.net/yqp5zx1b/1/

Related