Build the ANidea Theme Switcher using jQuery

Theme Carousel

The goal is to have a list of all the themes available. We need to consider the addition of themes in the future, so our drawer remains scalable no matter how many themes we create. By having the list of themes inside list items, we can write a loop and have more control over it.

To make the theme carousel work, we will download, install and use the jQuery Infinite Carousel plugin. Let’s add the following line after at the HEAD:

<script type="text/javascript" src="js/lib/plugins/jquery.infinite-carousel.js"></script>

And lets add the following after inside the theme-drawer DIV:

<div id="theme-carousel">
<div id="btn-previous">Prev</div>
<div id="themes-frame">
<ul>
<li><a href="#" rel="theme01"><img src="themes/theme01/preview.gif" alt="Theme 01" /></a></li>
<li><a href="#" rel="theme02"><img src="themes/theme02/preview.gif" alt="Theme 02" /></a></li>
<li><a href="#" rel="theme03"><img src="themes/theme03/preview.gif" alt="Theme 03" /></a></li>
<li><a href="#" rel="theme04"><img src="themes/theme04/preview.gif" alt="Theme 04" /></a></li>
<li><a href="#" rel="theme05"><img src="themes/theme05/preview.gif" alt="Theme 05" /></a></li>
</ul>
</div><!-- end themes-frame -->
<div id="btn-next">Next</div>
</div><!-- end #theme-carousel -->

To break it down, we have a container named “theme-carousel,” which holds the buttons to make the themes scroll left or right. In between the buttons, we have a container called “themes-frame” which holds the UL (unordered list) that contains the list of themes. Let’s add the following to the CSS:

#theme-carousel {
width: 960px;
margin: 10px auto;
overflow: hidden;
}

#themes-frame {
overflow: hidden;
float: left;
width: 904px;
}

#btn-previous,
#btn-next {
width: 26px;
height: 70px;
text-indent: -9999px;
cursor: pointer;
float: left;
margin: 10px 0;
}

#btn-next {
float: right;
}

#btn-previous {
background: url(../img/prev-next-sprite.png) no-repeat left top;
}

#btn-previous:hover {
background: url(../img/prev-next-sprite.png) no-repeat left bottom;
}

#btn-next {
background: url(../img/prev-next-sprite.png) no-repeat right top;
}

#btn-next:hover {
background: url(../img/prev-next-sprite.png) no-repeat right bottom;
}

#theme-drawer ul {
position: relative;
padding: 0;
margin: 10px 0;
height: 71px;
}

#theme-drawer li {
list-style: none;
background: #666;
display: inline;
float: left;
margin-left: 22px;
width: 126px;
height: 71px;
}

#theme-drawer li span {
color: #000;
font: bold 11px Arial, Helvetica, sans-serif;
padding: 2px;
display: block;
background: #ccc;
}

The plug-in is smartly written to determine the width of the children (in our case, the themes) inside the selector, so it scrolls the appropriate distance when the triggers are clicked.

Now, let’s add the code to make the carousel work: In theme-switcher.js file, add the following inside the ‘document ready function’:

/* Theme Carousel */
$("#themes-frame").carousel("#btn-previous", "#btn-next");

The “themes-frame” ID is the carousel and the parameters inside the “carousel” class are the controllers to make it scroll left or right (previous or next, respectively).

The Themes

I created a folder in the root of the site called “themes.” Inside the themes folder, we have the subfolders for each theme. Each folder is named according to the theme name, so in this example they are called “theme01″ to “theme05.” The file structure for each theme folder is the same, it contains a background image (”bg.gif”), the preview image (”preview.gif”) and the CSS (”theme.css”). I strongly recommend keeping the naming conventions the same as it will make it easier for future maintenance.

The folder structure is very important as it allows us to create an efficient script. Plus, it looks neat to have a clean folder structure.

The Theme Switcher

Before we go any further, let’s add a “rel” value to the links inside the list items of each theme. This value will be the theme name.

To change the theme, we are simply going to call separate style sheets that lives in the themes folder, the ones we covered above.

