0

I have a several bootstrap sliders which has video and images. Outside of the sliders I would like a button that goes to the slide that has video. The number of the slide that has the video varies from slider. What I would like to do is get the number of slides and then get the slide number of the one with the class video-slide

Is there a way to do this using bootstrap carousel functions or some way using custom js?

Example Markup

<div class="carousel-inner" role="listbox">
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2013/10/clarivu1.jpg);"> </div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2013/10/clarivu2.jpg);"> </div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2013/10/clarivu3.jpg);"> </div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/clarivu8-1.jpg);"> </div>
  <div class="item active" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2013/10/clarivu5.jpg);"> </div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2014/06/optegra7.jpg);"> </div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/ruth-ad.jpg);"> </div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2013/10/clarivu-guidelines.jpg);"> </div>
  <div class="item video-slide">
    <video id="theVideo-83" controls="" preload="none" poster="">
        <source src="http://bootstrap.immaculate.co.uk/wp-content/uploads/making-of-edit4-final-HD.mp4">
    </video>
  </div>
</div>

JS Code, I am using php to get the post ID from WP to create a unique slider for each post.

for(var i<?php the_ID(); ?> = 0; i<?php the_ID(); ?> <= jQuery('.carousel-<?php the_ID(); ?> div.item').length; i<?php the_ID(); ?>++) {
                if (jQuery('.carousel-<?php the_ID(); ?> div.item')[i<?php the_ID(); ?>].hasClass('video-slide')) {
                    //i is the position of the video slide
                    console.log(i<?php the_ID(); ?>);
                }
          }

JS output according to RhysO

for(var i4689 = 0; i4689 <= $('.carousel-4689 div.item').length; i4689++) {
  if ($('.carousel-4689 div.item')[i4689].hasClass('video-slide')) {
    //i is the position of the video slide
      console.log(i4689);
  }
}

Error

$(...)[i4689] is undefined

Click function

$('.po-4689 .link-to-video"').on('click', function() {
    $('.carousel-4689').carousel(*[numberHere]*);
});
Ben H
  • 502
  • 1
  • 7
  • 24
  • Do you like to have the index of the element or just the amount of it? Like in your example there are 9 elements with item and 1 element with video-slide. – Stefan Kert Aug 18 '16 at 12:01
  • at which point of time or an event you need this information? – vijayP Aug 18 '16 at 12:02
  • I need the number on load so I can then use goToSlide() to link to it from a static link. So In my example there are 9 slides, 1 slide with video-slide and that is the 9th slide so i need the number 9 – Ben H Aug 18 '16 at 12:03
  • Can you show your `goToSlide();` function, so we know how, and where, the result should be returned? This would allow us to also improve that function, if necessary, to better fit your scenario. – David Thomas Aug 18 '16 at 12:07
  • See recent edits. Thank you – Ben H Aug 18 '16 at 12:21
  • `var items = Array.from(yourCarouselNode.querySelectorAll('div.item'));` `var videoTiles = items.filter(div => div.classList.contains('video-slide'));` `var videoTileIndices = videoTiles.map(tile => items.indexOf(tile));` – Thomas Aug 18 '16 at 12:52

2 Answers2

2

Use the JQuery selectors, like so:

for(var i = 0; i <= $('div.item').length; i++) {
  if ($('div.item')[i].hasClass('video-slide')) {
    //i is the position of the video slide
  }
}

What this is doing is using a for loop and iterating through the amount of the div.item elements. When one is found that has the video-slide class, the inner block executes. You can also do this using the below code:

$('div.item').each(function(){
  if ($(this).hasClass('video-slide')) {
    //$(this) is the video slide (not the position, but the actual element)
  }
})
TechnicalTophat
  • 1,655
  • 1
  • 15
  • 37
0

Having had some time to spare, I thought I'd offer you a small jQuery plug-in that seems to meet your needs as described and – to some extent – inferred:

