2

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??

2 Answers 2

0

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>
0

Step 1:

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>

Step 2:

Create js.phtml file Magento_Theme/templates/js.phtml

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

Step 3:

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);
            }
        });
       });
      });
    });

Step 4:

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

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

Now the qty update work using ajax.

4
  • is it possible to makes changes by custom module? Dec 23, 2019 at 10:12
  • Yeah, you can also try like that. Dec 23, 2019 at 10:19
  • Failed to load resource: the server responded with a status of 404 (Not Found) Dec 23, 2019 at 10:32
  • first try to accomplish it with custom module, once all your requirement matches you'll able to move it to your custom module once you understand the flow. Dec 23, 2019 at 10:53

Your Answer

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

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