Nik Las
Nik Las

Reputation: 29

Shopify cart reduce quantity Ajax opposite of Shopify.addItem()

For transparency: this is an exact copy of a request that I have made in a Shopify forum, but I did not get any help there (except for an expensive offer to solve the issue...).

I own a Shopify store that uses a popup cart before checkout. I am using the following code on the popup cart, in order to enable customers to increase or decrease the quantity of items in the cart:

<div class="input-group m-0">
      <input type="button" value="-" class="button-minus" data-field="quantity">
      <input id="{{ item.variant.id }}" type="number" step="1" max="" value="{{ item.quantity }}" name="quantity" class="quantity-field">
      <input type="button" value="+" class="button-plus" data-field="quantity" onclick="Shopify.addItem({{ item.variant.id }}, 1)">
</div>

As you might see I am using the Shopify.addItem() function when onclick is triggered in order to increase the amount of items per product in the cart. This function really works. Sadly I did not find any function to reduce the quantity by 1. So therefore I wrote some JavaScript, but it sadly does not work. Find the code here:

$('.input-group').on('click', '.button-minus', function(e) {
    e.preventDefault();
    var fieldName = $(e.target).data('field');
    var parent = $(e.target).closest('div');
    var currentVal = parseInt(parent.find('input[name=' + fieldName + ']').val(), 10);
    var currentVariant = parseInt(parent.find('input[name=' + fieldName + ']').attr('id'), 10);
    jQuery.post('/cart/change.js', { quantity: currentVal - 1, id: currentVariant });    
});

Upvotes: 0

Views: 2932

Answers (2)

Nik Las
Nik Las

Reputation: 29

I used the results from HymnZ. Sadly the provided code needed small changes to work in my shop. Find it below! And honors to HymnZ for the hint to the solution!

Shopify.reduceItem = function(variant_id, quantity, callback) {
  var quantity = quantity;
  quantity = quantity-1;
  var params = {
    type: 'POST',
    url: '/cart/change.js',
    data: 'quantity=' + quantity + '&id=' + variant_id,
    dataType: 'json',
    success: function(line_item) {
      if ((typeof callback) === 'function') {
        callback(line_item);
      }
      else {
        Shopify.cartPopap(variant_id);
        Shopify.onItemAdded(line_item);
      }
    },
    error: function(XMLHttpRequest, textStatus) {
      Shopify.onError(XMLHttpRequest, textStatus);
    }
  };
  jQuery.ajax(params);
};

Upvotes: 0

HymnZzy
HymnZzy

Reputation: 2925

Your currentVal & currentVariant declaration is wrong. Need to add " inside a property

var currentVal = parseInt(parent.find('input[name="' + fieldName + '"]').val(), 10);
var currentVariant = parseInt(parent.find('input[name="' + fieldName + '"]').attr('id'), 10);

+ jQuery.post needs to be in an aysnc ... await function. Try this

$('.input-group').on('click', '.button-minus', async function(e) {
  ......
  await jQuery.post('/cart/change.js', { quantity: currentVal - 1, id: currentVariant });    
});

The above should work, but wouldn't it be nifty if we can use Shopify.removeItem ? Create a function like this and add it to scripts.js.liquid file

Shopify.removeItem = async function(id,quantity){
  await $.ajax({
    method:'POST',
    url:'/cart/change.js',
    data:{ id:id, quantity:(--quantity) },
    dataType: 'json'
  })
}

and change the quantity buttons to

<div class="input-group m-0">
  <input type="button" value="-" class="button-minus" data-field="quantity" onclick="Shopify.removeItem({{ item.variant.id }},{{ item.quantity }})">
  <input id="{{ item.variant.id }}" type="number" step="1" max="" value="{{ item.quantity }}" name="quantity" class="quantity-field">
  <input type="button" value="+" class="button-plus" data-field="quantity" onclick="Shopify.addItem({{ item.variant.id }}, 1)">
</div>

Upvotes: 2

Related Questions