3

I have implemented Ajax to my "Add to Cart" button so that customers can add products to their cart without reloading the page.

Here is bare minimum of code which I used in order to achieve successful Ajax call in Product Details page for adding Product to Cart without refresh:

<form method="post" action="<?php /* @escapeNotVerified */ echo $block->getSubmitUrl($_product); ?>" id="product_addtocart_form"<?php if ($_product->getOptions()) {echo ' enctype="multipart/form-data"';} ?>>
    <input type="hidden" name="product" value="<?php /* @escapeNotVerified */ echo $_product->getId(); ?>" />

    <button type="submit">Add to Cart</button>

    <script type="text/x-magento-init">
        {
            "#product_addtocart_form": {
                "catalogAddToCart": {
                    "bindSubmit": true
                }
            }
        }
    </script>
</form>

Well, this far everything works perfect. When the button is clicked, message appears in page about successful Product adding to Cart.

The problem is when Product cannot be added to Cart for some reason (for example, out of stock). Then instead of message showing in page dynamically, the refresh happens and only then message pops out in page.

How do I stop refresh in those cases and simply just show the message about reason why Product is not able to be added to Cart?

2
  • Post ur controller/ajax file code
    – Jackson
    Mar 17, 2017 at 6:41
  • @AnkitShah they both are Magento2 standard files from blank theme without any changes made.
    – Toms Bugna
    Mar 17, 2017 at 11:34

1 Answer 1

7

In order to achieve this, you need to follow these steps:

1) Override Magento2 default theme js file by copying it from this path: vendor/magento/module-catalog/view/frontend/web/js/catalog-add-to-cart.js (this is a path if you used composer for magento2 installation) to your custom theme path (may be a custom module as well, but in my case I had custom theme): app\design\frontend\TheBrewCompany\default\Magento_Catalog\web\js\catalog-add-to-cart.js

2) Find in code mage.catalogAddToCart widget -> ajaxSubmit function -> $.ajax call -> success call back -> and if (res.backUrl) statement (in my case it was line 86-88).

3) Delete code that is inside that if statement and leave it empty. These two lines:

window.location = res.backUrl;
return;


At this point the redirect will not happen anymore. But then comes next problem: message about reason why product could not be added to cart is not printed in web-site. Instead, it will be printed in next page load (refresh or page change). To print those messages, do following steps:

1) In the same catalog-add-to-cart.js file, at the top, define two more files:

'Magento_Customer/js/customer-data',
'jquery/jquery-storageapi'

2) In function declaration add two more arguments: _ and customerData

3) In the previously emptied if statement, insert this code:

customerData.reload('messages');


Done. At the end, the changes should look something like this: beginning of file:

    define([
    'jquery',
    'mage/translate',
    'jquery/ui',
    'Magento_Customer/js/customer-data',
    'jquery/jquery-storageapi'
], function($, $t, _, customerData) {

and ajax success callback:

if (res.backUrl) {
    customerData.reload('messages');
}


And final step: in order to make changes work, do following steps:

1) delete pub/static/frontend directory

2) run command php bin/magento setup:di:compile

3) run command php bin/magento setup:static-content:deploy

4) run command php bin/magento cache:flush

1
  • The perfect answer. I would like to make one suggestion customerData.reload('messages'); reloads complete customer data instead of the just message. In order to just reload message var sections = ['messages']; customerData.invalidate(sections); customerData.reload(sections, true); Mar 25, 2020 at 8:25

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.