6

How to update cart qty using ajax magento 2

I want to change qty on cart page. I don't want to use the update button. It should be update automatically without reloading the page.

3 Answers 3

9

Reload totals cart after ajax change quantity 1. Step

In your custom them create ( Magento_Theme/layout/checkout_cart_index.xml )

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
    <referenceContainer name="content">
        <block class="Magento\Framework\View\Element\Template" name="cart.ajax.qty.update"  template="Magento_Theme::js.phtml" after="-"/>
    </referenceContainer>
</body>

2.Step

creat js.phtml file ( Magento_Theme/templates/js.phtml )

<script>
require ([
        'jquery',
    ],
    function ($) {
       $(window).on("load", function () {
            require([
                'custom'
            ]);
        });
    });

3. Step create custom.js file in theme web folder ( Namespace/Yourtheme/web/js/custom.js )

    define([
    'jquery',
    'Magento_Checkout/js/action/get-totals',
    'Magento_Customer/js/customer-data'
     ], function ($, getTotalsAction, customerData) {

    $(document).ready(function(){
    $(document).on('change', 'input[name$="[qty]"]', function(){
        var form = $('form#form-validate');
        $.ajax({
            url: form.attr('action'),
            data: form.serialize(),
            showLoader: true,
            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);
            }
        });
       });
      });
    });

4.Step ( map your js file )

Create requirejs-config.js on your theme root ( Namespace/yourtheme/requirejs-config.js)

var config = {
   map: {
    '*': {
        custom:'js/custom'
    }
  }
};

Now the qty update work using ajax If have any issue ask in comment.

5
  • Hello Surendra Kumar Ahir. Please elaborate the answer. We are trying to achieve this. Commented Oct 12, 2018 at 5:05
  • Hello, I am trying to implement you method on my Magento 2.2 store but having some difficulties. It would be great if you can take a look at this thread: magento.stackexchange.com/questions/253404/…
    – Greg
    Commented Dec 13, 2018 at 9:19
  • Hi, I followed each step and It works fine but sometimes I get the error in console “customer-data.js:89 Uncaught TypeError: Cannot read property ‘sectionLoadUrl’ of undefined” and due to the error totals not loading. When I remove this js ‘Magento_Checkout/js/action/get-totals’ then It works fine. Anyone help me to resolve the error? Thank You
    – Vishal
    Commented Nov 22, 2019 at 12:19
  • after ajax qty update how to get cart subtotal I tried with totals.totals()['subtotal'] but it takes old subtotal Commented Aug 13, 2020 at 14:02
  • Hi - how do I apply this on the whole website? Commented Mar 7, 2022 at 8:56
1

I tried your approach, it is working for me if i enter the quantity in quantity textfield. But it doesn't work if i use increment/decrement signs to update the quanity. Can you please guide me how can do this.

$('.qty-down-fixed-onclick-page-cart, .qty-up-fixed-onclick-page-cart').on('click',  ajaxQuantityUpdate);

Above code works but only once. After ajax call it stops working. Secondly my product image breaks after ajax call.

0

Hi the current solution is good although I had the same problem, here's how I solved it:

  1. Edit this file Magento_Checkout/templates/cart/form.phtml in your own theme. Remove the following part:

    <script>
    require([
    'jquery',
    'mage/mage'
    ], function ($) {
    'use strict';       
    $(".qty-down-fixed-onclick-page-cart").click(function() {
        var number_click = parseInt($(this).closest('div.qty').find('.input-text.qty').attr('data-qty'));
        var val_input = $(this).closest('div.qty').find('.input-text.qty').val();
        val_input = parseInt(val_input);
        if(val_input <= number_click){
            val_input = number_click;
        }
        else{
            val_input = val_input - number_click;
        }
        $(this).closest('div.qty').find('.input-text.qty').val(val_input);
        return false;
    });
    $(".qty-up-fixed-onclick-page-cart").click(function() {
        var number_click_2 = parseInt($(this).closest('div.qty').find('.input-text.qty').attr('data-qty'));
        var val_input = $(this).closest('div.qty').find('.input-text.qty').val();
        val_input = parseInt(val_input);
        val_input = val_input + number_click_2;
        $(this).closest('div.qty').find('.input-text.qty').val(val_input);
        return false;
    });
    });
    </script>
    
  2. Edit the custom.js file form the current solution to:

    define(['jquery','Magento_Checkout/js/action/get-totals',
    'Magento_Customer/js/customer-data',
    'mage/mage'
    ], function ($, getTotalsAction, customerData) {
    'use strict';
    $(document).ready(function(){
        $(document).on(
            'input',
            'input[name$="[qty]"]',
            function(){
                reloadCart();
        });
        $(document).on(
            'click',
            '.qty-down-fixed-onclick-page-cart',
            function(){
            var number_click = parseInt($(this).closest('div.qty').find('.input-text.qty').attr('data-qty'));
            var val_input = $(this).closest('div.qty').find('.input-text.qty').val();
            var current_val = val_input;
            val_input = parseInt(val_input);
            if(val_input <= number_click){
                val_input = number_click;
            }
            else{
                val_input = val_input - number_click;
            }
            $(this).closest('div.qty').find('.input-text.qty').val(val_input);
            if (current_val > 1)
            {
                reloadCart();
            }
            return false;
        }
        );
        $(document).on(
            'click',
            '.qty-up-fixed-onclick-page-cart',
            function(){
                var number_click_2 = parseInt($(this).closest('div.qty').find('.input-text.qty').attr('data-qty'));
                var val_input = $(this).closest('div.qty').find('.input-text.qty').val();
                val_input = parseInt(val_input);
                val_input = val_input + number_click_2;
                $(this).closest('div.qty').find('.input-text.qty').val(val_input);
                reloadCart();
                return false;
            }
        );
    });
    
    function reloadCart() {
        var form = $('form#form-validate');
        $.ajax({
            url: form.attr('action'),
            data: form.serialize(),
            showLoader: true,
            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);
            }
        });
    }
    });
    

This way you'll get:

  1. On input "event" and not "change". This prevents an additional click outside the quantity box when you manually enter a quantity.
  2. On every qty increment or decrement the cart will reload on click of the arrows unless quantity is 1 on the arrow down click.
1
  • How can i get cartSubtotal in this custom.js Commented Aug 11, 2020 at 7:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.