Ad

How To Get Each Different Value Of Form Ruining In Loop With Ajax?

- 1 answer

I have products in loop on collection page and I want to get each product value with jQuery and ajax but code I have, only getting first product value whenever we click on any product's add to cart button, is only showing of first product, below is my code:

function addItem(form_id) {
  var postData = $('#'+form_id).serialize();
  alert(postData);
  $.ajax({
    type: 'POST',
    url: '/cart/add.js',
   dataType: 'json',
  data: $('#'+form_id).serialize(),
  success: addToCartOk,
  error: addToCartFail
});

}

Here I am checking: https://soft-theme.myshopify.com/collections/all its only getting id=27733468427 which ever button I click

Anyone can help me on this, please?

Ad

Answer

You have several forms with the same ID. This is not allowed in HTML DOM: each id="..." attribute should be unique, you can’t use several forms with the same id="add-to-cart". When browser encounters several objects with the same id, it ignores other objects with this id, because id’s should be unique.

You can to use class="add-to-cart" instead.

(Also, remove the id="add" from your add buttons, it's also a duplicate id. You can use class instead.)

Also, you don't really need to pass an ID in your code. You can get the form wrapping the element using this, which refers to the button clicked (however, it needs to be wrapped with a $ to convert the DOM object into the jQuery object):

So, you can use this in your forms:

<form method="post" action="/cart/add" class="add-to-cart">
  <input type="text" name="id" value="27733468427" class="ppp" />
  <input type="submit" name="add"
         value="Add to Cart"
         onclick="addItem(this); return false;"/>
</form>

This is a reference to the <input type="submit" ... /> element. So, you can just get the form wrapping this element by using .closest, like this:

function addItem(button) {
  var $button = $(button);
  var $form = $button.closest('form');
  var postData = $form.serialize();
  alert(postData);
  $.ajax({
    type: 'POST',
    url: '/cart/add.js',
   dataType: 'json',
  data: $form.serialize(),
  success: addToCartOk,
  error: addToCartFail
});

This is not the recommended way of doing things, though. onclick="..." is a deprecated way of doing things, because you are mixing JavaScript with HTML. Instead, it's recommended to remove onclick="..." alltogether and bind the event callback in a <script> code. To do this, just remove the onclick in your forms:

<form method="post" action="/cart/add" class="add-to-cart">
  <input type="text" name="id" value="27733468427" class="ppp" />
  <input type="submit" name="add"
         value="Add to Cart"/>
</form>

And bind the method using class add-to-cart (make sure you’ve made it into the class, otherwise my code won’t work):

$(function() {
  $("form.add-to-cart").submit(function () {
    var $form = $(this);
    var postData = $form.serialize();
    alert(postData);
    $.ajax({
      type: 'POST',
      url: '/cart/add.js',
      dataType: 'json',
      data: $form.serialize(),
      success: addToCartOk,
      error: addToCartFail
    });
    return false;
});

The code above does the following:

  • The $(function() { ... }); around the code makes sure that the code is only run when all the elements are loaded.
  • $("form.add-to-cart") finds all the forms with class="add-to-cart"
  • $("form.add-to-cart").submit(function () { ... }); adds a callback function. This function will be called each time any form with class="add-to-cart" is submited.

This is the recommended alternative to onclick.

Update: the first version of my code had a bug: since $("form.add-to-cart").submit is attached to the form, and not to the button, we should use $(this) to refer to the form. We don’t need closest in the second version of the code.

Ad
source: stackoverflow.com
Ad