2

I would like to initialize a jQuery carousel plugin on the product details page, the slide carousel.

I've found two ways to do it, but am wondering if there is a better way.

First off, I added the script to the plugin to my theme's require-config.js file with:

// app/design/frontend///require-config.js var config = {

// When load 'requirejs' always load the following files also
deps: [
    "js/main" // path to main.js script
],
paths: {
    'slick': 'js/vendor/jquery/slick.min' // path to script in my theme
},
shim: {
    'slick': {
        deps: ['jquery'],
        exports: 'jQuery.fn.slick'
    }
}

};

Then I found that I could initialise the carousel in my main.js with:

define([
        "jquery",
        "slick"
    ],
    function($) {
        "use strict";

        $('.products-related .product-items').slick();

        return;
    }
);

But this approach means the slick.min.js file is loaded on every page, and $('.products-related .product-items').slick(); is executed on every page.

I could initialize the script only on the product details page by adding the following <script> tag to app/code/Magento/Catalog/view/frontend/templates/product/list/items.phtml

<script>
    require([
        "jquery",
        "slick"
    ], function ($) {
        $('.products-related .product-items').slick();
    });
</script>

But this means I need to override a template file and use an inline script, is there a better way? Where I would load an external script just on the product details page?

It probably has little performance impact if I just add it to main.js which is easier but I'm just curious.

Thanks!

3 Answers 3

2

You can use data-mage-init for call Widget Js in template

First extend layout catalog_product_view to your theme layout dir (Don't edit core files)

Add attribute data-mage-init to div wrap you want to slide

<ol class="products list slider items product-items" data-mage-init='{"SlickSlide": {}}'> 
  // Slide content here
</ol>


Here is requirejs-config.js

var config = {
   map: {
       '*': {
          'SlickSlide' :  'js/init',
          'slick' :  'js/slick.min',

       }
   },
};

File init.js just simple widget standard of magento to init your lib

define([
'jquery',
'slick',
], function (jQuery, slick) {
'use strict';

jQuery.widget('mage.Slick', {
    options: {
        "test": 111// HERE YOU CAN PASS ANY PARAMETERS
    },

    /**
     * Initialize widget
     */
    _create: function () {
        var self = this,
            slick;

        console.log('test');
        jQuery(".product-items").slick({
            dots: true,
            infinite: true,
            slidesToShow: 3,
            slidesToScroll: 3
        });

    },

});

return jQuery.mage.Slick;

});
2
  • thanks this was helpful, but I found that with jQuery(".product-items") it's kind of defeating the point of using data-mage-init. I described another approach in an answer I gave.
    – Holly
    Apr 13, 2017 at 6:41
  • also, do you know how do you use the options in jQuery(".product-items").slick({...? Can these be overiden with data-mage-init='{"SlickSlide": {}}'?
    – Holly
    Apr 13, 2017 at 6:42
0

You can do this with layout XML.

In app/design/frontend/Path_To_Active_Theme/Magento_Catalog/layout/catalog_product_view.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
    <head>
        <link src="Packagename_Modulename:path_to_js.js"/>
    </head>
</page>

Then just remove it from your requirejs-config.js file.

Inside of app/design/frontend..../Packagename_modulename/web throw your js file in there

0

While @mrtuvn answer worked well and put me on the correct path I found an alternative solution which suited my scenario better was as follows. (I took most of it from the devdocs.)

So first in my theme's require-config.js I have:

// app/design/frontend/<your_vendor_name>/<your_theme_name>/require-config.js
var config = {
    map: {
        '*': {
            'productSlickCarousel' :  'js/product-slick-init',
            'slickCarousel': 'js/vendor/jquery/slick.min'
        }
    },
    shim: {
        slickCarousel: ['jquery']
    }
};

Then I put the jQuery Slick plugin in: app/design/frontend/<your_vendor_name>/<your_theme_name>/js/vendor/jquery/slick.min

Then I added the script to initialise the plugin:

// app/design/frontend/<your_vendor_name>/<your_theme_name>/web/js/product-slick-init.js
define([
    'jquery',
    'slickCarousel'
], function ($) {
    'use strict';

    return function (config, element) {
        var slickConfig = {
            infinite: true,
            slidesToShow: 3,
            slidesToScroll: 3,
            prevArrow: "<i class='previous'></i>",
            nextArrow: "<i class='next'></i>"
        };
        $(element).slick(slickConfig);
    };
});

Finally in the app/design/frontend/<your_vendor_name>/<your_theme_name>/Magento_Catalog/templates/product/list/items.phtml template file I called the initializing script with data-mage-init:

<ol class="products list items product-items" data-mage-init='{"productSlickCarousel": {}}'>

This approach also has the advantage of allowing you to use $(element) so that any the script is only initialized on the element which it data-mage-init is used.

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.