3

I am trying to make an e-commerce-like webpage (for practice) wherein a click on any of the buttons would update the cart value by the number (quantity) specified on the input element. So far, I was only able to update the cart from the first form because when I try to assign the function on every form using a loop, the cart updates for a millisecond then returns to zero. I assume its because of the scope. I know there's an easier way to do this without manually assigning the function for every document.forms[n]

JS

 window.onload = function() 
 {
    var getForm = document.forms[0];
    var numItems = 0;
    getForm.onsubmit = function(event) 
    {
      event.preventDefault();
      var getInput = getForm.elements["num-item"].value;
      if(parseInt(getInput)) 
      {
        numItems = numItems + parseInt(getInput);
        var getCart = document.getElementById("item-count");
        getCart.innerHTML = numItems;
        getForm.reset();            
      }
      else 
      {
        alert("Please enter a valid number");
      }
  }

HTML Cart:

<div class="basket">
    <p><i class="fa fa-shopping-basket"></i></p>
    <p id="item-count">0</p>
</div>

HTML Form: For brevity, I'm only posting 1 form example, but in reality, I have 6 other forms that are exactly the same.

<div class="buy-config">
    <form class="buy-form" name="buy-form">
        <label>Quantity:</label>
            <input type="text" class="num-item" />
            <button class="buy-btn">Add to Cart</button>
    </form>
</div>

3 Answers 3

3

Loop through all of the forms by querying the selector (using whatever method you prefer, depending on performance requirements and markup flexibility -- I've used getElementsByClassName) and executing a for loop.

Inside the loop, bind a function to the "submit" event using addEventListener. You can define the function in-line (as I've done), or define the function elsewhere, assign it to a variable, and reference the variable when binding to the event.

Within the event listener function, you will refer to the form that was submitted as this.

On top of the changes described above, I've made some minor changes to your code:

  1. Your previous version was overwriting the contents of the cart each time. This may have been on purpose, depending on whether you have one "basket" for each item or one overall (this wasn't clear in the question). So, rather than initialize numItems to zero, I've initialized it to the current number of items in the cart.
  2. Consider using input type="number" HTML form elements. They're supported by nearly every browser and only accept digits -- they also have up/down arrows and can be set with the scroll wheel. On browsers that don't support them, they fall back to a basic text input.

var forms = document.getElementsByClassName("buy-form");
for (var i = 0; i < forms.length; i++) {
  forms[i].addEventListener("submit", function(event) {
    event.preventDefault();
    var numItems = parseInt(document.getElementById("item-count").innerHTML);
    var getInput = this.getElementsByClassName("num-item")[0].value;
    if (parseInt(getInput)) {
      numItems = numItems + parseInt(getInput);
      var getCart = document.getElementById("item-count");
      getCart.innerHTML = numItems;
      this.reset();
    } else {
      alert("Please enter a valid number");
    }
  });
}
<div class="basket">
  <p><i class="fa fa-shopping-basket"></i></p>
  <p id="item-count">0</p>
</div>
<div class="buy-config">
  <form class="buy-form" name="buy-form">
    <label>Quantity:</label>
    <input type="number" class="num-item" />
    <button class="buy-btn">Add to Cart</button>
  </form>
</div>
<div class="buy-config">
  <form class="buy-form" name="buy-form">
    <label>Quantity:</label>
    <input type="number" class="num-item" />
    <button class="buy-btn">Add to Cart</button>
  </form>
</div>
<div class="buy-config">
  <form class="buy-form" name="buy-form">
    <label>Quantity:</label>
    <input type="number" class="num-item" />
    <button class="buy-btn">Add to Cart</button>
  </form>
</div>

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much! It works! Question -- what does the [0] mean in var getInput = this.getElementsByClassName("num-item")[0].value;? I assume its not the current index, otherwise, you would have used i. So what does that line do, exactly?
@Charisse getElementsByClassName always returns a collection of elements, even if that collection only has one item (since you are allowed to have multiple elements that have the same class). you cannot read the value property of an entire collection -- so instead, you need to just take the first element of the collection (or find some other method of making sure you get the correct element) and get the value property of that specific element.
2

You can use the jQuery selector.

<script src="http://code.jquery.com/jquery-1.12.0.min.js"></script>
<script>
    $(document).ready(function() {
      $('.buy-btn').click(function(){
          $(this).parent('form').submit();
      });
    });
</script>

<form class="buy-form">
   <label>Quantity:</label>
   <input type="text" class="num-item" />
   <button class="buy-btn">Add to Cart</button>
</form>

The code above will setup a function for each HTML elements that has the css class buy-btn. You can select anything using parent, children, prev, next or find function from jQuery.

Of course this is just a basic exemple I'm showing here, and again some simple example could be :

$('.buy-btn').click(function(){
   $(this).parent('form').submit();
   //var itemCount = $('#item-count').html();
   //itemCount++;
   //$('#item-count').html(itemCount);
   var numItem = $(this).prev('.num-item').val();
   $('#item-count').html(numItem);
});

Comments

2

Unfortunately, you're going to have to loop through the elements in your JavaScript and assign the function to each, however you can do it a bit simpler with some querySelector methods thrown in:

window.onload = function() {
    var getCart = document.getElementById('item-count');
    var forms = document.querySelectorAll('.buy-form');
    var numItems = 0;
    var isNum = function(n) {
        return(!isNaN(parseFloat(n)) && isFinite(n));
    };
    var handler = function(e) {
        (e || event).preventDefault();
        var getInput = this.querySelector('.num-item').value;
        if(isNum(getInput)) {
            numItems += parseInt(getInput);
            getCart.innerHTML = numItems;
            this.reset();            
        } else {
            alert("Please enter a valid number");
        }
    };
    for(var i = 0, len = forms.length; i < len; i++) {
        forms[i].addEventListener('submit', handler);
    }
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.