Combining navigation on the easySlider jQuery plugin

Dec 23

Today, I was putting together a proof-of-concept for a new website design that included a media ‘slider’ on the home page. I did a bit of searching and came across the Easy Slider 1.7 plugin which uses jQuery to simplify this task. Score! We love jQuery here at TPI because it takes heavy-coding Javascript tasks and makes them really simple to accomplish and usually more interactive and fun.

This plugin seemed to have all we needed except one thing. There was a choice in navigation between arrows left and right (previous and next) OR numeric/individual item navigation below. (For this case, we’ll use actual ‘Sliders’ as our representation of the easySlider. Hungry yet?)

Navigation illustration

For the design we’re envisioning, both systems needed to be utilized. It seemed like a simple fix and I set about combining both  navigation types to show up at the same time. Problem. For some reason, the next/previous buttons weren’t behaving properly when you used the numeric navigation below to choose an item! If you clicked on an item in the numeric nav, the next button would inexplicably send the gallery zooming off into space and then slowly return to the first item in the list.

How do we fix this!? Good ol’ scheming and know-how to the rescue! I’ll give you the quick-and-dirty since I’m pretty sure that’s what you’re interested in, anyway.

First, to show both navigations, go into easySlider1.7.js and find this part:

if(options.controlsShow){
var html = options.controlsBefore;
if(options.numeric){
html += '<ol id="'+ options.numericId +'"></ol>';
} else {
if(options.firstShow) html += '<span id="'+ options.firstId +'"><a href=\"javascript:void(0);\">'+ options.firstText +'</a></span>';
html += ' <span id="'+ options.prevId +'"><a href=\"javascript:void(0);\">'+ options.prevText +'</a></span>';
html += ' <span id="'+ options.nextId +'"><a href=\"javascript:void(0);\">'+ options.nextText +'</a></span>';
if(options.lastShow) html += ' <span id="'+ options.lastId +'"><a href=\"javascript:void(0);\">'+ options.lastText +'</a></span>';
};

html += options.controlsAfter;
$(obj).after(html);
};

And change it to this:

if(options.controlsShow){
var html = options.controlsBefore;
if(options.numeric){
html += '<ol id="'+ options.numericId +'"></ol>';
if(options.firstShow) html += '<span id="'+ options.firstId +'"><a href=\"javascript:void(0);\">'+ options.firstText +'</a></span>';
html += ' <div id="arrows"><span id="'+ options.prevId +'"><a href=\"javascript:void(0);\">'+ options.prevText +'</a></span>';
html += ' <span id="'+ options.nextId +'"><a href=\"javascript:void(0);\">'+ options.nextText +'</a></span></div>';
if(options.lastShow) html += ' <span id="'+ options.lastId +'"><a href=\"javascript:void(0);\">'+ options.lastText +'</a></span>';
} else {
if(options.firstShow) html += '<span id="'+ options.firstId +'"><a href=\"javascript:void(0);\">'+ options.firstText +'</a></span>';
html += ' <span id="'+ options.prevId +'"><a href=\"javascript:void(0);\">'+ options.prevText +'</a></span>';
html += ' <span id="'+ options.nextId +'"><a href=\"javascript:void(0);\">'+ options.nextText +'</a></span>';
if(options.lastShow) html += ' <span id="'+ options.lastId +'"><a href=\"javascript:void(0);\">'+ options.lastText +'</a></span>';
};

html += options.controlsAfter;
$(obj).after(html);
};

Then find this part:

if(options.numeric){
for(var i=0;i<s;i++){
$(document.createElement("li"))
.attr('id',options.numericId + (i+1))
.html('<a rel='+ i +' href=\"javascript:void(0);\">'+ (i+1) +'</a>')
.appendTo($("#"+ options.numericId))
.click(function(){
animate($("a",$(this)).attr('rel'),true);
});
};
} else {
$("a","#"+options.nextId).click(function(){
animate("next",true);
});
$("a","#"+options.prevId).click(function(){
animate("prev",true);
});
$("a","#"+options.firstId).click(function(){
animate("first",true);
});
$("a","#"+options.lastId).click(function(){
animate("last",true);
});
};

And change it to this:

if(options.numeric){
for(var i=0;i<s;i++){
$(document.createElement("li"))
.attr('id',options.numericId + (i+1))
.html('<a rel='+ i +' href=\"javascript:void(0);\">'+ (i+1) +'</a>')
.appendTo($("#"+ options.numericId))
.click(function(){
animate($("a",$(this)).attr('rel'),true);
});
};
$("a","#"+options.nextId).click(function(){
animate("next",true);
});
$("a","#"+options.prevId).click(function(){
animate("prev",true);
});
$("a","#"+options.firstId).click(function(){
animate("first",true);
});
$("a","#"+options.lastId).click(function(){
animate("last",true);
});
} else {
$("a","#"+options.nextId).click(function(){
animate("next",true);
});
$("a","#"+options.prevId).click(function(){
animate("prev",true);
});
$("a","#"+options.firstId).click(function(){
animate("first",true);
});
$("a","#"+options.lastId).click(function(){
animate("last",true);
});
};

NOW, to make it work properly (and here’s the kicker), parseInt!!!!!

Find the ‘animate’ function (~line 140):

function animate(dir,clicked){
if (clickable){
clickable = false;
var ot = t;
switch(dir){
case "next":
t = (ot>=ts) ? (options.continuous ? t+1 : ts) : t+1;
break;
case "prev":
t = (t<=0) ? (options.continuous ? t-1 : 0) : t-1;
break;
case "first":
t = 0;
break;
case "last":
t = ts;
break;
default:
t = dir;
break;
};

And insert this itttty bitty little parseInt:

function animate(dir,clicked){
if (clickable){
clickable = false;
var ot = t;
t = parseInt(t);
switch(dir){
case "next":
t = (ot>=ts) ? (options.continuous ? t+1 : ts) : t+1;
break;
case "prev":
t = (t<=0) ? (options.continuous ? t-1 : 0) : t-1;
break;
case "first":
t = 0;
break;
case "last":
t = ts;
break;
default:
t = dir;
break;
};

Thats it! Wow, that seemed a lot harder than it was. We figured out that the two navigations were treating the current item differently (one as an integer, one as a string – who knew!) so basically we’re just telling them all to be integers so both methods will work the same.

For reference, here’s another little proof of concept we drew up. Sliders. Get it? We’re hilarious, i know. (click the pickles OR the ketchup. CRAZY!) easySlider plugin ‘Sliders’ demo