Magento – Add Ajax Quantity Increment and Decrement Button on cart page in Magento 2

magento2magento2.2magento2.2.4

I want to implement Ajax Quantity Increment and Decrement Button functionality on cart items on Cart page (not on Product detail and Minicart). I didn't find any article or any module to achieve this. Could anyone help me with it?

Best Answer

@Lalit Kaushik You can try in this way.

app/code/Custom/ShoppingCart/registration.php

    <?php

\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Custom_ShoppingCart',
__DIR__
);

app/code/Custom/ShoppingCart/etc/module.xml

    <?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Custom_ShoppingCart" setup_version="1.0.0">
    </module>
</config>

app/code/Custom/ShoppingCart/view/frontend/layout/checkout_cart_index.xml

    <?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock  name="checkout.cart.form">
            <block class="Magento\Framework\View\Element\RendererList" name="checkout.cart.item.renderers.override" as="renderer.list.custom"/>
            <arguments>
                <argument name="renderer_list_name" xsi:type="string">checkout.cart.item.renderers.override</argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

app/code/Custom/ShoppingCart/view/frontend/layout/checkout_cart_item_renderers.xml

<body>
        <referenceBlock name="checkout.cart.item.renderers.override">
        <block class="Magento\Checkout\Block\Cart\Item\Renderer" as="default" template="Custom_ShoppingCart::cart/item/default.phtml" />
        <block class="Magento\Checkout\Block\Cart\Item\Renderer" as="simple" template="Custom_ShoppingCart::cart/item/default.phtml" />
        </referenceBlock>
    <referenceBlock name="checkout.cart.item.renderers.default.actions.edit" remove="true" />
    <referenceBlock name="checkout.cart.item.renderers.simple.actions.edit" remove="true" />
</body>

app/code/Custom/ShoppingCart/view/frontend/templates/cart/item/default.phtml

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

// @codingStandardsIgnoreFile

/** @var $block \Magento\Checkout\Block\Cart\Item\Renderer */

$_item = $block->getItem();
$product = $_item->getProduct();
$isVisibleProduct = $product->isVisibleInSiteVisibility();
/** @var \Magento\Msrp\Helper\Data $helper */
$helper = $this->helper('Magento\Msrp\Helper\Data');
$canApplyMsrp = $helper->isShowBeforeOrderConfirm($product) && $helper->isMinimalPriceLessMsrp($product);
?>
<tbody class="cart item">
    <tr class="item-info">
        <td data-th="<?php echo $block->escapeHtml(__('Item')); ?>" class="col item">
            <?php if ($block->hasProductUrl()):?>
                <a href="<?php /* @escapeNotVerified */ echo $block->getProductUrl() ?>"
                   title="<?php echo $block->escapeHtml($block->getProductName()) ?>"
                   tabindex="-1"
                   class="product-item-photo">
            <?php else:?>
                <span class="product-item-photo">
            <?php endif;?>
            <?php echo $block->getImage($block->getProductForThumbnail(), 'cart_page_product_thumbnail')->toHtml(); ?>
            <?php if ($block->hasProductUrl()):?>
                </a>
            <?php else: ?>
                </span>
            <?php endif; ?>
            <div class="product-item-details">
                <strong class="product-item-name">
                    <?php if ($block->hasProductUrl()):?>
                        <a href="<?php /* @escapeNotVerified */ echo $block->getProductUrl() ?>"><?php echo $block->escapeHtml($block->getProductName()) ?></a>
                    <?php else: ?>
                        <?php echo $block->escapeHtml($block->getProductName()) ?>
 <?php endif; ?>
                </strong>
                <?php if ($_options = $block->getOptionList()):?>
                    <dl class="item-options">
                        <?php foreach ($_options as $_option) : ?>
                            <?php $_formatedOptionValue = $block->getFormatedOptionValue($_option) ?>
                            <dt><?php echo $block->escapeHtml($_option['label']) ?></dt>
                            <dd>
                                <?php if (isset($_formatedOptionValue['full_view'])): ?>
                                    <?php /* @escapeNotVerified */ echo $_formatedOptionValue['full_view'] ?>
                                <?php else: ?>
                                    <?php /* @escapeNotVerified */ echo $_formatedOptionValue['value'] ?>
                                <?php endif; ?>
                            </dd>
                        <?php endforeach; ?>
                    </dl>
                <?php endif;?>
                <?php if ($messages = $block->getMessages()): ?>
                    <?php foreach ($messages as $message): ?>
                        <div class="cart item message <?php /* @escapeNotVerified */ echo $message['type'] ?>"><div><?php echo $block->escapeHtml($message['text']) ?></div></div>
                    <?php endforeach; ?>
                <?php endif; ?>
                <?php $addInfoBlock = $block->getProductAdditionalInformationBlock(); ?>
                <?php if ($addInfoBlock): ?>
                    <?php echo $addInfoBlock->setItem($_item)->toHtml() ?>
                <?php endif;?>
            </div>
        </td>

        <?php if ($canApplyMsrp): ?>
            <td class="col msrp" data-th="<?php echo $block->escapeHtml(__('Price')); ?>">
                <span class="pricing msrp">
                    <span class="msrp notice"><?php /* @escapeNotVerified */ echo __('See price before order confirmation.'); ?></span>
                    <?php $helpLinkId = 'cart-msrp-help-' . $_item->getId(); ?>
                    <a href="#" class="action help map" id="<?php /* @escapeNotVerified */ echo($helpLinkId); ?>" data-mage-init='{"addToCart":{"helpLinkId": "#<?php /* @escapeNotVerified */ echo $helpLinkId;?>","productName": "<?php /* @escapeNotVerified */ echo $product->getName(); ?>","showAddToCart": false}}'>
                        <span><?php /* @escapeNotVerified */ echo __("What's this?"); ?></span>
