Question

for the Slick slider of the Slider Banner PageBuilder module, I am trying to add an 'init' call, so I can run a function on initialization of the slider. First I tried adding a new js file called widget-hero.js on this path:

Example/PageBuilderExtensionSlider/view/base/web/js/content-type/slider/appearance/default/widget-hero.js

in which I have this code:

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

    return function (config, element) {

        var $element = $(element);

        console.log('from Example/PageBuilderExtensionSlider/view/base/web/js/content-type/slider/appearance/default/widget-hero.js');

        console.log($element);

        $element.on('init', function(slick) {
            console.log('Slick Init from widget-hero.js');
        });

    };
});

It normally works and console logs 'Slick Init from widget-hero.js' , but there are times when it doesn't work, so, I reckon sometimes the file gets read while the slider hasn't been initialized yet.

Then I tried editing the file that initializes the Slick slider by copying to this path:

Example/PageBuilderExtensionSlider/view/base/web/js/content-type/slider/appearance/default/widget.js

On that files I have this code:

define([
    'jquery',
    'Magento_PageBuilder/js/events',
    'slick'
], function ($, events) {
    'use strict';

    return function (config, sliderElement) {
        var $element = $(sliderElement);

        /**
         * Prevent each slick slider from being initialized more than once which could throw an error.
         */
        if ($element.hasClass('slick-initialized')) {
            $element.slick('unslick');
        }

        $element.slick({
            autoplay: $element.data('autoplay'),
            autoplaySpeed: $element.data('autoplay-speed') || 0,
            fade: $element.data('fade'),
            infinite: $element.data('is-infinite'),
            arrows: $element.data('show-arrows'),
            dots: $element.data('show-dots')
        });

        // Redraw slide after content type gets redrawn
        events.on('contentType:redrawAfter', function (args) {
            if ($element.closest(args.element).length) {
                $element.slick('setPosition');
            }
        });

        console.log('from Example/PageBuilderExtensionSlider/view/base/web/js/content-type/slider/appearance/default/widget.js');

        console.log($element);

        $element.on('init', function(slick) {
            console.log('Slick Init from widget.js');
        });
    };
});

But the init call doesn't work here, I do get the console log of these lines console.log('from Example/PageBuilderExtensionSlider/view/base/web/js/content-type/slider/appearance/default/widget.js'); console.log($element);

But I am not getting console.log('Slick Init from widget.js');

Suming up, init is not working from the file where we initialize the slick slider, any idea why this could be happening?

My console log: enter image description here

Was it helpful?

Solution

This sounds a lot like you're experiencing a race condition with the default and widget-hero.js widgets. Most likely what's happening is the default widget is being called first and Slick is initialized before your event handler is registered.

You'll want to ensure you register your on event handler before the call .slick(), as the initialization of Slick could happen before your code can register the event. In your second example you should move the event registration up:

define([
    'jquery',
    'Magento_PageBuilder/js/events',
    'slick'
], function ($, events) {
    'use strict';

    return function (config, sliderElement) {
        var $element = $(sliderElement);

        /**
         * Prevent each slick slider from being initialized more than once which could throw an error.
         */
        if ($element.hasClass('slick-initialized')) {
            $element.slick('unslick');
        }

        $element.on('init', function(slick) {
            console.log('Slick Init from widget.js');
        });

        $element.slick({
            autoplay: $element.data('autoplay'),
            autoplaySpeed: $element.data('autoplay-speed') || 0,
            fade: $element.data('fade'),
            infinite: $element.data('is-infinite'),
            arrows: $element.data('show-arrows'),
            dots: $element.data('show-dots')
        });

        // Redraw slide after content type gets redrawn
        events.on('contentType:redrawAfter', function (args) {
            if ($element.closest(args.element).length) {
                $element.slick('setPosition');
            }
        });
    };
});

Within Page Builder we do not yet have a method of declaring in which order the store front widgets should load. If you're adding a new appearance that also needs to initialize Slick you should follow the same principle as shown above, registering your event before you initialize.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top