1

I'd like to add a some JavaScript only to the product listings page, is this possible with RequireJS and without touching a phtml file? How?

I looked through the documentation and they suggest only three available methods:

  1. Declarative notation using the data-mage-init.
  2. Declarative notation with the <script type="text/x-magento-init" /> tag.
  3. Imperative notation with the <script> tag.

Each of these methods all require adding/editing a phtml file.

Also, the documentation seems to contradict itself.

We strongly recommend that you use the described approaches and do not add inline JavaScript.

This does not makes sense as the 3rd method they suggest is inline JavaScript!?

These methods all seem a little convoluted and over engineered, I starting to think I should only add one JS file with RequireJS for my entire theme, and have it load on every page, even if it's only being used on a few. Is this good practice? I just want to add some jQuery to a few pages.

1 Answer 1

0

Magento 2 documentation is correct, let me show you an example by product list page itself.

<?php if (!$block->isRedirectToCartEnabled()) : ?>
    <script type="text/x-magento-init">
    {
        "[data-role=tocart-form], .form.map.checkout": {
            "catalogAddToCart": {}
        }
    }
    </script>
<?php endif; ?>

As you already said:

Declarative notation using the data-mage-init.

Declarative notation with the <script type="text/x-magento-init" /> tag.

Imperative notation with the <script> tag.

Magento 2 bad practices are you using your script directly inside the .phtml file. Something like

    <script type="text/javascript">
        require(["jQuery"], function($){
            //so ugly and long business logic code
            //best practices is move all business logic code inside JS Components
        });
    </script>

What Magento 2 trying to do is:

  1. Create jQuery UI widget, like the first code block, it is catalogAddToCart ('Magento_Catalog/js/catalog-add-to-cart')
  2. You have options to extend, flexible warranty.
  3. Compatible to knockout template, not only phtml template.
  4. Easy to maintained.

The 3rd method might lead to misunderstanding. For example, I want the catalogAddToCart JS components initialise for specified element only, I will need 3rd method. Something like

<script>
require([
    'jquery',
    'MyLovelyJSComponents',
    'domReady!'
], function ($) {
    $('[data-role=lovely]').lovelyComponent(options);

Cheers.

3
  • thanks but I don't see how the 3rd option differs from what you point out is bad practice, it is inline JavaScript.
    – Holly
    Dec 4, 2017 at 23:27
  • @Holly: In short, bad practices is you leave your business logic code in the template file. The business logic code must be put inside JS components, like what Magento 2 do (UI widget), then from the template file what you did is just initialise it not using it for any specified task in the template. Dec 4, 2017 at 23:36
  • I see, by the way is ‘domReady!’ just likes jQuery’s document.ready function
    – Holly
    Dec 8, 2017 at 6:48

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.