Newer posts are loading.
You are at the newest post.
Click here to check if anything new just came in.

September 25 2013

13:46

Building Vertical-Tabbed Content Sections with jQuery

Advertise here with BSA


Ajax-style loading boxes are useful when displaying large sets of related data. Think about something like an FAQ page, knowledgebase, or support system. Any type of navigation is often suitable as long as the user can determine how to navigate between content areas.

In this tutorial I want to demonstrate how we can build a custom vertical content section using jQuery. All of the internal content is held inside div containers which can be navigated with an icon-based menu. This content isn’t loaded externally via Ajax, but is instead hidden & displayed using content sections already on the page. Check out my live sample demo to get an idea of what we are building.

jquery vertical content tabs sections tutorial preview screenshot

Live DemoDownload Source Code

Getting Started

There are only two required files we need for this dynamic content section to work. The first is jQuery which you can download in a compressed local format. The other is Font Awesome which is a free open source CSS3 icon webfont. This means we can include certain fonts using @import and render icon graphics as font elements in the page.

<!doctype html>
<html lang="en-US">
<head>
  <meta charset="utf-8">
  <meta http-equiv="Content-Type" content="text/html">
  <title>jQuery Vertical Tabbed Content Sections</title>
  <meta name="author" content="Jake Rocheleau">
  <link rel="shortcut icon" href="http://designm.ag/favicon.ico">
  <link rel="icon" href="http://designm.ag/favicon.ico">
  <link rel="stylesheet" type="text/css" media="all" href="css/styles.css">
  <link rel="stylesheet" type="text/css" media="all" href="css/font-awesome.min.css">
  <script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
</head>

This is what my document header looks like. I have included these two required items along with my core styles.css stylesheet. Also be sure that when you include the Font Awesome CSS file that you also copy over the entire /font/ directory. This includes all the important file types such as TTF and OTF, which are necessary to recognize any of the icon characters.

Creating Inner Body Content

The two main sections of the page are held within a single inner wrapping div. Obviously the navigation is much smaller than the content, so I have the navbar floating left without a connecting background. #sidemenu is actually an unordered list of items which display as block elements inside a fixed-width container.

<ul id="sidemenu">
  <li>
    <a href="#home-content" class="open"><i class="icon-home icon-large"></i><strong>Home</strong></a>
  </li>

  <li>
    <a href="#about-content"><i class="icon-info-sign icon-large"></i><strong>About</strong></a>
  </li>
  
  <li>
    <a href="#ideas-content"><i class="icon-lightbulb icon-large"></i><strong>Ideas</strong></a>
  </li>
  
  <li>
    <a href="#contact-content"><i class="icon-envelope icon-large"></i><strong>Contact</strong></a>
  </li>
</ul>

Now the other page element uses the ID #content which links to a number of internal div elements. These are labeled according to the navigation anchor links with the various IDs of home, about, ideas, and contact.

<div id="content">
    <div id="home-content" class="contentblock">
      <h1>The Main Page!</h1>
      <p>I swear this has some really great stuff. Content is courtesy of <a href="http://bluthipsum.com/">Bluth Ipsum</a>.</p>
      
      <p>Smack of ham. What is she doing at a beauty pageant? Is she running the lights or something? She's always got to wedge herself in the middle of us so that she can control everything. Yeah. Mom's awesome.</p>
      
      <p>Probably out there without a flipper, swimming around in a circle, freaking out his whole family.</p>
      
      <p>Fun and failure both start out the same way.</p>
    </div><!-- @end #home-content -->
    
    
    <div id="about-content" class="contentblock hidden">
      ...
    </div><!-- @end #about-content -->
    
    <div id="ideas-content" class="contentblock hidden">
      ...
    </div><!-- @end #ideas-content -->
    
    <div id="contact-content" class="contentblock hidden">
      ...
    </div><!-- @end #contact-content -->
</div><!-- @end #content -->

