0

I have a Slick slideshow. My nodes have a Timer field. Right now, I am setting the time of the slick slide like so:

Drupal.behaviors.mrpeanut = {
  attach: function (context, settings) {
    var $slider = $("#slick-views-slideshow-page-1-slider");
    $slider.once('mrpeanut').on("afterChange", function(event, slick, currentSlide) {
            slideTime = $('div.slide--' + slick.currentSlide + ' div.field--name-field-timer').text();
            $slider.slick("setOption", "autoplaySpeed", slideTime);
        });
  }
}

However, I had some feedback that I may be better off to preprocess the field then attach a JS settings array with all the timer values. This is what I started piecing together based on some discussion in Slack (thanks, @nikathone).

In mrpeanut.module:

function mrpeanut_preprocess_node(&$variables) {
    $variables['#attached']['library'][] = 'mrpeanut/mrpeanut';
    $node = $variables['node'];
    $slideTime = $node->hasField('field_timer') ? $node->get('field_timer')->value : 20000;
    $slideTime = $slideTime * 1000; // Convert milliseconds to seconds
    $variables['#attached']['drupalSettings']['slideTime'][$node->id()] = $slideTime;
}

In mrpeanut.js:

(function($, Drupal, drupalSettings) {
    Drupal.behaviors.mrpeanut = {
        attach: function(context, settings) {
            var $slider = $("#slick-views-slideshow-page-1-slider");
            var slideTime = drupalSettings.slideTime;

            // Get Node ID from the article
            var nodeAbout = $('.slide').find('article').attr('about');
            var nodeID = nodeAbout.substring(6, $('.slide').find('article').attr('about').length);

            $slider.once('mrpeanut').on("afterChange", function(event, slick, currentSlide) {
                $slider.slick("setOption", "autoplaySpeed", slideTime);
            });
        }
    }
})(jQuery, Drupal, drupalSettings);

However, it's not actually setting the correct timer values. One issue I'm having is that I need to capture all Node IDs from the view (whereas now I am only getting the first). Second, I'm setting the time slide on the afterChange instead of initially all-at-once.

  • I have test your code, I think this not gonna work because ['#attached'] should added to render array if you try it in hook_form_alter for example $form['#attached']['drupalSettings']['slideTime'] = $slideTime; it works. – berramou Sep 29 '18 at 21:42
  • It's part of a view. Would it work if I somehow put my code in the view? – MrPeanut Sep 29 '18 at 22:17
  • View, which hook ?or maybe you can move your code to the hook_page_attachments(array &$page) to attach library to entire page: something like $page['#attached']['library'][] = 'mrpeanut/mrpeanut'; you will need the field_timer value ;( ! – berramou Sep 29 '18 at 22:28
  • The library is getting attached properly... I think the issue is that the field_timer value is getting added to a new array with each node load (from preprocess_node) instead of to the same array (but I could be wrong). – MrPeanut Sep 30 '18 at 16:08
0

Here's my final mrpeanut.js:

(function($, Drupal, drupalSettings) {
    Drupal.behaviors.mrpeanut = {
        attach: function(context, settings) {
            var slider = $("#slick-views-slideshow-page-1-slider");
            var slideTime = drupalSettings.slideTime;
            var nodeIdArray = []
            $('article').each(function(i){
                var nodeAbout = $(this).attr('about');
                var nodeID = nodeAbout.substring(6, $(this).attr('about').length);
                nodeIdArray.push(nodeID);
            });

            slider.once('mrpeanut').on("afterChange", function(event, slick, currentSlide) {
                slider.slick('slickSetOption', 'autoplaySpeed', slideTime[nodeIdArray[currentSlide]], true);
            });
        }
    }
})(jQuery, Drupal, drupalSettings);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.