Magento – How to Extend and initialize a JS Widget with Proper Custom Namespace / Replace Existing Widget

javascriptjquerymagento2

I want to modify the mage.catalogAddToCart JS widget of Magento 2.

According to http://devdocs.magento.com/guides/v2.0/javascript-dev-guide/javascript/custom_js.html I have to do a

$.widget('foobar.myCatalogAddToCart', $.mage.catalogAddToCart, {


}

But I was not able to init it with a

<script type="text/x-magento-init">
            "#product_addtocart_form": {
                "myCatalogAddToCart": { }
            }
        }
</script>

also not

<script type="text/x-magento-init">
            "#product_addtocart_form": {
                "foobar.myCatalogAddToCart": { }
            }
        }
</script>

I am confused, because Magento Base also does not use the Namespace in its initialization. It is just

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

When I call my Widget mage.myCatalogAddToCart it works.

Questions:

  1. How can I use a proper custom namespace (foobar in the example)?

Bonus:

  1. Can I also rewrite catalogAddToCart compeletly, so I do not have to change the .phtml initialization?

Edit

Answer to Question 1.) I must have made some other mistake. The first one (init with "myCatalogAddToCart") is working now. The namespace just does not seem to matter.

But still try to figure out the answer to question 2.)

Best Answer

I've answered the first part of your question in another question https://magento.stackexchange.com/a/96371/28167

The short answer is, using your example, "foobar.myCatalogAddToCart" is completely arbitrary.

All that matters is that it must match what get's returned. That text has no other meaning outside the scope of your widget and other widgets that extend your widget as you are doing with catalogAddToCart.

<script type="text/x-magento-init">
    "#product_addtocart_form": {
            "myCatalogAddToCart": { }
        }
    }
</script>

The only way this would work is if you create a requirejs-config mapping to your widget file. That would look like this

var config = {
    map: {
        '*': {
            "myCatalogAddToCart": 'Vendor_Module/js/path/to/widget'
        }
    }
};

"myCatalogAddToCart" could be any unique string so long as it is the same in your script tag and in the requirejs-config.js file.