Notice that each of the inner div elements uses .contentblock as an additional class for styling. Yet #home-content is the only one without the extra .hidden class because this homepage content should immediately display once everything finishes loading. We can use jQuery to un-hide the other page areas and re-hide the homepage content section when switching in the navigation.

CSS Design Styles

With the Font Awesome CSS already included we can use this font family anytime. I’ve also linked to another font family named Cantora One which is hosted by Google Web Fonts. Other than this my stylesheet uses a few basic resets along with a core container for each inner div section.

@import url('http://fonts.googleapis.com/css?family=Cantora+One');

html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
  outline: none;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  -ms-text-size-adjust: 100%;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
html { overflow-y: scroll; }
body { 
  font-size: 62.5%; 
  line-height: 1;
  padding: 45px 20px;
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  background: #fff url('../images/bg.png'); /* http://subtlepatterns.com/connected/ */
}

br { display: block; line-height: 1.6em; } 
img { border: 0; max-width: 100%; }

h1 {
  font-family: 'Cantora One', Arial, sans-serif;
  font-size: 3.0em;
  line-height: 1.6em;
  margin-bottom: 10px;
  color: #787878;
}

p {
  font-size: 1.4em;
  line-height: 1.25em;
  color: #575757;
  font-weight: normal;
  margin-bottom: 10px;
}

a { color: #8dadd8; }
a:hover { color: #7299cf; }

/* main page */
#w {
  display: block;
  width: 900px;
  margin: 0 auto;
  background: none;
}


#content {
  display: block;
  background: #fff;
  padding: 0px 15px;
  margin-left: 80px;
  -webkit-box-shadow: 1px 2px 1px rgba(0,0,0,0.4);
  -moz-box-shadow: 1px 2px 1px rgba(0,0,0,0.4);
  box-shadow: 1px 2px 1px rgba(0,0,0,0.4);
  min-height: 300px;
}


.contentblock {
  display: block;
  padding: 15px 20px;
}

.contentblock.hidden {
  display: none;
}

You will notice that I’ve only included a white background on the main #content div which keeps the navigation off to the side as a separate element. There are so many different ways you could design this interface, but I like seeing the background on the active link turn white and appear to blend into the page itself. Also I have .contentblock.hidden set to no display which we can manipulate directly in jQuery.

/* side navigation */
#sidemenu {
  margin: 0;
  padding: 0;
  width: 80px;
  float: left;
  background: #e8e8e8;
  border-right: 1px solid #c9c9c9;
}


#sidemenu li { display: block; text-align: center; border-top: 1px solid #fff; font-size: 1.1em; }

#sidemenu li a { 
  display: block;
  padding: 6px 2px;
  color: #555;
  text-decoration: none;
  border-bottom: 1px solid #d1d1d1;

}
#sidemenu li a:hover {
  background: #f2f2f2;
}

#sidemenu li a strong { 
  display: block;
  margin-top: 5px;
}

#sidemenu li a.open {
  width: 101%;
  background: #fff;
}

The outer navigation container is fixed to a width of 80px and floated off to the left side. We can use margins and padding on the other content box to keep these two from overlapping. The #sidemenu element uses a border on the right to encapsulate all the links.

Any anchor link with the additional .open class will be set to 101% width. This means it will be wider than the border and appear to be naturally connected into the page content. Everything else about the nav CSS is related to styling the icons and the text which are held in two separate HTML elements.

jQuery Animations

Finally we get to the bottom of the index.html file which includes a small block of jQuery. The main event handler is triggered whenever a user clicks on the navigation link items. First we want to disable the click event using e.preventDefault(). Since the content is loading dynamically, we don’t want to append the page ID onto the URL unless JavaScript were disabled.

$(function(){
  $('#sidemenu a').on('click', function(e){
    e.preventDefault();

    if($(this).hasClass('open')) {
      // do nothing because the link is already open
    } else {
      var oldcontent = $('#sidemenu a.open').attr('href');
      var newcontent = $(this).attr('href');
      
      $(oldcontent).fadeOut('fast', function(){
        $(newcontent).fadeIn().removeClass('hidden');
        $(oldcontent).addClass('hidden');
      });
      
     
      $('#sidemenu a').removeClass('open');
      $(this).addClass('open');
    }
  });
});

