Pure JS plus/minus buttons

by helgatheviking

HTML

<div class="quantity">
  <input class="qty" type="number" name="quantity" min="0" max="3" step="1" value="" />
  <button aria-label="Reduce quantity" disabled='disabled' class="kia-qty-selector-button kia-qty-selector-button--minus">-</button>
  <button aria-label="Increase quantity" class="kia-qty-selector-button kia-qty-selector-button--plus">+</button>
</div>

CSS

.quantity {
  border-radius: 4px;
  box-sizing: content-box;
  display: flex;
  margin: 0 0 .25em;
  position: relative;
  width: 107px;
}

.quantity::after {

  border: 1px solid;
  border-radius: 4px;
  bottom: 0;
  content: "";
  left: 0;
  opacity: .45;
  pointer-events: none;
  position: absolute;
  right: 0;
  top: 0;

}

.quantity>input.qty {
  -webkit-appearance: textfield;
  -moz-appearance: textfield;
  appearance: textfield;
  background: transparent;
  border: 0;
  box-shadow: none;
  color: currentColor;
  flex: 1 1 auto;
  font-size: 1em;
  font-weight: 600;
  line-height: 1;
  margin: 0;
  min-width: 40px;
  order: 2;
  padding: .4em 0;
  text-align: center;
  vertical-align: middle;
}


.quantity>.kia-qty-selector-button {
  background: none transparent;
  border: 0;
  box-shadow: none;
  color: currentColor;
  cursor: pointer;
  font-size: .9em;
  font-style: normal;
  font-weight: 400;
  margin: 0;
  min-width: 30px;
  opacity: .6;
  padding: 0;
  text-align: center;
  text-decoration: none;
}

.quantity>.kia-qty-selector-button:disabled {
  background: red;
}

.quantity>.kia-qty-selector-button--minus {
  border-radius: 4px 0 0 4px;
  order: 1;
}

.quantity>.kia-qty-selector-button--plus {
  border-radius: 0 4px 4px 0;
  order: 3;
}

JavaScript

document.addEventListener('click', handle);

function handle(event) {

  if (event.target.classList.contains('kia-qty-selector-button')) {
    return handleQtyChange(event.target);
  }

}

function handleQtyChange(btn) {

  event.preventDefault();

  // Find the input.
  let quantity = btn.closest('.quantity');
  let qty = quantity.querySelector('.qty');

  // Read value and attributes min, max, step.
  let val = parseFloat(qty.value);
  let max = parseFloat(qty.getAttribute('max'));
  let min = parseFloat(qty.getAttribute('min'));
  let step = parseFloat(qty.getAttribute('step'));

  if (btn.classList.contains('kia-qty-selector-button--plus')) {




    if (isNaN(val)) {
      qty.value = step;
    } else if (val + step > max) {
      qty.value = max;
    } else {
      qty.value = (val + step);
    }

    if (!isNaN(max) && parseFloat(qty.value) === max) {

      btn.disabled = true;
    }


    if (!isNaN(min) && parseFloat(qty.value) > min) {
      let minusButton = quantity.querySelector('.kia-qty-selector-button--minus');
      minusButton.disabled = false;
    }
  } else if (btn.classList.contains('kia-qty-selector-button--minus')) {

    if (isNaN(val)) {
      qty.value = min;
    } else if (val - step < min) {
      qty.value = min;
    } else {
      qty.value = (val - step);
    }

    if (!isNaN(min) && parseFloat(qty.value) === min) {
      btn.disabled = true;
    }

    if (!isNaN(max) && parseFloat(qty.value) < max) {
      let plusButton = quantity.querySelector('.kia-qty-selector-button--plus');
      plusButton.disabled = false;
    }

  }

  qty.dispatchEvent(new Event("change"));
}