skip to Main Content

I am building a special Shopify page, where multiple items can be added to the cart via Shopify’s Ajax API. I set up a test version of the page here: https://monstermuffin.com/pages/ajax-test

Here is the js code I have currently to set up the asynchronous call / add to cart:

  
  Shopify.queue = [];

  Shopify.moveAlong = function() {
    if (Shopify.queue.length) {
      var request = Shopify.queue.shift();
      Shopify.addItem(request.variantId, request.quantity, request.properties, Shopify.moveAlong);
    }
    else {
      //document.location.href = '/cart';
    }
  };

  Shopify.addItem = function(id, qty, properties, callback) {
    var params = {
      quantity: qty,
      id: id, 
      properties: properties
    };
    $.ajax({
      type: 'POST',
      url: '/cart/add.js',
      dataType: 'json',
      data: params,
      success: function(){
        if(typeof callback === 'function'){
          callback();
        }
      },
      error: function(){
      }
    });
  }

  function push_to_queue(variantID, quantity, properties,callback) {
    Shopify.queue.push({
      variantId: variantID,
      quantity: quantity,
      properties: properties
    });

    if(typeof callback === 'function'){
      callback();
    }
  }
  
  $('#add-helmet-panties').click(function() {
    $('.quantity-field:visible').each(function() {
      
      var thisVariant = $(this).prop('id');
      var thisQuantity = parseInt($(this).val(), 10) || 0;
      var theseProps = {
        'Base Colour': $('#base-colour').val()
      }

      push_to_queue(thisVariant, thisQuantity, theseProps, Shopify.moveAlong);
      
    });
  });

Oddly, it is currently adding only 3 or 4 of the products to the cart at a time.

I’ve really struggled with this! Any advice would be appreciated. I can provide more information if needed!

2

Answers


  1. It is simple… you want your click listener to simply iterate the NON-ZERO variants, and add them to the queue. So call push_to-queue. Do not bother with the call to move along. Instead, once the queue is all filled, then you call move along.

    It is funny, I wrote the pseudo-code for this originally, and Caro at Shopify re-wrote it into this version, now public for almost ten years… neat.

    Also it seems your concept of the base colour property is off? It is being applied to all the variants. Why bother? Instead, set it as a cart attribute where the product has a base colour, once. More efficient. Makes more sense.

    Login or Signup to reply.
  2. var length = {{ product.variants.size }};
    
      $(document).ready(function () {
        $("#quantity-0").focus();    
        $("#submit-table").click(function(e) {     
          e.preventDefault();
          //array for Variant Titles
          var toAdd = new Array();
          var qty ;
          for(i=0; i < length; i++){
    
            toAdd.push({
              variant_id: $("#variant-"+i).val(),        
              quantity_id: $("#quantity-"+i).val() || 0
            });
          }
          function moveAlong(){
            if (toAdd.length) {
              var request = toAdd.shift();
              var tempId= request.variant_id;
              var tempQty = request.quantity_id;
              var params = {
                type: 'POST',
                url: '/cart/add.js',
                data: 'quantity='+tempQty+'&id='+tempId,
                dataType: 'json',
                success: function(line_item) { 
                  alert("Product Added to Cart");
                  moveAlong();
    
                },
                error: function() {
                  //console.log("fail");
                  moveAlong();
    
                }
              };
              $.ajax(params);
            }
            else {              
              document.location.href = '/cart';
            }  
          };
          moveAlong();
        });
      });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <form class="page-width"> 
        <table>
          <tr>
            <th>Name</th>
            <th>Quantity</th>
            <th>Stock</th>
          </tr>
          {% for variant in product.variants %}
          <tr>
            <td>{{ variant.title }} - {{ variant.price | money }}</td>
            <td>
              <input type="hidden"  value="{{ variant.id }}" id="variant-{{ forloop.index0 }}"/>
              <input  type="number" value="0" id="quantity-{{ forloop.index0 }}"/>
            </td>
            <td>{{ variant.inventory_quantity  }} in stock.</td>
          </tr>
          {% endfor %}
        </table>
    
    
        <div class="purchase-section{% if product.variants.size > 1 %} multiple{% endif %}">
          <div class="purchase">
            {% unless product.available %}
            <p>Sold Out</p>
            {% else %}
            <br />
            <input type="submit" value="Add!" class="btn" id="submit-table"/>
    
            {% endunless %}<input type="reset" class="btn" value="Reset">
          </div>   
        </div>
      </form>
    </div>
    <script type="text/javascript" charset="utf-8">
      //<![CDATA[
      // Including jQuery conditionally.
      if (typeof jQuery === 'undefined') {
        document.write({{ "http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" | script_tag | json }});
        document.write('<script type="text/javascript">jQuery.noConflict();</script>');
      }
      //]]>
    </script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search