// using an immediately-invoked function expression
// (IIFE), to execute the function as soon as it's
// encountered by the browser:
(function($) {

  // assigning the plugin its name, 'goToSlide'
  // and using the $.fn shortcut to the jQuery
  // prototype:
  $.fn.goToSlide = function(opts) {

    // here we use jQuery.extend() to
    // set up the plugin defaults (the
    // first Object) and override those
    // default settings with the user-
    // supplied overrides/options held
    // in the 'opts' Object passed to
    // the plugin:
    var settings = $.extend({
        // the class-name to assign to the
        // currently-active slide-link:
        'activeLinkClass': 'activeLink',

        // the class-name to identify the
        // currently-active slide:
        'activeSlideClass': 'active',

        // CSS selector for the element in 
        // which the controls should be inserted:
        'controlsIn': '#controls',

        // the class-name (or white-space separated
        // list of class-names) to give to those
        // links which link to a 'plain' slide:
        'goToSlideClass': 'fa fa-file-powerpoint-o',

        // as above, but for the links which link
        // to a slide containing a video:
        'goToVideoClass': 'fa fa-file-video-o',

        // the class-name by which a slide can
        // be identified as containing a video:
        'hasVideoClass': 'video-slide',

        // the class with which to style the
        // created <li> elements containing
        // a link to the slides:
        'liClass': 'slideNumber',

        // Boolean, true: shows the number of the
        //                the slide to which the
        //                link will show,
        //          false: hides the number of the
        //                 slide.
        'showPageNumbers': true,

        // the selector by which a slide may be
        // be identified:
        'slideSelector': '.item'
      }, opts),

      // creating an <li> element, and setting
      // its class-name(s) to those defined by
      // the user via the opts Object:
      li = $('<li />', {
        'class': settings.liClass
      }),

      // creating an <a> element, and attaching
      // an anonymous function with which the
      // functionality/behaviour of the <a>
      // is assigned:
      a = $('<a />').on('click', function(e) {

        // the hash (fragment-identifier) of
        // the <a> element identifies a given
        // slide, using an id-selector
        // (a hash is of the form "#fragment"):
        $(this.hash)

          // we add the class-name which identies
          // the currently-active slide to the
          // current slide:
          .addClass(settings.activeSlideClass)

          // finds the current-slide's siblings:
          .siblings()

          // removes the active-slide's class-name:
          .removeClass(settings.activeSlideClass);

        // the current <a> element:
        $(this)

          // adding the class-name which identifies
          // the active <a> element:
          .addClass(settings.activeLinkClass)

          // finds the closest <li> element:
          .closest('li')

          // finds the sibling elements of that
          // closest <li> element:
          .siblings()

          // retrieves the child elements:
          .children()

          // and removes the active-link class:
          .removeClass(settings.activeLinkClass);
      }),

      // empty variables for later, to avoid
      // declaring the same variables within
      // a loop:
      liClone,
      aClone,
      controls,
      slideWrap;

    // returning the 'this' passed to the plug-in, in order
    // to allow for chaining; and iterating over the
    // collection (the 'this'):
    return this.each(function(slideIndex, slideWrapper) {
      // slideIndex: the index of the current element
      // in the collection;
      // slideWrapper: a reference to the current
      // node in the collection, the 'this'.

      // caching the current node in a jQuery object,
      // $(slideWrapper) and $(this) would be identical:
      slideWrap = $(slideWrapper);

      // trying to find the element in which to
      // place the controls, using the selector
      // from the settings Object:
      controls = slideWrap.find(settings.controlsIn);

      // a jQuery object will always be truthy; so
      // here we test if the jQuery object/collection
      // has a length. If it does then a relevant
      // element was found:
      if (controls.length) {

        // therefore we use that element:
        controls = controls;

      // else: no element was found, and the length
      // 0 (zero), and therefore falsey:
      } else {

        // so here we create a <ul> element,
        // and prepend it to the slideWrapper
        controls = $('<ul />').prependTo(slideWrapper);
      }

      // here we find the slide elements, using the
      // selector from the settings Object, and use
      // the each() method to iterate over them:
      slideWrap.find(settings.slideSelector).each(function(index, slide) {
        // index: the index of the current element in the
        // jQuery collection over which we're iterating;
        // slide: a reference to the current element of
        // the collection over which we're iterating.

        // cloning the created <li> node (above)
        liClone = li.clone();

        // cloning the created <a> element, and
        // also its data and functions (the true
        // passed to the clone() method):
        aClone = a.clone(true)

          // using the attr() method, and its
          // anonymous function, to set the
          // href attribute (not property)
          // of the cloned <a>:
          .attr('href', function() {

            // here we assign the id of the current
            // slide element to the string created
            // in the following line (using this form
            // in order that in the event of multiple
            // elements being passed to the plugin
            // the id of each slide is unique, as is
            // the href of each created link):
            slide.id = 'slide_' + slideIndex + '_' + index;

            // returning the assigned slide id prefixed with
            // the '#' character, to indicate a fragment-
            // identifier (and conveniently also a CSS
            // id-selector):
            return '#' + slide.id;
          })

          // setting the text of the cloned <a>, if
          // settings.showPageNumbers is exactly equal
          // to Boolean true (truthy doesn't count) we
          // return the index of the current slide + 1,
          // as JavaScript is zero-based; otherwise
          // if settings.showPageNumbers is anything 
          // other than Boolean true, we return an
          // empty string:
          .text(settings.showPageNumbers === true ? index + 1 : '')

          // here we use the addClass() method to add
          // relevant classes to the cloned <a> element:
          .addClass(function() {

            // we create an Array of class-names,
            return [
              // if the classList of the slide element contains
              // the class which identifies it as containing
              // a video element, we return the class(es)
              // defined in settings.goToVideoClass,
              // otherwise we return the class(es) held in
              // the settings.goToVideoClass (this is because
              // the question identified only two potential
              // options, 'slide' or 'video-slide'; should
              // there be more options than an if or switch
              // should be used instead):
              slide.classList.contains(settings.hasVideoClass) ? settings.goToVideoClass : settings.goToSlideClass,

               // as above, but here we're testing whether
               // the current slide has the class identifying
               // it as currently active; if so we return
               // settings.activeLinkClass, otherwise an
               // empty string:
               slide.classList.contains(settings.activeSlideClass) ? settings.activeLinkClass : '']

                 // joining the array together with a single
                 // white-space:
                 .join(' ');
          });

        liClone
          // appending the cloned <a> to the
          // cloned <li>:
          .append(aClone)

          // appending the cloned <li> (and
          // its contents) to the controls:
          .appendTo(controls);
      });
    });
  };

// here we pass in jQuery in order that, within the function,
// we can use the $ alias for brevity:
})(jQuery);