Jumping into the actual logic, we first check if the currently clicked item has a class of .open. If so then the link is already visible so we do nothing. Otherwise we create two new variables named oldcontent and newcontent. Using jQuery .fadeOut() on the old content we can then use a callback function to add the .hidden class while simultaneously showing the new content with .fadeIn().

The final two lines of code adjust the menu item once all the inner content has finished animating. We remove all .open classes from the menu links and then apply it onto the newly selected link item. This all happens within 1-2 seconds of time so it appears very sequential. We could always use a jQuery delay if there was some need to halt the animations. But this generic interface is quite easy to setup and shouldn’t require a whole lot of convoluted scripting.

Final Thoughts

I hope this tutorial may be useful to some web designers or developers who need a similar widget. The codes are easy to transfer into your own script or even into a plugin if needed. Of course, plugin functionality might be more convoluted than we need – but this type of dynamic webpage effect is perfect for section-based content with divisions in the material. Feel free to download a copy of my source codes and see if you can implement this design in your own future projects.


Advertise here with BSA

July 28 2013

09:00

Tabulous.js: Organize Random Content in Tabs with jQuery


  

Aaron Lumsden from West-Yorkshire simply loves jQuery. It’s been merely a few days ago, that we introduced our readers to progression.js, a plugin that gives users real time hints and progress updates as they complete forms. Today I ran across another useful plugin by the same programmer. Tabulous.js helps you organize any content in containers with tabbed navigation and nice animated effects to hide and show the enclosed elements.

Sponsored post
feedback2020-admin
04:05

June 30 2010

12:15

January 18 2010

18:34

Sexy Animated Tabs Using MooTools

One modern, attractive way of placing a lot of content into a little space is by using a tab system. This tutorial will show you how to create a sexy, animated tab system complete with CSS sprites, cookies, and animated tab swapping.


MooTools Tabs

Assumptions

There are a few assumptions and notes that we’re going into this system with:

  • We’ll be using the most recent version of MooTools: 1.2.4.
  • The client must support JavaScript.
  • We’ll be using PHP for any server-side scripting. Any server-side language of your choosing will also work its corresponding syntax/methods

The tutorial also assumes a basic knowledge of javascript. A tiny bit of MooTools or JavaScript framework experience will help.

The Plot

So how is this awesome system going to work? Here’s the basic outline:

  • When the page loads, we output two UL lists with list items: the first list contains the tabs, the second list contains the tab content items.
  • For each tab set we output, we check for a given cookie that could tell us which tab should be displayed based on the previous visit. If no cookie is present, we assume the first tab.
  • When the user clicks a tab, the current content item for that tab slides out of view and the new tab content slides in.
  • We save the index of the tab in a cookie for future loading purposes (i.e. we want to make the last-clicked-tab the first to display on the next page/visit.)

The system itself is pretty bulletproof. If the user doesn’t allow cookies, the starting tab for each list will always be 0.
If JavaScript support isn’t present, the tabs wont be seen on screen as we’ll display:none; them initially.

Step One: The HTML

The HTML to accomplish the tab system and corresponding content items is incredibly simple in structure.

<div class="tab-container">
	<ul id="tabs1" class="tabs">
		<li>Tab 1</li>
		<li>Tab 2</li>
		<li>Tab 3</li>
		<li>Tab 4</li>
	</ul>
	<div class="clear"></div>
	<ul id="contents1" class="tabs-content">
		<li>This is the content for tab 1.</li>
		<li>This is the content for tab 2.</li>
		<li>This is the content for tab 3.</li>
		<li>This is the content for tab 4.</li>
	</ul>
</div>

We will be modifying the above HTML with PHP later in this tutorial to create a more robust system.

