7

I want to use ajax to change the quantity of one item on the cart magento 2 cart page.

I have added this javascript:

$('.cart.item .qty').on({ change: function() { var post_url = $(this).attr('data-post-url'); $.post(post_url, $(this).serialize(), function(data) { $(".form-cart").replaceWith(data.cart_html); $("#cart-totals").replaceWith(data.totals_html); $("#cart-totals").trigger('contentUpdated'); }, "json"); } }); 

The value of data.totals_html is

<div id="cart-totals" class="cart-totals" data-bind="scope:'block-totals'"> <!-- ko template: getTemplate() --><!-- /ko --> <script type="text/x-magento-init"> { "#cart-totals": { "Magento_Ui/js/core/app": {"components":{"block-totals":....} </script> 

When I change the quantity, the total component content is not refresh..

Anyone have an idea for dynamically update the total component after replace the html code?

4 Answers 4

3

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Great and simple answer :). However, for some reason, when reloading the cart totals this way, it will never have an estimated shipping cost. It will always be zero :(
Where we apply quantity increment and decrements.
Qty increment decrement not working if i run this code. Do you know how to fix this
1

You can consult this way to ajax re-load block totals in cart:

define([ "jquery", 'Magento_Checkout/js/action/get-payment-information', 'Magento_Checkout/js/model/totals' ], function($, getPaymentInformationAction, totals) { $('.cart.item .qty').on({ change: function() { var post_url = $(this).attr('data-post-url'); $.post(post_url, $(this).serialize(), function(data) { //custom your update $(".form-cart").replaceWith(data.cart_html); $("#cart-totals").replaceWith(data.totals_html); //reload block total var deferred = $.Deferred(); totals.isLoading(true); getPaymentInformationAction(deferred); $.when(deferred).done(function() { totals.isLoading(false); }); //end }, "json"); } }); }); 

Comments

1

Just run the following js code -

require( [ 'Magento_Checkout/js/model/quote', 'Magento_Checkout/js/model/cart/totals-processor/default' ], function( quote, totalsDefaultProvider ) { totalsDefaultProvider.estimateTotals(quote.shippingAddress()); } ); 

For more information, please refer to this article.

Disclaimer: I am the CEO of MexBS (The company who published this article)

1 Comment

Would this still be true for Magento 2.2.6? I tried this - but unlike Surendra's answer it does not trigger reloading the totals block in the cart.
1

Change the code in cartQtyUpdate.js to this one

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); /* Minicart reloading */ customerData.reload(sections, true); /* Totals summary reloading */ var deferred = $.Deferred(); getTotalsAction([], deferred); }, error: function (xhr, status, error) { var err = eval("(" + xhr.responseText + ")"); console.log(err.Message); } }); }); $(document).on('click', '.alo_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); /* Minicart reloading */ customerData.reload(sections, true); /* Totals summary reloading */ var deferred = $.Deferred(); getTotalsAction([], deferred); }, error: function (xhr, status, error) { var err = eval("(" + xhr.responseText + ")"); console.log(err.Message); } }); }); }); }); 

now it works well

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.