0

I'm writing a shortcode to display responsive Bootstrap carousels that adjust column numbers according to browser width. It works for a single shortcode, and responsively adjusts as follows:

Responsive Boostrap carousel shortcode

However, I'm struggling to implement it so that it will work with multiple instances of the shortcode. I have prepared the shortcode so that it outputs a data-instance attribute that increments for every instance of it.

Here is the shortcode output without the js, which works but is not responsive:

<div id="features-carousel-11" class="carousel responsive posts-list slide light" data-instance="1" data-interval="4000" data-wrap="true" data-columns="3">

<h2 class="text-center title Responsive Features">Responsive Features</h2>

<div class="carousel-inner">

    <div class="item">              
        <div class="post-column col-xs-12 col-sm-4 col-lg-4"><div class="post-wrapper"><div class="post-image"><a href="/features/design/"><i class="fa fa-pencil" aria-hidden="true"></i></a></div><h3><a href="/features/design/">Design</a></h3>We theme the template to suit your needs. <br><div><a href="/wp-admin/post.php?post=313&amp;action=edit">(Edit)</a></div></div></div>
        <div class="post-column col-xs-12 col-sm-4 col-lg-4"><div class="post-wrapper"><div class="post-image"><a href="/features/search-engine-optimised/"><i class="fa fa-search" aria-hidden="true"></i></a></div><h3><a href="/features/search-engine-optimised/">Search Engine Optimised</a></h3>We structure and configure the site so people can find you. <br><div><a href="/wp-admin/post.php?post=314&amp;action=edit">(Edit)</a></div></div></div>
        <div class="post-column col-xs-12 col-sm-4 col-lg-4"><div class="post-wrapper"><div class="post-image"><a href="/features/edit-it-yourself/"><i class="fa fa-pencil-square-o" aria-hidden="true"></i></a></div><h3><a href="/features/edit-it-yourself/">Edit It Yourself</a></h3>You can edit the text and images yourself.<br><div><a href="/wp-admin/post.php?post=315&amp;action=edit">(Edit)</a></div></div></div>
    </div>

    <div class="item active">
        <div class="post-column col-xs-12 col-sm-4 col-lg-4"><div class="post-wrapper"><div class="post-image"><a href="/features/social-media/"><i class="fa fa-facebook" aria-hidden="true"></i></a></div><h3><a href="/features/social-media/">Social Media</a></h3>Let your customers find you anywhere.&nbsp;<br><div><a href="/wp-admin/post.php?post=319&amp;action=edit">(Edit)</a></div></div></div>
        <div class="post-column col-xs-12 col-sm-4 col-lg-4"><div class="post-wrapper"><div class="post-image"><a href="/features/many-features/"><i class="fa fa-cogs" aria-hidden="true"></i></a></div><h3><a href="/features/many-features/">Many Features</a></h3>From testimonials to a multi-location map. <br><div><a href="/wp-admin/post.php?post=362&amp;action=edit">(Edit)</a></div></div></div>
        <div class="post-column col-xs-12 col-sm-4 col-lg-4"><div class="post-wrapper"><div class="post-image"><a href="/features/map/"><i class="fa fa-map-o" aria-hidden="true"></i></a></div><h3><a href="/features/map/">Map</a></h3>Featuring multiple locations, opening hours, &amp; directions.<br><div><a href="/wp-admin/post.php?post=370&amp;action=edit">(Edit)</a></div></div></div>
    </div>

</div>

<ol class="carousel-indicators">
    <li data-target="#features-carousel-11" data-slide-to="0" class=""></li>
    <li data-target="#features-carousel-11" data-slide-to="1" class="active"></li>
</ol>

<br>

<a class="btn btn-default" href="/features">View All</a><br><a class="btn btn-sm btn-default" href="/wp-admin/edit.php?post_type=features"><i class="fa fa-pencil"></i> Edit All</a>            

<a class="left carousel-control" href="#features-carousel-11" role="button" data-slide="prev">
    <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
</a>

<a class="right carousel-control" href="#features-carousel-11" role="button" data-slide="next">
    <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
</a>

Here is the js file, modified from Eric Winton's solution, that works for a single instance of the shortcode:

jQuery(document).ready(function() {

jQuery(window).resize(function() {

  var browserWidth = jQuery(window).innerWidth();

  function resizeSlider(numColumns) {

    //Translate number of bootstrap columns
    if (numColumns == 6) {
      var bsColumn = "col-xs-2";
    } else if (numColumns == 5) {
      var bsColumn = "col-xs-5th";
    } else if (numColumns == 4) {
      var bsColumn = "col-xs-3";
    } else if (numColumns == 3) {
      var bsColumn = "col-xs-4";
    } else if (numColumns == 2) {
      var bsColumn = "col-xs-6";
    } else if (numColumns == 1) {
      var bsColumn = "col-xs-12";
    }

    //Upwrap the slide images from their containing divs
    jQuery(".responsive .post-wrapper").unwrap().unwrap();

    //Wrap every card in the appropriate bootstrap column
    jQuery(".responsive .post-wrapper").wrap("<div class='" + bsColumn + " post-column'></div>");

    var slideWrappers = jQuery(".post-column");

    //Wrap every 3 cards in an item class, forming 1 whole slide
    for (var i = 0; i < slideWrappers.length; i += numColumns) {
      if (i == 0) {
        var activeItem = ' active';
      } else {
        var activeItem = '';
      }

      slideWrappers.slice(i, i + numColumns).wrapAll("<div class='item" + activeItem + "'></div>");
    }

    //Empty the control indicators and rebuild them based on new number of slides
    jQuery(".responsive .carousel-indicators").html("");

    var newNumberOfSlides = jQuery("#myCarousel .item").length;

    for (var s = 0; s < newNumberOfSlides; s++) {
      if (s == 0) {
        var activeClass = "class='active'";
      } else {
        var activeClass = "";
      }

      jQuery(".responsive .carousel-indicators").append("<li data-target='#carousel' data-slide-to='" + s + "'" + activeClass + "></li>");
    }

      }

      var shortcodeColumns = parseInt(jQuery('.responsive.carousel').attr("data-columns"), 10);

      //if we're on a large desktop, organize the slides in 3 columns
      if (browserWidth > 1200) {
        resizeSlider(shortcodeColumns);
        //Large Tablet - 3 columns
      } else if ((browserWidth > 991) && (shortcodeColumns > 3)) {
        resizeSlider(3);
        //Large Tablet - 3 columns
      } else if ((browserWidth > 767) && (shortcodeColumns > 2)) {
        resizeSlider(2);
        //Small Tablet - 2 column
      } else {
        resizeSlider(1);
      }
    }).resize();

    });

How could I now make this work with multiple instances of the shortcode?

I've tried various methods suggested on looping through elements using data attributes ("data-instance", in the above case), but it seems to have difficulty with the js from the line on "var slideWrappers".

Thank you for your assistance.

Your Answer

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

Browse other questions tagged or ask your own question.