// using the plug-in, with its defaults:
$('.carousel-inner').goToSlide();

(function($) {
  $.fn.goToSlide = function(opts) {
    var settings = $.extend({
        'activeLinkClass': 'activeLink',
        'activeSlideClass': 'active',
        'controlsIn': '#controls',
        'goToSlideClass': 'fa fa-file-powerpoint-o',
        'goToVideoClass': 'fa fa-file-video-o',
        'hasVideoClass': 'video-slide',
        'liClass': 'slideNumber',
        'showPageNumbers': true,
        'slideSelector': '.item'
      }, opts),
      li = $('<li />', {
        'class': settings.liClass
      }),
      a = $('<a />').on('click', function(e) {
        $(this.hash)
          .addClass(settings.activeSlideClass)
          .siblings()
          .removeClass(settings.activeSlideClass);
        $(this)
          .addClass(settings.activeLinkClass)
          .closest('li')
          .siblings()
          .children()
          .removeClass(settings.activeLinkClass);
      }),
      liClone,
      aClone,
      controls,
      slideWrap;

    return this.each(function(slideIndex, slideWrapper) {
      slideWrap = $(slideWrapper);
      controls = slideWrap.find(settings.controlsIn);

      if (controls.length) {
        controls = controls;
      } else {
        controls = $('<ul />').prependTo(slideWrapper);
      }

      slideWrap.find(settings.slideSelector).each(function(index, slide) {
        liClone = li.clone();
        aClone = a.clone(true)
          .attr('href', function() {
            slide.id = 'slide_' + slideIndex + '_' + index;

            return '#' + slide.id;
          })
          .text(settings.showPageNumbers === true ? index + 1 : '')
          .addClass(function() {
            return [slide.classList.contains(settings.hasVideoClass) ? settings.goToVideoClass : settings.goToSlideClass, slide.classList.contains(settings.activeSlideClass) ? settings.activeLinkClass : ''].join(' ');
          });
        liClone
          .append(aClone)
          .appendTo(controls);
      });
    });

  };
})(jQuery);

$('.carousel-inner').goToSlide();
.slideNumber {
  display: inline-block;
  list-style-type: none;
  margin: 0.2em 0.5em;
  width: 2em;
  height: 2em;
  box-sizing: border-box;
}
.slideNumber a {
  display: block;
  width: 100%;
  height: 100%;
  text-decoration: none;
  text-align: center;
  line-height: 2;
  border: 1px solid transparent;
  box-sixing: border-box;
}
a.slideLink {
  border-color: #0f0;
}
a.videoLink {
  border-color: #f00;
}
.slideNumber a::before {
  margin: 0 0.2em 0 0;
  margin: 0 0.2em 0 0;
}
.slideNumber a.activeLink {
  border-radius: 50%;
  box-shadow: 0 0 0.5em 0.1em limegreen;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div class="carousel-inner" role="listbox">
  <ul class="controls"></ul>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2013/10/clarivu1.jpg);">slide 1</div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2013/10/clarivu2.jpg);">slide 2</div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2013/10/clarivu3.jpg);">slide 3</div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/clarivu8-1.jpg);">slide 4</div>
  <div class="item active" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2013/10/clarivu5.jpg);">slide 5</div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2014/06/optegra7.jpg);">slide 6</div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/ruth-ad.jpg);">slide 7</div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2013/10/clarivu-guidelines.jpg);">slide 8</div>
  <div class="item video-slide">
    <video id="theVideo-83" controls="" preload="none" poster="">
      slide 9
      <source src="http://bootstrap.immaculate.co.uk/wp-content/uploads/making-of-edit4-final-HD.mp4">
    </video>
  </div>
</div>

<div class="carousel-inner" role="listbox">
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2013/10/clarivu1.jpg);">slide 1</div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2013/10/clarivu2.jpg);">slide 2</div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2013/10/clarivu3.jpg);">slide 3</div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/clarivu8-1.jpg);">slide 4</div>
  <div class="item active" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2013/10/clarivu5.jpg);">slide 5</div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2014/06/optegra7.jpg);">slide 6</div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/ruth-ad.jpg);">slide 7</div>
  <div class="item" style="background-image:url(http://bootstrap.immaculate.co.uk/wp-content/uploads/2013/10/clarivu-guidelines.jpg);">slide 8</div>
  <div class="item video-slide">
    <video id="theVideo-83" controls="" preload="none" poster="">
      slide 9
      <source src="http://bootstrap.immaculate.co.uk/wp-content/uploads/making-of-edit4-final-HD.mp4">
    </video>
  </div>
</div>

JS Fiddle demo.

References:

Bibliography:

Community
  • 1
  • 1
David Thomas
  • 249,100
  • 51
  • 377
  • 410