Now that we have the folder structure down, let’s add the following to the JavaScript file:

/* theme switcher */
$("#themes-frame a").click(function() {
var themename = $(this).attr("rel");
$("#active-theme").attr({ href: "themes/" + themename + "/theme.css"});
hideDrawer();
return false;
});

Still with me?… The JavaScript in plain English is as follows: When the user clicks on a tag inside the “themes-frame” ID, we are going to get the value from the “rel” property of the clicked element.  That value is the new theme that we want to change to.  We are then going build a string containing the folder structure of the themes folder plus the value of the clicked theme. This way, we can update the “href” attribute of the “active-theme” ID, which is located in the head of the HTML. After the theme is changed, we’ll hide the theme drawer automatically for the user.

Hold your horses: This alone will still not work, so we’ll need to add this single line to the head of the HTML file:

<!-- The Theme Style Sheet-->
<link rel="stylesheet" id="active-theme" type="text/css" href="themes/default/theme.css" />

Saving the Theme

To save the theme the user has selected, we are going to set a cookie. To accomplish this, we’re going to use another jQuery plugin that will deal with cookies. Let’s call the plug-in in the head part, after the carousel plugin:

<script type="text/javascript" src="js/lib/plugins/jquery.cookie.js"></script>

To define the cookie, let’s add the following at the top of the theme-switcher.js file:

/* cookie vars */
var cookie_name = "selected_theme";
var cookie_options = { path: '/', expires: 7 };

In plain english, we named the cookie “selected_theme” and it will last for 7 days.

We’ll need to store the value of the theme selected by the user, so let’s add the following after the “hideDrawer” function call:

$.cookie(cookie_name, themename, cookie_options);

We are getting the values from the variables defined above, plus, we are defining that the value of the cookie is the theme the user has selected.

That’s it! We are now storing a cookie for the site! As previously mentioned, this cookie stores the value of the last selected theme. We need to determine if the cookie has been defined or not, so for the users next visit, to show the last theme the user selected.

/* Get Cookie */
var get_cookie = $.cookie(cookie_name);
if(get_cookie != null) {
$("#active-theme").attr({ href: "themes/" + get_cookie + "/theme.css"});
}

The use of variables makes your JS look cleaner and it’s easier to maintain. What the IF statement is doing is determining that if there is a value for the cookie, we’ll update the “rel” value in the “active-theme” ID. It is the same line of code as the one in the Theme Switcher function, but instead of looking for “theme_name,” we are looking for “cookie_name,” which is the last “theme_name” value.

In other words, we’ll check to see if the cookie already has a value, and will place that value in the “active-theme” ID that we defined earlier to switch themes.

If you did everything correctly (and I didn’t miss anything) you should have the following on your files:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>ANidea.com Theme Drawer and Switcher Tutorial!</title>

<link rel="stylesheet" href="css/anet-sfw-screen.css" type="text/css" media="screen, projection" />
<link rel="stylesheet" href="css/styles.css" type="text/css" media="screen, projection" />
<!-- The Theme Style Sheet-->
<link rel="stylesheet" id="active-theme" type="text/css" href="themes/default/theme.css" />

<!-- JavaScript -->
<script type="text/javascript" src="js/lib/jquery/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="js/lib/plugins/jquery.infinite-carousel.js"></script>
<script type="text/javascript" src="js/lib/plugins/jquery.cookie.js"></script>
<script type="text/javascript" src="js/theme-switcher.js"></script>

</head>