MooTools Tabs

Step Two: CSS

As with any CSS and HTML combo, you may style the tabs and their content items however you’d like.
I’ve chosen to use Facebook-style CSS sprites for my example tabs.
Realize that you’ll want to style the following items in a specific fashion so that the system works:

  • The tab content items must have a height of 0 and their overflow’s hidden. That allows for all of the content items to be “hidden”, so to speak, when the page loads.
  • Between the “ul.tabs li a” and “ul.tabs li a.active” CSS selectors, you’ll want to assign the “active” selector a different look so that the user knows its’ the currently selected tab.
/* tabs structure */
.tab-container	{ width:320px; background:#eee; padding:5px 10px; }
ul.tabs			{ list-style-type:none; margin:0; padding:0; }
	ul.tabs li		{ float:left; margin:10px 5px 0 0; }
	ul.tabs li a	{ padding:5px 10px; border:1px solid #ddd; font-weight:bold; background:url(tab-sprite.jpg) 0 0 repeat-x; color:#000; text-decoration:none; }
	ul.tabs li a.active	{ border-color:#028433; background-position:0 -96px; color:#fff; } /* sprite! background position swap */
		ul.tabs li a.active:hover	{ text-decoration:none; cursor:default; }
	ul.tabs li:hover	{ text-decoration:underline; }
ul.tabs-content	{ margin:10px 0 0 0; padding:0; }
	ul.tabs-content li	{ height:0; overflow:hidden; margin:0; padding:0; }

/* clears floats */
div.clear		{ clear:both; }

/* ie fixes */
* html ul.tabs-content li { float:left; } /* ie6 */
*+ html ul.tabs-content li { width:99%; float:left; } /* ie7 */

Note that we need to implement a few Internet Explorer-specific fixes; ugly, but necessary.

MooTools Javascript Framework

Step Three: The MooTools Javascript

One of the great advantages of MooTools is the powerful Class system.
MooTools classes allow for flexible, organized, and extendable functionalities.
Our MooTools class will be called “TabSet.” Since the TabSet class performs many actions,
lets break down each part of the class.

The first line is always giving the class a name:

/* give the class a name */
var TabSet = new Class({

Next we need to create an object that will hold our class’ options:

	options: { //default tab options
		activeClass: 'active', //css class
		cookieName: '', //no name means no cookie
		cookieOptions: { //options for the cookie, if cookie's wanted
			duration: 30, //30 days
			path: '/'
		},
		startIndex: 0 //start with this item if no cookie or active
	},

Our options allow us to define:

  • activeClass: The CSS class that should be assigned to the currently-selected (or “active”) tab.
  • cookieName: The name of the cookie that will represent this tab set. If you don’t define a cookie name, cookies wont be used.
  • cookieOptions: An object that holds the options for the cookie.
  • startIndex: The tab to make active initially. Starts with 0. Overridden by the activeClass variable if a cookie is found.

With only three options in the class, TabSet would be considered a relatively simple class.

Next we implement two Options and Events:

Implements: [Options,Events],

Implementing Options and Events will allow us to correctly handle given options and
fire custom Load and Change events on our lists anywhere within the class.

Next we define the “initialize” method which runs upon creation of every instance of the class:

	initialize: function(tabs,contents,options) {
		//handle arguments
		this.setOptions(options); //mix the given options with the default options
		this.tabs = $$(tabs); //save the given tabs within the class
		this.contents = $$(contents); //save the given "contents" within the class
		//determine the "active" tab
		var active = (Cookie.read(this.options.cookieName) || this.options.startIndex);  //decide the index that should be active initially
		this.activeTab = this.tabs[active].addClass(this.options.activeClass); //now identify the "active" tab
		this.activeContent = this.contents[active].setStyle('height','auto'); //identify the "active" content
		//run each tab/content combo through the "processItem" method which we'll see below
		this.tabs.each(function(tab,i) { this.processItem(tab,this.contents[i],i); },this);
		//tabs are ready -- fire the load event!
		this.fireEvent('load');
	},

Next comes the workhorse method of our TabSet class: processItem:

	processItem:function(tab,content,i) {
		var contentHeight = content.getScrollSize().y;
		//add a click event to the tab
		tab.addEvent('click',function() {
			//if it's not the active tab
			if(tab != this.activeTab) {
				//stopper
				if(e) e.stop();
				//remove the active class from the active tab
				this.activeTab.removeClass(this.options.activeClass);
				//make the clicked tab the active tab
				(this.activeTab = tab).addClass(this.options.activeClass);
				//tween the old tab content up
				//tween the new content down
				this.activeContent.set('tween',{
					onComplete:function() {
						this.activeContent = content.fade('in').set('tween',{ onComplete: $empty }).tween('height',contentHeight);
						//fire the tab change event
						this.fireEvent('change',[tab,content]);
					}.bind(this)
				}).setStyles({
					height: contentHeight,
					overflow: 'hidden'
				}).fade('out').tween('height',0);
				//save the index to cookie
				if(this.options.cookieName) Cookie.write(this.options.cookieName,i);
			}
		}.bind(this));
	}
});

Here’s the basic outline of what the processItem method does:

  1. Accepts a matching tab, content item, and its index…
  2. Calculates the height of the content element.
  3. Adds a click event to the tab that:
    1. Validates that this tab isn’t already active (we don’t want to animate or change anything if they click the already-active tab)
    2. Removes the “active” CSS class from the current tab and adds it to the tab that was just clicked.
    3. Slides the current tab’s content out of view, then slides the new content into view. The “change” event is fired when the animation is complete.
    4. Saves the new tab’s index to the cookie so that when the user reloads the page or goes to another page, the new tab will be selected initially.

And now a sample usage of our class:

window.addEvent('domready',function() {
	var tabset = new TabSet($$('#tabs1 li a'),$$('#contents1 li'),{
		cookieName: 'demo-list'
	});
});

We provide our instance the tab LI A’s and the content LI’s. We also provide the optional options argument. That’s how easy it is to use this class! Here’s the complete class with usage:

/* class */
var TabSet = new Class({
	options: {
		activeClass: 'active', //css class
		cookieName: '',
		cookieOptions: {
			duration: 30, //30 days
			path: '/'
		},
		startIndex: 0 //start with this item if no cookie or active
	},
	Implements: [Options,Events],
	initialize: function(tabs,contents,options) {
		//handle arguments
		this.setOptions(options);
		this.tabs = $$(tabs);
		this.contents = $$(contents);
		//determine the "active" tab
		var active = (Cookie.read(this.options.cookieName) || this.options.startIndex);
		this.activeTab = this.tabs[active].addClass(this.options.activeClass);
		this.activeContent = this.contents[active].setStyle('height','auto');
		//process each tab and content
		this.tabs.each(function(tab,i) {
			this.processItem(tab,this.contents[i],i);
		},this);
		//tabs are ready -- load it!
		this.fireEvent('load');
	},
	processItem:function(tab,content,i) {
		var contentHeight = content.getScrollSize().y;
		//add a click event to the tab
		tab.addEvent('click',function(e) {
			//stop!
			if(e) e.stop();
			//if it's not the active tab
			if(tab != this.activeTab) {
				//remove the active class from the active tab
				this.activeTab.removeClass(this.options.activeClass);
				//make the clicked tab the active tab
				(this.activeTab = tab).addClass(this.options.activeClass);
				//tween the old tab content up
				//tween the new content down
				this.activeContent.set('tween',{
					onComplete:function() {
						this.activeContent = content.fade('in').set('tween',{ onComplete: $empty }).tween('height',contentHeight);
						//fire the tab change event
						this.fireEvent('change',[tab,content]);
					}.bind(this)
				}).setStyles({
					height: contentHeight,
					overflow: 'hidden'
				}).fade('out').tween('height',0);
				//save the index to cookie
				if(this.options.cookieName) Cookie.write(this.options.cookieName,i,this.options.cookieOptions);
			}
		}.bind(this));
	}
});

/* usage */
window.addEvent('load',function() {
	var tabset = new TabSet($$('#tabs1 li a'),$$('#contents1 li'),{
		cookieName: 'demo-list'
	});
});
MooTools Cookies

Step Four: PHP / HTML

Remember how I said we’d be modifying our original HTML with PHP? Now’s the time. Since we may
have a cookie set for our TabSet, we should attempt to detect that when we output the tab HTML.
Why? Because we want the tabs to load in smoothly. We also want to accommodate for users that don’t have JavaScript or cookies enabled.
Without this PHP, you may notice a slight “jump” in the active content area.

<?php
	/*
		Removes a desired variable from the querystring
		Credit:  http://www.addedbytes.com/code/querystring-functions/
	*/
	function remove_querystring_var($url, $key) {
		$url = preg_replace('/(.*)(\?|&)' . $key . '=[^&]+?(&)(.*)/i', '$1$2$4', $url . '&');
		$url = substr($url, 0, -1);
		return ($url);
	}

	/* generate the urls */
	$demo_tabs_url = remove_querystring_var($_SERVER['REQUEST_URI'],'demo-list');
	$demo_tabs_url.= (is_numeric(strpos($demo_tabs_url,'demo-list')) ? '&' : '?').'demo-list=';

	/* current tab */
	$current_tab = isset($_COOKIE['demo-list']) ? (int) $_COOKIE['demo-list'] : (isset($_GET['demo-list']) ? (int) $_GET['demo-list'] : 0);

?>

<div class="tab-container">
	<ul id="tabs1" class="tabs">
		<li><a href="<?php echo $demo_tabs_url.'0'; ?>" <?php echo $current_tab == '0' ? ' class="active"' : ''; ?>>Tab 1</a></li>
		<li><a href="<?php echo $demo_tabs_url.'1'; ?>"  <?php echo $current_tab == '1' ? 'class="active"' : ''; ?>>Tab 2</a></li>
		<li><a href="<?php echo $demo_tabs_url.'2'; ?>"  <?php echo $current_tab == '2' ? 'class="active"' : ''; ?>>Tab 3</a></li>
		<li><a href="<?php echo $demo_tabs_url.'3'; ?>"  <?php echo $current_tab == '3' ? 'class="active"' : ''; ?>>Tab 4</a></li>
	</ul>
	<div class="clear"></div>
	<ul id="contents1" class="tabs-content">
		<li <?php echo $current_tab == '0' ? ' style="height:auto;"' : ''; ?>>This is the content for tab 1. This is the content for tab 1. This is the content for tab 1. This is the content for tab 1. This is the content for tab 1. This is the content for tab 1. This is the content for tab 1. This is the content for tab 1.</li>
		<li <?php echo $current_tab == '1' ? ' style="height:auto;"' : ''; ?>>This is the content for tab 2. This is the content for tab 2. This is the content for tab 2. This is the content for tab 2. This is the content for tab 2. This is the content for tab 2. This is the content for tab 2. This is the content for tab 2.</li>
		<li <?php echo $current_tab == '2' ? ' style="height:auto;"' : ''; ?>>This is the content for tab 3. This is the content for tab 3. This is the content for tab 3. This is the content for tab 3. This is the content for tab 3. This is the content for tab 3. This is the content for tab 3. This is the content for tab 3.</li>
		<li <?php echo $current_tab == '3' ? ' style="height:auto;"' : ''; ?>>This is the content for tab 4. This is the content for tab 4. This is the content for tab 4. This is the content for tab 4. This is the content for tab 4. This is the content for tab 4. This is the content for tab 4. This is the content for tab 4.</li>
	</ul>
</div>

Step Five: PHP: Accommodating For Users Without Javascript or Cookies

Some users don’t enable JavaScript or cookies for security purposes. We still want our system to work for them though. If you recall from the previous block of code,
we’re using links with a querystring key of “demo-list” to denote a change in tab. The following block of PHP at the top of the page (before ANY output) will
help us change the cookie value to the requested tab.

<?php
	/* handle the cookies */
	if($_GET['demo-list']) {
		/* set the new cookie */
		setcookie('demo-list',(int) $_GET['demo-list'],time()+60*60*24*30,'/'); //30 days
		if($_COOKIE['demo-list']) {
			header('Location: '.remove_querystring_var($_SERVER['REQUEST_URI'],'demo-list'));
			exit();
		}
	}
?>

Note that we only refresh the page if we can verify that the cookie has been set. If the cookie hasn’t been set, the user has their cookies disabled.

MooTools Cookies

Mission Accomplished!

Here’s a quick summary of the benefits of the MooTools TabSet class:

  • Our class implements Events so that we may create custom events and event handlers.
  • The layout of the entire system is controlled completely by simple HTML and CSS.
  • The use of cookies to remember the previous tab is great usability improvement.
  • The very class that it’s a MooTools class allows for it to be easily implemented from project to project.

The Inline MooTools Javascript

I’ve always advocated coding a desired MooTools functionality “inline” before turning it into a class. Here’s the inline MooTools JavaScript code:

$$('ul.tabs').each(function(tabList) {
	//get the content list
	var tabContentList = tabList.getNext('ul.tabs-content'),
		//get the name of the cookie, which is the "title" attribute of the tab list
		cookie = 'demo-list',
		//the start tab index
		startIndex = Cookie.read(cookie) || 0,
		//get the actual tab LI items
		tabs = tabList.set('title','').getElements('li'),
		//get the content LI items
		lis = tabContentList.getElements('li'),
		//the tab (LI) that is currently active
		activeTab = tabs[startIndex].addClass('active'),
		//the content LI that is currently active
		activeContent = lis[startIndex].setStyle('height','auto');
	//for every tab within this tab/content relationship...
	tabs.each(function(tab,i) {
		//stopper
		if(e) e.stop();
		//calculate the respective content item's height
		var content = lis[i], contentHeight = content.getScrollSize().y;
		//add the click event to the tab which...
		tab.addEvent('click',function() {
			//if it's not the currently activated tab...
			if(tab != activeTab) {
				//add and remove the active class from old vs. new tab
				activeTab.removeClass('active');
				(activeTab = tab).addClass('active');
				//start the wipe up, wipe down effect
				activeContent.set('tween',{
					onComplete:function() {
						activeContent = content.fade('in').set('tween',{ onComplete: $empty }).tween('height',contentHeight);
					}
				}).setStyles({
					height: contentHeight,
					overflow: 'hidden'
				}).fade('out').tween('height','0');
				//write to cookie
				Cookie.write(cookie,i);
				//fin!
			}
		});
	});
	//fire click event
	activeTab.fireEvent('click');
});

Notice that all of the “var” statements at the top either become arguments or options for the class. The transition from inline MooTools JavaScript to a class is extremely simple!

MooTools Tabs

Have Improvement Ideas?

Have more ideas for this class? Be sure to share them in the comments below!

Write a Plus Tutorial

Did you know that you can earn up to $600 for writing a PLUS tutorial and/or screencast for us? We’re looking for in depth and well-written tutorials on HTML, CSS, PHP, and JavaScript. If you’re of the ability, please contact Jeffrey at nettuts@tutsplus.com.

Please note that actual compensation will be dependent upon the quality of the final tutorial and screencast.

Write a PLUS tutorial


Older posts are this way If this message doesn't go away, click anywhere on the page to continue loading posts.
Could not load more posts
Maybe Soup is currently being updated? I'll try again automatically in a few seconds...
Just a second, loading more posts...
You've reached the end.
(PRO)
No Soup for you

Don't be the product, buy the product!

close
YES, I want to SOUP ●UP for ...