How to Create Your Very Own “Archive Navigator”

April 8, 2008

Archive Navigator Title Image

Be sure to check out part two of this tutorial afterwards!

Last week I received an email from fellow reader Jaap asking if I could provide a link to a plugin that would implement something like my very cool Archive Navigator you see to the right.

I did some searching and found a jQuery plugin that is capable of the same effect called Coda-Slider. The reason this plugin is called 'Coda-Slider', is because this effect was made popular on Panic's product site for their web development software called Coda.

[Javascript required to view Flash movie, please turn it on and refresh this page]

If you're looking for a quick solution to pull this off, head on over to Niall Doherty's blog (the author of the Coda-Slider plugin) and download it. There's enough documentation there to pull off the effect in a matter of minutes if you know what you're doing.

But if you're looking to improve on your web developing skills, I'll show you how to pull this off from scratch and customize it for WordPress using just the jQuery library.

Warning: The following will require intermediate HTML and CSS knowledge.

Step 1: Building the Navigator

First, we're going to build out the elements needed for the Navigator. Open up your favorite text editor and create a couple of divs which will nest like this:

<div class="crop">
        <div class="widearea">
                <div id="divone">
                        Hello World
                </div>
                <div id="divtwo">
                        Hello Earth
                </div>
                <div id="divthree">
                        Hello Planet
                </div>
        </div>
</div>

With CSS, we will try to achieve a layout like the following diagram:

Here's some sample CSS code that will go along with the HTML above:

div.crop {
        width: 300px;
        height: 400px;
        overflow: hidden;
}

div.widearea {
        width: 1000px;  /*make it as wide as needed to fit all child divs
                        in one row*/

        height: 400px;
}

div.widearea div {
        width: 300px;
        height: 400px;
        display: block;
        float: left;
}

Since the .crop div is a parent div of the other divs, specifying fixed dimensions as well as assigning hidden to the overflow attribute will effectively crop out anything not inside its dimensions. Although this example only has three divs, you can create as many as you want as long as you make the .widearea div wide enough.

Next, we'll need to add some controllers available to the user so that they can interact with this. For simplicity's sake, let's add three buttons:

<div class="crop">
        ...
</div>

<button id="buttonone">Go to divone</button>
<button id="buttontwo">Go to divtwo</button>
<button id="buttonthree">Go to divthree</button>

Now that we've built out the HTML, we will start getting into the fun stuff.

Effects with jQuery

The first thing that needs to happen before we can start writing javascript for the jQuery library is to reference it. I recommend downloading it and referencing it off your own host rather than referencing it elsewhere.

Once you've dropped the library into your host, add a reference to it in your html like so:

<script type="text/javascript" src="jquery-1.2.3.min.js"></script>

Next, create a new js file with your text editor. This will hold all the custom javascript we will write. Let's take a step back and try and figure out what our objectives are before we start writing code:

  1. Add a click event handler to our buttons
  2. Create one (or more) functions which will produce the sliding effect

So for the first objective, creating a click event handler (also known as onClick) is real simple using jQuery:

$("#buttonone").click(function() {
        enter your function here
});

Hopefully it's intuitive enough that you clued in that to create the other click event handlers for the other two buttons, you just had to copy and paste that line of code and replace buttonone with buttontwo or buttonthree. To explain this a little better: we are targeting the button with id buttonone (as done with $("#buttonone")) and then assigning a click event handler which will call a function.

Next, we will create the functions inside these click event handlers which will "scroll" the .widearea div horizontally:

$("#buttonone").click(function() {
        $(".widearea").animate({
                marginLeft: "0px"
        }, 500);
});