</a>
                </span>
            </td>
        <?php else: ?>
            <td class="col price" data-th="<?php echo $block->escapeHtml(__('Price')); ?>">
                <?php echo $block->getUnitPriceHtml($_item); ?>
            </td>
        <?php endif; ?>
        <td class="col qty" data-th="<?php echo $block->escapeHtml(__('Qty')); ?>">
            <div class="field qty">
               <label class="label" for="cart-<?php /* @escapeNotVerified */ echo $_item->getId() ?>-qty">
                    <span><?php /* @escapeNotVerified */ echo __('Qty') ?></span>
               </label>
               <div class="control qty">
           <!--   <form action="<?php /* @escapeNotVerified */ //echo $block->getUrl('checkout/cart/updatePost') ?>"
          method="post"
          id="form-validate"
          data-mage-init='{"validation":{}}'
          class="form form-cart"> -->

               <button type="button" value="update_qty" name="update_cart_action" id="<?= /* @escapeNotVerified */ $_item->getId() ?>-dec"  class="decreaseQty-<?= /* @escapeNotVerified */ $_item->getId() ?>">-</button>
                <input id="cart-<?= /* @escapeNotVerified */ $_item->getId() ?>-qty"
                   name="cart[<?= /* @escapeNotVerified */ $_item->getId() ?>][qty]"
                   data-cart-item-id="<?= /* @escapeNotVerified */ $_item->getSku() ?>"
                   value="<?= /* @escapeNotVerified */ $block->getQty() ?>"
                   type="number"
                   size="4"
                   title="<?= $block->escapeHtml(__('Qty')) ?>"
                   class="input-text qty"
                   data-validate="{required:true,'validate-greater-than-zero':true}"
                   data-role="cart-item-qty" readonly/>
               <button type="button" value="update_qty" name="update_cart_action" id="<?= /* @escapeNotVerified */ $_item->getId() ?>-upt" class="increaseQty-<?= /* @escapeNotVerified */ $_item->getId() ?>">+</button>
       </form>
 </div>
</div>
  </td>

        <td class="col subtotal" data-th="<?php echo $block->escapeHtml(__('Subtotal'));?>">
 <?php if ($canApplyMsrp): ?>
                <span class="cart msrp subtotal">--</span>
            <?php else: ?>
                <?php echo $block->getRowTotalHtml($_item); ?>
            <?php endif; ?>
        </td>
    </tr>
    <tr class="item-actions">
        <td colspan="100">
            <div class="actions-toolbar">
                <?php /* @escapeNotVerified */ echo $block->getActions($_item) ?>
            </div>
        </td>
    </tr>
</tbody>
<script type="text/javascript">
require(["jquery","Magento_Checkout/js/action/get-totals","Magento_Customer/js/customer-data"],function($, getTotalsAction, customerData){
  $(document).ready(function(){
    $(document).on('click', 'button.increaseQty-<?= /* @escapeNotVerified */ $_item->getId() ?>,button.decreaseQty-<?= /* @escapeNotVerified */ $_item->getId() ?> ', function(){
        var $this = $(this);
        var ctrl = ($(this).attr('id').replace('-upt','')).replace('-dec','');
        var currentQty = $("#cart-"+ctrl+"-qty").val();
        if($this.hasClass('increaseQty-<?= /* @escapeNotVerified */ $_item->getId() ?>')){
            var newAdd = parseInt(currentQty)+parseInt(1);
             $("#cart-"+ctrl+"-qty").val(newAdd);
        }
        else if($this.hasClass('decreaseQty-<?= /* @escapeNotVerified */ $_item->getId() ?>')) {
             if(currentQty>0){
                var newAdd = parseInt(currentQty)-parseInt(1);
                $("#cart-"+ctrl+"-qty").val(newAdd); 
             }
        }
        var form = $('form#form-validate');
        var url="<?php  echo $block->getUrl('checkout/cart/updatePost') ?>";
        $.ajax({
                url: url,
                type: "POST",
                data: form.serialize(),
 showLoader: true,
                cache: false,
                success: function(res){
                  var parsedResponse = $.parseHTML(res);
                    var result = $(parsedResponse).find("#form-validate");
                    var sections = ['cart'];
                    $("#form-validate").replaceWith(result);
                    // The mini cart reloading
                    customerData.reload(sections, true);

                    // The totals summary block reloading
                    var deferred = $.Deferred();
                    getTotalsAction([], deferred);
                },
                error: function (xhr, status, error) {
                    var err = eval("(" + xhr.responseText + ")");
                    console.log(err.Message);
                }
            });
            return true;
    });
  });

});
</script>
Related Topic