Sometimes, We Write Stuff...
MooTools Content Slider Update - Numbered Nav
So, here we are again... yet another content slider update! By far, the most requested addition I have received is a way to 'jump' to other slides, along with a navigation for it. I'm actually going to take that one step further, and show you how to accomplish that with a dynamically created navigation list!
Overview
This tutorial will build upon the past div slider tutorials on this site, so I'm just going to focus mainly on the creation/functionality of our new numbered nav. (If you haven't gone over those yet, I highly recommend that you glance over them to get familiar with everything.) In particular, I will be explaining the use of the 'element.adopt' method, the dynamic creation of html elements and their contents, and then the code to tie it all into our original slider. I'll also add in a little code that prevents a graphical glitch that the past slider was suffering from. (The 'stuttering' effect that was happening when the prev/next buttons were rapidly pushed.)
As always, I'll try to keep this simple – and please feel free to ask questions, call me a jackass, say thanks, etc. in the comments area! The full code and example link are located below.
The XHTML
Our XHTML is basically identical to our last tutorial. I have made two minor changes, though. First, I've turned our 'controls' div into an unordered list, and assigned the buttons as anchors inside of each list:
<ul id="controls"> <li id="prevbtn"><a>prev</a></li> <li id="playbtn"><a>pause</a></li> <li id="nextbtn"><a>next</a></li> </ul>
I've also added another unordered list, with an id of 'num_nav': (I'll give you one guess what that will be for...)
<ul id="num_nav"> </ul>
The CSS
Very little has been changed here. Other than changing the CSS a bit to handle the controls being inside of list items, the only new addition is the styling/positioning for our numbered navigation. It's just some basic styling:
#num_nav {
width: 500px;
height: 30px;
position: absolute;
top: 427px;
left: 105px;
list-style: none;
}
#num_nav li {
display: block;
float: left;
width: 20px;
height: 20px;
margin: 2px;
border: 1px solid;
border-color: #666666;
background-color: #333333;
}
#num_nav a {
display: block;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
}
The Javascript/MooTools
This is where the majority of the changes/additions are located, as you can probably imagine.
Config Area Changes
First, I've added a few important new things to our 'config' area:
var numNav = new Array(); //create an array to hold our dynamically created number navigation
var isSliding = 0; //will be used to prevent multiple clicking
var numNavHolder = $('num_nav'); //get element for our numbered nav
Dynamic Number Buttons Creation
Now we will dynamically create our numbered navigation items, and then insert them into the 'numNavHolder' that we just defined above. This makes use of the native 'adopt' method of MooTools Elements, and I think you'll find it quite powerful! We'll do this in our 'setup' area of the code, inside the setup loop for each slide. The first thing we'll do is create the anchor element and the list item element. As we create our anchor element, we'll also give it a class and insert content (the number) into it:
var numItem = new Element('li', {id: 'num'+index});
var numLink = new Element('a', {
'class': 'numbtn',
'html': (index+1)
});
Next, we'll use the 'adopt' method to insert our 'numLink' inside the 'numItem' we just created, and then we'll put this new nav item into the 'num_nav' unordered list. (Think about those wooden Russian dolls... as that's essentially what we're doing here.) Note that I've also used the javascript function 'push()' here to add each new anchor into an array, which we'll be using in a moment:
numItem.adopt(numLink); //inserts link into list item numNavHolder.adopt(numItem); //inserts link item into the numbered nav numNav.push(numLink); //push element into an array, for accessing later
Lastly, we'll highlight our initial active button:
var initNum = numNav[itemNum];
origColor = initNum.getStyle('color'); //get original link color
initNum.setStyles({
'background-color': '#272727',
'color': '#FF6600'
});
Updated Movement Function
In order to keep this small and easy-to-understand, I condensed the animation functions into a single function called 'slideMove' It's nearly identical to the previous 'slideForward' and 'slideBackward' functions from the earlier tutorials, except that it accepts two parameters, direction and passedID. Direction is required, and as you may have guessed it tells our movement function 'how' to move – 0 is for backward, 1 is for forward, and 2 is for a direct jump to a number. (Obviously, the 'passedID' parameter is only required when direction=2.) Here's a look at the entire 'slideMove' function:
var slideMove = function(direction, passedID){
//get item to slide out
var curItem = items[itemNum];
var curNumItem = numNav[itemNum];
//change index based on value of 'direction' parameter
if(direction == 1){
if(itemNum < (numItems - 1)){
itemNum++;
}
else{
itemNum = 0;
}
}
else if(direction == 0){
if(itemNum > 0){
itemNum--;
}
else{
itemNum = (numItems - 1);
}
}
else {
if(itemNum != passedID){
itemNum = passedID;
}
}
//now get item to slide in using new index
var newItem = items[itemNum];
var newNumItem = numNav[itemNum];
//set up our animation stylings for slide
var item_in = new Fx.Morph(newItem, {
duration: transitionTime,
transition: Fx.Transitions.Cubic.easeOut,
link: 'ignore',
//click prevention actions
onStart: function(){
isSliding = 1; //prevents extra clicks
},
onComplete: function(){
isSliding = 0; //allow clicks again
}
});
var item_out = new Fx.Morph(curItem, {
duration: transitionTime,
transition: Fx.Transitions.Cubic.easeOut,
link: 'ignore'
});
//number nav button effects
var num_in = new Fx.Morph(newNumItem, {
duration: 100,
transition: Fx.Transitions.linear,
link: 'ignore'
});
var num_out = new Fx.Morph(curNumItem, {
duration: 100,
transition: Fx.Transitions.linear,
link: 'ignore'
});
//we will set a beginning value here
//this is so that it gives the illusion of continuous motion from one direction, even after the first cycle of items
item_in.start({
'left': [502, 0]
});
//no beginning values needed, since we always want to push the old item out to the left
item_out.start({
'left': '-502'
});
num_in.start({
'background-color': '#272727' ,
'color': '#FF6600'
});
num_out.start({
'background-color': '#333333' ,
'color': origColor
});
};
Take special notice of the 'onStart' and 'onComplete' events I'm making use of in the item_in animation (FX) setup above. (These are used to set the 'isSliding' variable's value, which we will use to prevent the extra clicks glitching.)
Hooking Up the Buttons
The next/prev/play buttons are all essentially the same, except for one thing. Through the use of an 'if' statement, I am checking the 'isSliding' variable to determine whether to perform the movement function or not. Here's an example with the 'next' button:
nextBtn.addEvent('click', function(){
if(isSliding == 0){
if(isPaused == 0){
$clear(theTimer);
theTimer = slideMove.periodical(slideTimer, this, 1);
}
slideMove(1);
}
});
The code for the new number navigation is quite similar. The only difference is that we will be passing the index of the button into our move function, so that it knows what slide to jump to. I've also set them to change the cursor to 'pointer' on hover, making it more like a button. Check it out:
numNav.each(function(element, index) {
var origColor = element.getStyle('color');
element.addEvents({
'click' : function(){
if(isSliding == 0 && itemNum != index){
if(isPaused == 0){
$clear(theTimer);
theTimer = slideMove.periodical(slideTimer, this, 1);
}
slideMove(2, index);
//alert("index: " + index);
}
},
'mouseenter' : function() {
this.setStyle('cursor', 'pointer');
}
});
});
Conclusion
And there you have it, a timed content slider with basic controls... and now also with dynamically created slide number buttons!
Demo/Download
+ Comments
Really nice... There's only one thing missing in my opinion. The pause effect on a mouseOver event.
I'm trying to add it but with no success. Can Someone try it?
@Raff
If it were written as a class, it would be a lot easier[cleaner] to $clear the timer.
You would have methods that look like
buttonAction: function(){} //where all of the events for the buttons would be defined
startTimer: function(){}, endTimer: funciton(){},
In your buttonActions method, you can do a mouseover[mouseenter is better] for the buttons that would call the endTimer method, and have a mouseout[mouseleave] event that would start the timer again.
Writing it as a class would make it infinitely more flexible than what you currently have.
Hi Mark, you are absolutely correct about this being more clean/flexible as a class. I think that should probably be the next (and final) tutorial in this 'slider' series. (This started out as a simple timed slideshow, and I honestly had not planned on taking it this far...* grin *)
Hello, first of all I'm sorry for my bad english. Second, I have a question. How about if replace li's content in num_nav with thumbnails, and make really cool looking gallery? I was trying to do something like that, but with no good result :(. It'll be interesting for me to know is it possible, or it is not a good idea. Thanks in advance.
Hello smile – your English is just fine, no worries! ![]()
As for your question: It would be possible to do that, but I know there are much better MooTools scripts/classes out there for creating image galleries.
One of my next posts will be a list of quality MooTools classes/scripts... so I will be sure to include a gallery or two! (I hope to make that post sometime this weekend.)
Hi Daniel! Your script is great and one of the best ones I could find specially for Mootools 1.2
The script is working fine but I have 1 problem :
I don't want the number tabs in my slider so I remove the
<ul id="num_nav">
</ul>
from the html but after that the slider stops working :(
Is there a way to make this work like it does right now with the num-nav removed ?
Thanks ![]()
Daniel don't bother about my previous comment. I didn't notice that you had 3 versions of this script
I'm a satisfied guy now.... just got it like I wanted!
Just 1 last "wish" :D As I'm using your control_slider script so there is no num-nav in that one, this means that after we have slided through all the elements we go back to number 1 element... Now in this one we see the number 1 highlighted once again which shows us that we are on element 1..
Now in the other slider where there is no num-nav we never get to know which element we are in, is there a way to show some other kind of effect after we come back to the first element ? Nothing really important, but if you ever plan to work more on this then please keep this in mind
Thanks
You're my hero!
Hello, Daniel. Thank You for your answer. And I'll wait for that list. It will be very interesting for me. Have a nice day and smile ![]()
Speedy and Smile, thanks so much for your pleasant comments! (And I do apologize that I'm so slow to respond... business has been really intense over these last few weeks.)
@Speedy: I probably won't do much more with this until I convert it into a class... but I hope to get to that soon. I think your 'wish' will be fairly easy to accomplish at that point.
@Smile: Yeah, I'll get a nice list put together for us this weekend. You can expect that post on Sunday, more than likely. ![]()
Thanks for your kind reply Daniel
You're doing a great job helping pathetic people like me with your great scripts lol ![]()
Forget about my previous wish... Its not that important
The most tempting thing I see when I visit your site is the fading rollover/hover on the links on the sidebar/download,view demo buttons... I'm trying to learn how to do this for a long time and even more when I saw dragoninteractive.com. Now I know how to do it with images and I was also able to do it with mootools 1.11 using this method : http://demos111.mootools.net/Fx.Styles Now I want to do the same with 1.2 using this method : http://demos.mootools.net/Mouseenter But the problem is that I can't get it to work with more than 1 element as its using IDs for the effect to work... Now as you may have guessed by now that I'm a noob in js/mootools so I can't do it on my own lol I just want to know how we can change it to work with multiple lists like we can do with the 1.11 version.
Sorry for going OT and also for asking to such a busy person like you but I know you are a GREAT guy and will help me when you have nothing else to do and getting bored for hours... after watching every show on the TV, listening all the songs on the iPod if you ever get time please guide me hehe...
Thanks
Hey all, sorry I haven't posted anything yet! Without going into too much detail, let's just say my stomach has been upset this weekend...
I'll be totally covered up Monday and Tuesday, but I should have a little time on Wednesday to finish the article.
Hey come on why do you need to be sorry?
Lol I mean really you are already cool enough to share you're hard work with us so yea man no sorry worry here ![]()
On the other side, really sorry to hear that you are not well... I mean I know how much I hate to be ill when I'm working on designing projects lol!
Get well soon mate and please take your time
First of all that slide is very cool, and thx for your time to share for us ![]()
I notice on previous post that Shnoab ask a question so I wonder is any posibility change to verical mode?
"Shoab said: Jul 11, 2008 04:39
How would one go about making this scroll vertically instead of horizontally. "
best regards
Vojc
Hi Vojc (and Shoab) - basically, all you would need to do is change the initialization and the animation to use 'top' instead of 'left'. Hope that makes sense!
thx for quick reply Daniel. So... I look and try changing from left to top but not working for me. I'm litlle dummy about program coding so any sugestion is wellcome... thx again
Vojc
I figure out, I think so. Just add one line of code:
//since the viewer obviously has javascript on, we can remove the 'first_item' class
if(index == 0){
element.removeClass('first_item');
element.setStyle('left', "0");
}
else{
element.setStyle('left', "0");
element.setStyle('top', "185");
element.setStyle('opacity', "0");
}
and
//this is so that it gives the illusion of continuous motion from one direction, even after the first cycle of items
item_in.start({
'left': [0, 0],
'top': [185, 0],
'opacity':[0,1]
});
//no beginning values needed, since we always want to push the old item out to the left
item_out.start({
'left': '0',
'top': '-185',
'opacity':[0]
});
End...
corect me if I'm wrong, please. Thx again for suggestion Daniel.
For those who need to dynamiclly display 2 record in one slide at the time just change some code and that it. This work only for horizontal slider.
Apply horizontal looper with row: all records column: 2 (I used free Tom Muck extension link: http://www.tom-muck.com/extensions/help/HorizontalLooper/)
Apply class="slide_item" into <tr> and delete <div class="slide_item"> amd </div>
change div.slide_item... to tr.slide... in css
That's all. Work for me

hey there.
first, thanks for that script.. i was using another slider but needed that automatic highlighted numbering thing. perfect.
but i've got one question.
is it possible to remove the autoplay and/or the whole play/pause thing without rewriting the js?
another suggestion would be to style the inner slide in a way that going from slide 1 to slide 5 would actually show the 3 slides in between.
now it's more a content jumper then a slider ![]()
anyway.. great script.
Tobi, yes it's quite easy to remove the autoplay... just remove the periodical aspect of the slide function.
As for showing the 'in-between' slides during transitions, that would involve setting the items up as a linear 'strip' and then sliding that strip as a whole. (Slightly different setup and execution, but should be easy enough.) Feel free to give it a shot and show everyone your version! ![]()
hehe,
yeah. guess i'll give it a try but it will take some time.. be back with questions.
Nice! But not unobstrusive! No chance to see all "tabs" with javascript deactivated. Should work on that.
@Beasty: Thanks... but I'm curious, honestly who disables Javascript in 2008? Judging from various client sites' stats, I'd have to say virtually none. However, you are welcome to work on it...it's free to download and modify.
Edit: While I'm not concerned about it in this case, Beasty is actually right – if I were using this on a client site and it contained highly important content, I'd probably adjust the original CSS (ditching the overflow:hidden) and re-set it via MooTools when the DOM is ready. ![]()
Raffaele Colleo, You can add
var items_container = $('items_container');
to the config vars and add
items_container.addEvent('mouseover', function(){
if(isSliding == 0){
if(isPaused == 0){
isPaused = 1;
$clear(theTimer);
playBtn.getElement('a').set('html', 'play');
}
}
});
items_container.addEvent('mouseout', function(){
if(isSliding == 0){
if(isPaused == 1){
isPaused = 0;
theTimer = slideMove.periodical(slideTimer, this, 1);
playBtn.getElement('a').set('html', 'pause');
}
}
});
to the control buttons.
It works for me ( see http://dev.deridderserver.nl/Matthijs/Test/Slide/ )
NOTE: Replace _ ; with an _
Is there any way to change the transition type? Basically I want to make the transition a fade-in/fade-out thing.
Anyone know how I can accomplish this?
First of all, this is an awesome tutorial. Thank you for creating it. I was playing around with it and I made it smaller and removed the previous/pause/next buttons. Something along the way caused the last slide to be visible until after they have all cycled through the container once. I can't figure out what's causing it, though. Any ideas on what may be causing that and/or how to go about fixing it? Thank you in advance for your advice.
Hey jeremy, the fade-out fade-in effect would be accomplished by simply removing the left attribute from the start function and replace it with opacity[0,1 in the item_in.start function and opacity [0 in item_out.start.
Here's a preview of your comment:
This is a pretty cool effect. I've done something like it, but for v1.1 of mootools. Check it out at 8trk.com