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.
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.
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.
Hi the current solution is good although I had the same problem, here's how I solved it:
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>
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: