Change Slideshow Ordering using jQuery

By Rob Gravelle

Change Slideshow Ordering using jQuery

A little while back, I built a simple slideshow for my personal website using jQuery. I didn't want to use a plugin because I found them to be a little bulky for what I needed. That inspired me to write the Create a Simple Automated Slideshow tutorial. Since then, I've had the opportunity to play with the code and add a few features, including Stop, Start, and Pause buttons, as well well some options to reverse, shuffle, and randomize the slide order. In today's tutorial, we'll be taking a closer look at the option controls, button onclick handlers, as well as the code that sorts the slides into the desired order.

The Option Controls

The UI for the option controls won't be winning any style awards, but it does provide plenty of flexibility in how the slideshow runs. There are no text inputs, so as to pretty much eliminate the need for validation. Having said that, be forewarned that selecting a transition time that is greater than that of the slide delay produces some truly wonky and psychedelic viewing!

<div id="controls">
  <h2>Slideshow Options</h2>
  <p><label>Delay (seconds):</label>
  <Select id="interval">
    <option value="1000">1</option>
    <option value="2000">2</option>
    <option value="3000">3</option>
    <option value="4000">4</option>
    <option value="5000" selected>5</option>
    <option value="6000">6</option>
    <option value="7000">7</option>
    <option value="8000">8</option>
    <option value="9000">9</option>
    <option value="10000">10</option>
  </Select>
      Order:
  <label for"forward">Forward</label><input name="order" value="forward" type="radio" checked />
  <label for"reverse">Reverse</label><input name="order" value="reverse" type="radio" />
  <label for"shuffle">Shuffle</label><input name="order" value="shuffle" type="radio" />
  <label for"random">Random</label><input name="order" value="random" type="radio" />
      
  Effect: <label for"slide">Slide</label><input type="radio" name="effect" value="slide">
          <label for"slide">Fade</label><input type="radio" name="effect" value="fade" checked>
       
     <label for"transitionTime">Transition Time (ms)</label>
     <Select id="transitionTime">
        <option value="500">500</option>
        <option value="1000" selected>1000</option>
        <option value="1500">1500</option>
        <option value="2000">2000</option>
       <option value="2500">2500</option>
       <option value="3000">3000</option>
    </Select>
  </p>
  <button id="start">Start Slideshow</button>  
  <button id="pause">Pause Slideshow</button>  
  <button id="stop">Stop Slideshow</button>
</div>

Here are the above controls in the browser:

option_controls.jpg

Regarding the buttons, I'd like to point out what each of them does in more detail. Although it may seem self-evident, I had to make a few decisions. For instance, the start button always restarts the slideshow using the current option settings, whether it is already running, paused, or stopped. Hence, you can think of it as a restart as well as a start. The pause button is only functional when the slideshow is running - sounds trivial, but it requires some coding. It also toggles between a "Pause" and "Continue" state. Finally, the stop button has to do a bit more work that you might have considered. More on that later...

Referencing the Option Controls

Each button's onclick event is bound to its own anonymous function within the jQuery's short-hand onready function. Options are referenced at the top of the Start button's onclick handler so that we pick up the latest settings. Here is the code for that:

$(function() { 
  var timerHandle,
      slideshowDiv = $('#slideshow'),
      divClone     = slideshowDiv.clone(),
      noOfSlides   = slideshowDiv.children('div').length;
     
  $('#start').click(function() {
    var delay          = parseInt( $("#interval option:selected").val() ),
        order          = $('input[name=order]:checked').val(),
        effect         = $('input[name=effect]:checked').val(),
        transitionTime = parseInt( $("#transitionTime option:selected").val() );

  });
});

Note that a couple of the options are converted into integers using the native JS parseInt() function. You can't depend on library functions to convert them for us!

Setting up the Starting Slide Order

The slides can be ordered in one of four ways, only three of which require some reordering. The branching is handled by a switch statement. I like to use it whenever multiple actions may result from the same expression test. It's especially powerful in JavaScript because, unlike other languages, which can only accept integers, the expression may result in any type. The order radio buttons each return a string value that we can test. Let's go over each scenario. Keep in mind that in each case, the slide show will progress through each slide from top to bottom in the stack. Therefore, we must position each slide to the index of its order.

switch ( order ) {
  case 'random':

    break;
  case 'reverse':
    break;
  case 'shuffle':

    break;
}

'random'

A random slide order is one that changes from slide to slide. Hence, after all of the slides have been displayed, the next iteration may be completely different as the next slide is always selected randomly. What that means from a setup perspective is that we need to select a random number from zero to the number of slides minus one. That allows us to select that slide in the stack using the jQuery eq() function. That slide is then detached from the stack and prepended to the first position so that it appears first. Thanks to a feature of the append() function, there is no need to call detach() explicitly. That's because, when you append elements that already exist, the pre-existing ones are removed from the collection for you so that they are essentially moved to their new position in the stack.

case 'random':
  var divIndex = Math.floor(Math.random() * noOfSlides);
  $('#slideshow > div').eq(divIndex).prependTo( $('#slideshow') );
  break;

'reverse'

The reverse code takes advantage of the same automatic removal feature of the append() function. The slide ordering is reversed by invoking the JS Array object's reverse() method:

case 'reverse':
  var slides = $('#slideshow > div');
  $('#slideshow').append(slides.get().reverse());
  break;

'shuffle'

Shuffling a collection of elements did not strike me as something that would be particularly easy to do. That is until I came across a nifty algorithm on jsFiddle. It stores the slide DIVs in a variable, from which it removes one randomly and appends it to the slideshow container until none remain in the variable.

case 'shuffle':
  var slides = $('#slideshow > div');
  while (slides.length) {
    $('#slideshow').append(slides.splice(Math.floor(Math.random() * slides.length), 1)[0]);
  }
  break;

Conclusion

Here is the updated demo. It is fully functioning so feel free to examine the code. If you are uncertain what some of it does, I'll be covering the button code in the next installment.



Rob Gravelle

Rob Gravelle resides in Ottawa, Canada, and has built web applications for numerous businesses and government agencies. Email him for a quote on your project.

Rob's alter-ego, "Blackjacques", is an accomplished guitar player, that has released several CDs. His band, Ivory Knight, was rated as one of Canada's top hard rock and metal groups by Brave Words magazine (issue #92) and reached the #1 spot in the National Heavy Metal charts on ReverbNation.com.



Make a Comment

Loading Comments...

  • Web Development Newsletter Signup

    Invalid email
    You have successfuly registered to our newsletter.
  •  
  •  
  •  
Thanks for your registration, follow us on our social networks to keep up-to-date