In our function, we are instructing the .widearea div to animate to margin-left (note how jQuery's syntax is a little different from CSS) of 0. If you got this set up, you'll notice clicking on the button doesn't do anything, that's because by default, we are already seeing divone so there's no reason to move the .widearea div. Let's set it up for buttontwo:

$("#buttontwo").click(function() {
        $(".widearea").animate({
                marginLeft: "-300px"
        }, 500);
});

If you add this in and click on buttontwo, the .widearea div should move 300px to the left so that #divtwo is in view. If you're wondering what the "500" is for, it specifies how long the animation should last in milliseconds.

Putting it all together now...

Eventually, after coding everything up, you'd end up with something like this:

<html>
<head>
        <title>Slider</title>
        <style type="text/css" media="screen">
                div.crop {
                        width: 300px;
                        height: 400px;
                        overflow: hidden;
                }

                div.widearea {
                        width: 1000px;
                        height: 400px;
                }

                div.widearea div {
                        width: 300px;
                        height: 400px;
                        display: block;
                        float: left;
                }
        </style>
</head>
<body>
<div class="crop">
        <div class="widearea">
                <div id="divone">
                        Hello World
                </div>
                <div id="divtwo">
                        Hello Earth
                </div>
                <div id="divthree">
                        Hello Planet
                </div>
        </div>
</div>
<button id="buttonone">Go to divone</button>
<button id="buttontwo">Go to divtwo</button>
<button id="buttonthree">Go to divthree</button>

<script type="text/javascript" src="jquery-1.2.3.min.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
        $("#buttonone").click(function() {
                $(".widearea").animate({
                        marginLeft: "0px"
                }, 500);
        });
        $("#buttontwo").click(function() {
                $(".widearea").animate({
                        marginLeft: "-300px"
                }, 500);
        });
        $("#buttonthree").click(function() {
                $(".widearea").animate({
                        marginLeft: "-600px"
                }, 500);
        });
});
</script>
</body>
</html>

If you want, you can copy and paste the above into an html file, stick it in a directory with version 1.2.3 of the jQuery library (the latest stable version as of this post) and run it for a quick demo. It functions the exact same as my archive navigator.