<body>
<div id="wrapper">
<div id="header">
<h1>The ANidea Theme Switcher</h1>
</div><!-- end #header -->
<div id="main-column">
        <p>Aliquam erat volutpat. Donec tincidunt. Morbi fermentum viverra ligula. Aenean dui orci, consectetuer vel, sodales sit amet, lobortis vel, mi. Suspendisse in pede vitae urna dignissim scelerisque. Vivamus adipiscing massa ac tortor. Maecenas venenatis feugiat odio. Curabitur feugiat, nisi sit amet elementum suscipit, lorem quam faucibus augue, id fringilla elit tortor non libero. Phasellus varius, lacus id imperdiet auctor, diam tellus mattis leo, vel mattis arcu orci id lectus. Fusce accumsan viverra magna. Suspendisse imperdiet nulla id dolor. Nam ipsum orci, commodo et, gravida eget, lobortis at, libero. Duis eu nunc. Maecenas vehicula, arcu et pretium rutrum, turpis lorem ultrices leo, quis bibendum lacus orci vel felis. Morbi viverra, leo non luctus gravida, justo mauris volutpat eros, non ullamcorper ante nisl sit amet mauris.</p>

<p>Proin ante. Vestibulum blandit eros id neque. Etiam velit. Donec leo lectus, accumsan non, tristique sed, ornare nec, lacus. Nunc fermentum, augue vel pellentesque tristique, nisl mi scelerisque neque, at malesuada justo massa nec magna. Integer vitae dui vel turpis auctor imperdiet. Nunc nec ligula. Ut placerat. Nullam sapien. Vestibulum sed lacus vitae odio convallis tristique. Donec tincidunt. Quisque nec metus. Quisque vestibulum dapibus enim. Maecenas magna. Aliquam aliquet magna quis erat.</p>

    </div><!-- end #main-column -->
    <div id="sub-column">
    	<h3>A List</h3>
    	<ul>
<li><a href="http://anidea.com">ANidea</a></li>
    		<li><a href="http://agencynet.com">AgencyNet</a></li>
    	</ul>
    </div><!-- end #sub-column -->
</div><!-- end #wrapper -->

<!-- The Theme Drawer -->
<div id="theme-wrapper">
<div class="drawer-toggler">Change Theme!</div>
<div id="theme-drawer">
<div id="theme-carousel">
<div id="btn-previous">Prev</div>
<div id="themes-frame">
<ul>
<li><a href="#" rel="theme01"><img src="themes/theme01/preview.gif" alt="Theme 01" /></a></li>
<li><a href="#" rel="theme02"><img src="themes/theme02/preview.gif" alt="Theme 02" /></a></li>
<li><a href="#" rel="theme03"><img src="themes/theme03/preview.gif" alt="Theme 03" /></a></li>
<li><a href="#" rel="theme04"><img src="themes/theme04/preview.gif" alt="Theme 04" /></a></li>
<li><a href="#" rel="theme05"><img src="themes/theme05/preview.gif" alt="Theme 05" /></a></li>
</ul>
</div><!-- end themes-frame -->
<div id="btn-next">Next</div>
</div><!-- end #theme-carousel -->
</div><!-- end #theme-drawer -->
</div><!-- end #theme-wrapper -->

</body>
</html>
/* @group Global Styles */

body {
background: #000;
font-size: .8em;
}

#wrapper {
background: #fff;
margin-top: 20px;
}

#main-column {
padding: 10px 0;
}

#sub-column {
background: #fefefe;
padding: 10px 0;
}

#sub-column ul {
list-style: none;
}

#sub-column li {
margin: 0 0 1px;
}

#sub-column li a,
#sub-column li a:link,
#sub-column li a:active,
#sub-column li a:visited
{
display: block;
padding: 8px 5px;
background: #ccc;
color: #333;
font-weight: 700;
text-decoration: none;
}

#sub-column li a:hover {
background: #999;
}

/* @end */

/* @group Theme Drawer */

#theme-wrapper {
position: fixed;
bottom: 0;
z-index: 900;
width: 100%;
}

.drawer-toggler {
background: #ff006f;
color: #fff;
font-weight: 700;
text-align: center;
cursor: pointer;
padding: 10px 0;
width: 140px;
position: absolute;
top: -30px;
right: 0;
}

#theme-drawer {
background: #eee;
border-top: 5px solid #666;
clear: both;
overflow: hidden;
position: relative;
z-index: 905;
}

#theme-carousel {
width: 960px;
margin: 10px auto;
overflow: hidden;
}

