Magento 2 – Update Cart Page with AJAX Using Increment/Decrement Buttons

ajaxmagento2qty-incrementshopping-cartupdate-cart

I am trying to update cart without refreshing when someone clicks on-increment or decrement button by creating custom module.

I override the cart/item/default.xml and add button, script to send formkey & qty of the updated cart to updateItemQty controller, I am trying to achieve the same functionality of update shopping cart button with my increment/decrement button

Here is File path which I override:

Module-checkout/view/frontend/templates/cart/item/default.phtml

File: default.xml

<label for="cart-<?= $block->escapeHtmlAttr($_item->getId()) ?>-qty">
                <span class="label"><?= $block->escapeHtml(__('Qty')) ?></span>
                <button type="button" id="increaseQty">+</button>
                <input id="cart-<?= $block->escapeHtmlAttr($_item->getId()) ?>-qty"
                       name="cart[<?= $block->escapeHtmlAttr($_item->getId()) ?>][qty]"
                       data-cart-item-id="<?= $block->escapeHtmlAttr($_item->getSku()) ?>"
                       value="<?= $block->escapeHtmlAttr($block->getQty()) ?>"
                       type="number"
                       size="4"
                       title="<?= $block->escapeHtmlAttr(__('Qty')) ?>"
                       class="input-text qty"
                       data-validate="{required:true,'validate-greater-than-zero':true}"
                       data-role="cart-item-qty"/>
                <button type="button" id="decreaseQty">-</button>
                <input name="form_key" id="form_key" type="hidden" value="<?php echo $block->getFormKey();?>">
</label>

and here is the script:

<?php
   //-- form key load
   echo $this->getBlockHtml('formkey');
?>
<?php echo $this->getBlockHtml('formkey'); ?>
<script type="text/javascript">
  require(["jquery"],function($){
      var formKey = jQuery("[name='form_key']").val();
      $("#increaseQty").on("click",function(){
        var currentQty = $("#cart-<?= $block->escapeHtmlAttr($_item->getId()) ?>-qty").val();
        var newAdd = parseInt(currentQty)+parseInt(1);
        $("#cart-<?= $block->escapeHtmlAttr($_item->getId()) ?>-qty").val(newAdd);
        var updateQty = $("#cart-<?= $block->escapeHtmlAttr($_item->getId()) ?>-qty").val();
        var url = "<?php echo $block->getBaseUrl().'checkout/cart/updateItemQty' ?>";
        $.ajax({
            url: url,
            method: "POST",
            data: { form_key:formKey,"cart[<?= $block->escapeHtmlAttr($_item->getId()) ?>][qty]": updateQty},
            dataType: 'json',
            showLoader:true,
            cache: false,
            success: function(data){
            }
        });

    });
});

currently I just added a script for increment button, I check that its send data perfectly to updateItemQtycontroller similar to update shopping cart button (formkey + qty) but it's not sending data to updatePost controller.

What did I do wrong??

Best Answer

First, change the button from static id to dynamic id, so it will work if cart have more than one product.

File: default.xml

<button type="button" id="increaseQty-<?= $block->escapeHtmlAttr($_item->getId()) ?>-btn">+</button>

<button type="button" id="decreaseQty-<?= $block->escapeHtmlAttr($_item->getId()) ?>-btn">-</button>

And this is the script:

<script type="text/javascript">
require(["jquery",
    "Magento_Checkout/js/model/quote",
    "Magento_Checkout/js/model/cart/totals-processor/default"
    ],
    function($, quote, totalsDefaultProvider){
        var formKey = jQuery("[name='form_key']").val();
        $("#increaseQty-<?= $block->escapeHtmlAttr($_item->getId()) ?>-btn").on("click",function(){
            var currentQty = $("#cart-<?= $block->escapeHtmlAttr($_item->getId()) ?>-qty").val();
            var newAdd = parseInt(currentQty)+parseInt(1);
            $("#cart-<?= $block->escapeHtmlAttr($_item->getId()) ?>-qty").val(newAdd);
            var updateQty = $("#cart-<?= $block->escapeHtmlAttr($_item->getId()) ?>-qty").val();
            var url = "<?php echo $block->getBaseUrl().'checkout/cart/updatePost' ?>";
            $.ajax({
                url: url,
                method: "POST",
                data: { form_key:formKey,"cart[<?= $block->escapeHtmlAttr($_item->getId()) ?>][qty]": updateQty},
                dataType: 'json',
                showLoader:true,
                cache: false,
                success: function(data){
                }
            });
        });
        $("#decreaseQty-<?= $block->escapeHtmlAttr($_item->getId()) ?>-btn").on("click",function(){
            var currentQty = $("#cart-<?= $block->escapeHtmlAttr($_item->getId()) ?>-qty").val();
            if(currentQty>1){
                var newAdd = parseInt(currentQty)-parseInt(1);
                $("#cart-<?= $block->escapeHtmlAttr($_item->getId()) ?>-qty").val(newAdd);
                var updateQty = $("#cart-<?= $block->escapeHtmlAttr($_item->getId()) ?>-qty").val();
            }else{
                alert("Can not choose less than one");exit();
            }
            var url = "<?php echo $block->getBaseUrl().'checkout/cart/updatePost' ?>";
            $.ajax({
                url: url,
                method: "POST",
                data: { form_key:formKey,"cart[<?= $block->escapeHtmlAttr($_item->getId()) ?>][qty]": updateQty},
                dataType: 'json',
                showLoader:true,
                cache: false,
                success: function(data){
                }
            });
        });
    });
</script>