Now, you'll notice something new in the javascript. There's this $(document).ready(function(){ wrapping it all and it ensures that no javascript gets run until the page is fully loaded. It prevents any javascript errors getting thrown because if you didn't have this and this javascript gets executed before the button or div involved is loaded, it wouldn't work.

Customizing it for WordPress

If you've ever created or modified a WordPress theme before, you might have come across the template tags. You can use these inside the divs of .widearea to list categories, tags, and more. Here are a few examples:

  • Tag cloud:
    <?php wp_tag_cloud(''); ?>
  • Categories listing:
    <?php wp_list_categories('arguments'); ?>
  • Last five posts:
    <?php query_posts('showposts=5');
            while (have_posts()) : the_post(); ?>
                    <li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li>
    <?php endwhile; ?>

Still with me?

I tried to make this mini-tutorial as newbie friendly as possible but there are some advanced topics in here that might have gone over your head. If you have any questions, feel free to ask through the comments as I'm sure I might have not explained something very well or left out something.

And if you're a seasoned programmer, I know some of this stuff is bad practice (I realize that the javascript is anti-OO), but I tried to make it accessible as possible.


54 Comments

  • David Sparks says:

    well.. i have the jQuery file on my machine, I copy and pasted your code into a blank html page, linked them together and previewed it and the divs wont float and the buttons wont work.

    edited some things and now the divs are floating but the script still isnt working. cant get the buttons to do anything.

    definitely driving me crazy…

  • Sam Lu says:

    David, it looks like I failed which version of jQuery to download as there are three links on the jQuery home page. Be sure to download either the jQuery 1.2.3 (94kb, Uncompressed) or jQuery 1.2.3 (29kb, Packed) and if necessary, rename it to jquery-1.2.3.min.js. It sounds like you might have downloaded the minified and gzipped version and you would need to add some code to decompress it before you would be able to use it.

  • David Sparks says:

    Thanks! yeah that is what i did. I managed to get it working late into the night hah.

    Thank you!

  • Jack says:

    Hi Sam,

    Awesome tutorial and really appreciated! It’s great to understand something rather than just cut & paste!

    I wonder if you can add an explanation of scrolling in 2-D? And how this would affect the code?

    Thanks.

    Jack

  • Sam Lu says:

    Jack, to introduce vertical scrolling, I guess you can just add the marginTop parameter to the animation call.

    I found a jQuery plugin which does 2D scrolling very well called LocalScroll and is worth checking out.

  • Alex says:

    Thanks for the great tutorial, this is the simplest slider I’ve seen so far.

    However, it doesn’t seem to work in Safari on OS X. I’ve tested in Firefox (Win and Mac), IE6 (Win), IE7 (Win), and Opera, and it works perfectly in all of those browsers. Safari just doesn’t slide.

    Any suggestions or perhaps this is a bug in Safari’s support for jQuery?

    Cheers!

  • Sam Lu says:

    That’s weird Alex, it works fine for me on Safari 3. Does my Archive Navigator near the top right of this page slide for you? What version of Safari are you using?

  • moh says:

    Thanks! Really quick and easy.

  • Mark Bowen says:

    Just came across this tutorial. Very nice to see such a quick way of getting this effect working.

    For all those having problems with this then if you are copy-pasting directly from this web-site you will probably find the problem you are having is with all the inverted commas being the wrong type. If you delete them all one by one and code them back in again then that should hopefully get rid of some of your headaches! ;-)

    Nice tutorial though so thanks.

    Best wishes,

    Mark

  • Paul says:

    Hey, I have a quick question,
    I was wondering if it is possble to control the slider with the keyboard- left and right buttons
    ?

  • Sam Lu says:

    Paul, theoretically it would be possible to control the slider with the keyboard left and right keys by adding event handlers for the left & right keypresses. With that said, almost all the javascript would need to be revamped as you could potentially run it on just two functions; one to move the div left and the other to move it right. You’d then need to set boundaries and control it via incrementing/decrementing a counter.

    Hopefully those hints help if you decide to take it on ;)

  • Sarah Neuber says:

    Thank you so much. I found this tutorial very helpful.
    I’m new to jquery and javascript in general so I’m glad when I find such easy to follow tutorials online. Now all I need is to find a way to have a “current” state on the taps (I used an ul with links instead of the buttons). Can you help?

  • Sam Lu says:

    Sarah, to have a current state on the tabs, you will need to make use of the click event handler and toggle class attribute provided by jQuery. Essentially, you will need to create a CSS class which you will assign to the current tab and toggle that when clicked.

  • Sarah Neuber says:

    Thanks for replying. I did this in the meanntime and as far as I can see it works ok. What do you think?

    $(“#tabone a”).click(function() {
    /* remove open class from other li’s
    and add it to this li*/
    $(this).parents(“li”).addClass(‘open’)
    .siblings().removeClass(‘open’);
    $(“.widearea”).animate({marginLeft: “0px”}, 500);
    return false;
    });

  • Sam Lu says:

    If that works for you Sarah, then you should use it. Your method is a little bit more creative than mine actually, but since you wrote it, you’ll understand it if the time comes to alter it or fix it if something goes wrong.

  • Tyler says:

    Hello Sam,

    This is a terrific tutorial and I’m excited to put it into motion on my site. But, I was wondering something. Is there any way to make this work without javascript enabled? In other words, is there a way to make this degrade nicely?

    Thanks,

    Tyler

  • Sam Lu says:

    @Tyler: I will write a follow-up post on this as there’s too much to cover in one comment :)

    Stay tuned.

  • Tyler says:

    Thanks! I look forward to reading it.

  • Sorthe says:

    Hi!

    I’ve tried for quit a while now, and I just can’t get it to work… Maybe I’ve just read myself blind on my one mistakes, but can you look at it?
    http://sorthe.org/index.phps

    I’ve made some changes, put jQuery in the folder /js/ and put the scripts in the head instead of the body, both shouldn’t have anything to say if it works or not…
    I’m on Mac OS X, Safari 3 (doesn’t work in FireFox neither)

  • Mark Bowen says:

    Sorthe,

    Took a look at your code that you have linked to and nothing seems to be wrong with it from what I can tell. Just make sure you definitely have the CSS file linked to otherwise you will get the contents of the three DIVs showing on the page and when you click any of the buttons then all the content will slide off the page. As long as you have the same CSS as shown above then your code should be working just fine.

    Best wishes,

    Mark

  • Sorthe says:

    Hmm…
    Well, thanks, I tried to include the CSS directly into the index.php as you did, and then it worked (yey!), so weird that it doesn’t work with an external CSS… I don’t really fancy having my CSS in the actual page, ’cause I like to have it all in one place, if you understand :P

    I just have to try again, but thanks for a great tutorial :D

  • Mark Bowen says:

    Hiya Sorthe,

    Just as a quick note that it should work with an external CSS file, not too sure why it wouldn’t. Must be something else up there I would think.

    Also this isn’t my tutorial, just thought I should point that out ;-) I was just looking at your code and saw that nothing looked wrong with it. I’m not actually anything to do with this site and in no way affiliated with it but rather just someone who happened across the tutorial too. ;-) :-)

    Just thought you should know so the props can go the correct person ;-)

    Thanks for a great tutorial, sitemaster!

    Best wishes,

    Mark

  • Hungzai says:

    Nice tutorial you have there! May i ask how do i change css styles for ‘current’ tabs? I have changed it to , but i want it to look a little different when it is at the current tab, are you able to give some pointers? Thanks!

  • hi there
    i’am new to the jquery and i tried your navigator by doing copy paste as you said but it didn’t work as it works in the right panel of this site.in my understanding it should work if i copy and paste in html page.

    thanking you

    suman

  • Sam Lu says:

    Suman, jquery just released a new version so be sure the line:

    <script type=“text/javascript” src=“jquery-1.2.3.min.js”></script>

    references the right file (jquery is up to 1.2.6 now).

    Beyond that you should not be experiencing any other problems as I’ve fixed the quotation issue Mark Bowen mentioned earlier so there is nothing wrong with the HTML.

  • Suman says:

    hi there

    thanx for the quick response yeap i put the same you provided in my response and about the procedure i simple copy and paste it in the blank html files.but it’s not floating as it floated in the right bar

  • matt says:

    i was going to purchase a full subscription, to bad you cant afford to host it and your exceeding your bandwidth, i guess you should fix that it kinda is a turn off to people like me who would like to access the site…

    Bandwidth Limit Exceeded
    The server is temporarily unable to service your request due to the site owner reaching his/her bandwidth limit. Please try again later.
    Apache/2.2.9 (Unix) mod_ssl/2.2.9 OpenSSL/0.9.7a mod_bwlimited/1.4 Server at http://www.woothemes.com Port 80
  • Sam Lu says:

    Matt, I’m not affiliated with Woothemes. Although this tutorial was used to help create the mast on their index page, I took no part in developing the service and am not part of the team.

  • matt says:

    ah ha, i understand sorry for the mix up man

  • Jordan says:

    Tried this, and it seems to work perfectly in FF3, but in IE I’m getting a problem. The .crop div doesn’t seem to be cropping the text in IE.

    Example:
    http://screencast.com/t/aee5N57o
    (Used the IE Tab FF Plugin)

    Here my Code:

    CSS

    .crop {width: 292px; overflow: auto;}

    #tabbed_box_1 {border:1px solid #3d4449; background-color:#5a6167; padding:10px; width: 292px;}

    .tabbed_area {width: 876px;}

    ul.tabs {margin:0px; padding:0px width: 302px;}

    ul.tabs li {list-style:none; display:inline;}

    ul.tabs li button {background-color:#464c54; color:#ffebb5; padding:14px 1px 14px 1px;
    text-decoration:none; font-size:9px; font-family:Verdana, Arial, Helvetica, sans-serif;
    font-weight: bold; text-transform:uppercase; border: 2px #3D4449 solid; width: 96px;}

    ul.tabs li button#tab_2 {width:88px; margin-left: 2px;}

    ul.tabs li:last-child {margin-left:2px;}

    ul.tabs li button:hover {background-color:#2f343a;}

    ul.tabs li button.active {position: relative; top: 1px; background-image: url(images/BlogrollGrad.jpg); background-repeat: repeat-x;
    color:#FFF; padding-top: 17px; padding-bottom: 16px; border:1px solid #929aa1; border-bottom: none;
    background-color: #3d4449;}

    .content {background-color: #3d4449; background-image: url(images/BlogrollGrad_2.jpg); background-repeat: repeat-x;
    background-position:bottom; width: 270px; padding:10px; border:1px solid #929aa1; display: block; float: left;}

    .content ul {margin:0px; padding:0px 20px 0px 20px;}

    .content ul li {list-style:none; border-bottom:1px solid #d6dde0; padding-top:15px; padding-bottom:15px; font-size:13px;}

    .content ul li a {text-decoration:none; color:#8b959c; font-family:Verdana, Arial, Helvetica, sans-serif; text-align:center;}

    .content ul li:last-child {border-bottom: none;}

    #content_2 ul a {color: #929aa1;}

    #content_2 ul a:hover {color: #FFF;}

    .content a:Hover {color: #FFF;}

    HTML

    Recent Posts
    Tags
    Categories

    <a href=”" rel=”bookmark”>

    Am I doing something incorrectly?

  • Jordan says:

    Woops, Wrong HTML

    Recent Posts
    Tags
    Categories

    <a href=”" rel=”bookmark”>

  • Jordan says:

    Okay, So that’s not working, Here’s an upload:

    http://dl.getdropbox.com/u/85600/HTML.txt

  • Sam Lu says:

    @Jordan: In your CSS, you assign the overflow attribute to the crop class as: auto. This needs to be set to: hidden as shown in my CSS above.

  • Kurt Cruse says:

    Wow. I’ve used 2 or 3 other (highly linked to and popular) jquery coda-slider tutorials which were much much more complicated, using up to 4 plugins. But this is exactly what I’ve actually been looking for. Bare bones, no unnecessary bells and whistles.

    Bravo. Bravo!

  • Kurt Cruse says:

    I also had some Safari trouble. After some testing I found that the problem occurred if the outtermost div (crop in this example) was floated. If I removed the quote it worked fine.

  • Kurt Cruse says:

    To add to that…

    I fixed the problem by inserting an empty DIV above the ‘crop’ DIV with a clear both style applied to it. Then the ‘crop’ div needs a margin of 0 auto. So..

    Slider

    div.crop {
    width: 300px;
    height: 400px;
    overflow: hidden;
    margin: 0 auto;
    }

    div.widearea {
    width: 1000px;
    height: 400px;
    }

    div.widearea div {
    width: 300px;
    height: 400px;
    display: block;

    }

    Hello World

    Hello Earth

    Hello Planet

    Test Link
    Go to divtwo
    Go to divthree

    $(document).ready(function(){
    $(“#buttonone”).click(function() {
    $(“.widearea”).animate({
    marginTop: “0px”
    }, 500);
    });
    $(“#buttontwo”).click(function() {
    $(“.widearea”).animate({
    marginTop: “-300px”
    }, 100);
    });
    $(“#buttonthree”).click(function() {
    $(“.widearea”).animate({
    marginTop: “-600px”
    }, 1000);
    });
    });

  • Kurt Cruse says:

    Well that last comment didn’t paste write (plz delete moderator). Here’s a screep cap instead.

  • Kevin says:

    Great Tutorial.

    Just a couple of questions;

    FIrst how do i make a button have an active state on it?

    Finally, how can I do the next and previous button? Should I have it on every div and just do each of it according to section where it can go?

    Thanks.

  • Sam Lu says:

    Kevin, in my current implementation, I’m actually using <li> elements for my “buttons”. In the second part of this tutorial I outline how to do this and have active/inactive states on them.

    In regards to your second question, I’d probably rather make two buttons in an external div and use jquery to instruct the “widearea” div to move a +/- 300px (or whatever size your viewport is) up to a maximum limit. If you want to make these buttons seem like they are inside the viewport, it can be achieved by adjusting the margins via CSS.

  • jon says:

    hey sam-
    i’m having a hard time understanding in which file to put the javascript for the buttons. im trying to integrate this into my sidebar, so does it go above the div codes inside sidebar.php? or does it go into a separate js file? if the latter, how do i reference that file?

    thanks!
    jon

    • Sam Lu says:

      John: the simplest solution would be to put all the javascript in a tag right before the final tag.

      You’d basically end up with something like this in whichever file you close your body with:

      <script type=”text/javascript”>
      $(document).ready(function(){
      $(“#buttonone”).click(function() {
      $(“.widearea”).animate({
      marginLeft: “0px”
      }, 500);
      });
      $(“#buttontwo”).click(function() {
      $(“.widearea”).animate({
      marginLeft: “-300px”
      }, 500);
      });
      $(“#buttonthree”).click(function() {
      $(“.widearea”).animate({
      marginLeft: “-600px”
      }, 500);
      });
      });
      </script>
      </body>
  • jon says:

    bingo, it worked!
    thank you!

  • Mike says:

    Hi Sam, First I want to thank you for this great tutorial. Second, I’ve encountered a small hiccup when trying to implement your strategy into a site I’m working on. I’m not sure if it has to do with the fact that instead of 3 panels, I am using 5 or if I messed up a number somewhere while modifying it to fit my needs.

    If you or another willing helper could take a look, I would greatly appreciate it. I’m still pretty new to this stuff so I’m not sure how to troubleshoot. The site is at http://www.mikegolofaro.com/TSGD/TSGD/index.html

    Thank you so much for any help you might be able to provide!

  • Mike says:

    Whoops! Maybe a description of the issues might help…

    I used my own links to access the panels which could be where the problem is coming from. When I click the different links, the animation effect works but it overshoots the targeted panel. If I click the same link again, it will bring up the correct panel but will not animate. Any ideas?

    • Sam Lu says:

      Hi Mike,
      I think your problem may stem from the href you assign to your links. Try changing your href for your links like so:

      <a href=“javascript:;” rel=“nofollow”>Shows</a>

      Change all your links’ href to javascript:; and it might fix it.

  • NAF says:

    Hey, what would be the simplest way to replace the browser buttons with linked images? Thanks.

  • [...] View Tutorial No Comment var addthis_pub=”izwan00″; BOOKMARK This entry was posted on Monday, June 8th, 2009 at 2:36 am and is filed under Javascript Tutorials. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site. [...]

  • [...] completa que pode ser adaptada por você bastando ter algum conhecimento de html e css. Neste outro site você encontrará uma documentação mais detalhada com exemplos de códigos. Slider.js criando [...]

  • sandrar says:

    Hi! I was surfing and found your blog post… nice! I love your blog. :) Cheers! Sandra. R.

  • Jetz says:

    Hello, I tried using this type but seems like it doesn’t work on firefox old and on the latest version, It works on IE and googlechrom but I just don’t know why it won’t slide on firefox.. >> Heres the script >>>
    _____________________________________________________

    $(document).ready(function() {

    $(“#nav1″).click(function() {
    $(“.widearea”).animate({
    marginLeft: “0px”
    }, 300);

    });

    $(“#nav2″).click(function() {
    $(“.widearea”).animate({
    marginLeft: “-760px”
    }, 300);
    });

    $(“#nav3″).click(function() {
    $(“.widearea”).animate({
    marginLeft: “-1520px”
    }, 300);
    });

    $(“#nav4″).click(function() {
    $(“.widearea”).animate({
    marginLeft: “-2280px”
    }, 300);
    });

    $(“#nav5″).click(function() {
    $(“.widearea”).animate({
    marginLeft: “-3040px”
    }, 300);
    });

    $(“#nav6″).click(function() {
    $(“.widearea”).animate({
    marginLeft: “-3800px”
    }, 300);
    });
    });

Leave a Comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>