#themes-frame {
overflow: hidden;
float: left;
width: 904px;
}

#btn-previous,
#btn-next {
width: 26px;
height: 70px;
text-indent: -9999px;
cursor: pointer;
float: left;
margin: 10px 0;
}

#btn-next {
float: right;
}

#btn-previous {
background: url(../img/prev-next-sprite.png) no-repeat left top;
}

#btn-previous:hover {
background: url(../img/prev-next-sprite.png) no-repeat left bottom;
}

#btn-next {
background: url(../img/prev-next-sprite.png) no-repeat right top;
}

#btn-next:hover {
background: url(../img/prev-next-sprite.png) no-repeat right bottom;
}

#theme-drawer ul {
position: relative;
padding: 0;
margin: 10px 0;
height: 71px;
}

#theme-drawer li {
list-style: none;
background: #666;
display: inline;
float: left;
margin-left: 22px;
width: 126px;
height: 71px;
}

/* @end */
/* cookie vars */
var cookie_name = "selected_theme";
var cookie_options = { path: '/', expires: 7 };

/* theme drawer hider */
function hideDrawer() {
$("#theme-drawer").slideToggle("normal", function () {
if ($("#theme-drawer").is(":visible")) {
$("#wrapper").css("margin-bottom", "150px");
} else {
$("#wrapper").css("margin-bottom", "20px");
}
});
}

$(document).ready(function(){

$(".drawer-toggler").click(function() {
hideDrawer();
});

/* Theme Carousel */
$("#themes-frame").carousel("#btn-previous", "#btn-next");

/* Get Cookie */
var get_cookie = $.cookie(cookie_name);
if(get_cookie != null) {
$("#active-theme").attr({ href: "themes/" + get_cookie + "/theme.css"});
}

/* theme switcher */
$("#themes-frame a").click(function() {
var themename = $(this).attr("rel");
$("#active-theme").attr({ href: "themes/" + themename + "/theme.css"});
hideDrawer();
$.cookie(cookie_name, themename, cookie_options);
return false;
});

});

If everything seems in order, your theme switcher should be working great!

In the second part of tutorial, we’ll show you how to integrate it with your WordPress installation.

Pages: 1 2 3

Bookmark and Share
12 Comments + Add Your Own
  1. 1

    NetOperator Wibby…

    I’ve been a fan of ANidea’s theme switcher for some time but I felt like it was kind of taboo to look through the sourcecode, lol.

    Thanks for the tutorial!

  2. 2

    Ryan Paul Thompson…

    Awesome breakdown, I can’t wait to go through this :) Thanks!

  3. 3

    jQueryGlobe…

    Impressive. I just don’t like frames

  4. 4

    Max.W…

    Thanks for this, I was really hoping you would post a tutorial someday on this. It’s a lovely tool to have and really adds value to the site, it gives users a choice on how they view the site which is a really great thing to see.

  5. 5

    Alice…

    Awesome!! Is part 2 up yet?

  6. 6

    Alice…

    Okay not to be a pain in the ass but I’ve worked through this (thanks so much, it’s great) and would love to see Part 2 and work it into Wordpress… just sayin’!

  7. 7

    Omar…

    Thanks everyone for the positive feedback! Part 2 is in the works! I’m doing my best to break it down so its easier to follow.

  8. 8

    shawn…

    Any possibility of getting part 2 added so that we can learn how to add this to our wordpress themes?

  9. 9

    Hitesh Panchal…

    Hi, your work is very nice. but its not working in IE 6. so can you pls tell me how to i will run it in IE 6 ??

    Regards,
    Hitesh Panchal

  10. 10

    Tim…

    can’t wait to see part 2 !

  11. 11

    Chris Pierre…

    Pretty interesting Tut, thanks a lot and like everyone else Im anticipating part 2.

    Chris Pierre

  12. 12

    Lis…

    This seems pretty straight forward. I look forward to trying it. I am EXCITED though to see how it will work with WP!

Leave a Comment

 

*required
jQuery Theme Changer

previously