The html times

Elegantly Powered by Google

The Anatomy of a jQuery Plugin by Thomas Steinmetz March 31st 2009 Delicious



Relevant Links

jQuery Plugins Library

Relevant Downloads

Writing a jQuery Plugin: Yet Another Tab Example

I started to tool around on my site earlier today and wanted an easy way for jQuery to control not only the actions of the tabs, but the css as well. I figured now was as good a time as any to write my first plugin. By the end of this little blurb you will hopefully have a better understanding of how to write a basic jQuery plugin.

First we need to tell jQuery what we are writing is a plugin. We do this by starting with $.fn.nktabs = function() {}. This tell jQuery we now have a plugin that can be called by something like $("#tabs").nktabs();. Seems simple, right?

Next we want to give the plug-some actual meat. Lets write the core of the tab switching, what happens whens someone clicks a tab.

  1. $(this).each(function() {
  2. $(this).children('li').children('a').each(function(){
  3. $("#" + this.id).click(function(){
  4. $("#" + active).css('background', options.a_background).css('border', options.a_border).css('color', options.a_color);
  5. show = this.id;
  6. $(".content").each(function(){
  7. $("#" + this.id).fadeOut("slow", function(){ if(count == x) {$("#content_" + show).fadeIn("slow"); count = 0;} else count++;});
  8. });
  9. $("#" + this.id).blur();
  10. $("#" + this.id).css('background', options.active_background).css('border-bottom', options.active_border_bottom).css('color', options.active_color);
  11. active = this.id;
  12. });
  13. });
  14. });

If you are familiar with jQuery you will know what this does, but for those that do not I will walk through it briefly. The first line, $(this).each(function(){ loops through each of the objects you have your plugin called from, in this case it would be our div with the id of "tabs", $("#tabs").nktabs(); . Next, since this is a list, we want to go from the top portion of the struction, the "" tag, down to the "<a>" where our tab link is (what the user will click on) so we traverse down it's children (sidenote: children are any node that resides inside of another node, eg: <ul><li>something<ul> -- the <li> is the child) with this line of code $(this).children('li').children('a').each(function(){ and we go straight to the "<a>" tag.

A semi-graphical way of looking at it is <ul> ---> <li> ---> <a>, the <a> tag is <li>'s child, which is <ul>'s child. Next we add an event listener to each this.id (the id of each <a>) so that when it is clicked, that function gets invoked. Within that anonymous function, we take any currently active tab, set the styles to be inactive, fade out any showing content div, and then fade in the content div corresponding to the id of the clicked <a> (naming scheme: #content_<a>.id). Lastly we just $("#" + this.id).blur(); to remove the dashed lines from the link we clicked and then add in the active css to the tab the <a> link is in. More on this below.

Back when we declared our plugin, we had an anonymous function with no arguments, it's time to change that. You will notice now we pass in a variable, "options".

  1. $.fn.nktabs = function(options) {

What this does is lets the user select options to control how the tabs look, their CSS. In order to control the CSS of the tabs inside our plugin we define some options of our own to be our defaults:

  1. var options = $.extend({
  2. float: 'right',
  3. padding_bottom:'19px',
  4. padding_left:'10px',
  5. margin_top: '55px',
  6. margin_right: '40px',
  7. display : 'inline',
  8. list_style_type : 'none',
  9. width: '100px',
  10. margin: '0',
  11. a_background: '#E8EBF0',
  12. a_border: '1px solid #ccc',
  13. a_color: '#5294FC',
  14. a_float: 'left',
  15. a_font_size: 'medium',
  16. a_font_weight: 'normal',
  17. a_line_height: '20px',
  18. a_margin_right: '8px',
  19. a_padding: '2px 13px 2px 12px',
  20. a_text_decoration: 'none',
  21. hover_color: '#f00',
  22. active_background: '#fff',
  23. active_border_bottom: '1px solid #fff',
  24. active_color: '#5294FC'
  25. }, options);

What this does is extends the options object that could be passed from the user (eg: $("#tabs").nktabs(my_options);) and we call $.extend() on them. This essentially lets us declare our own options object and then compares it with options object passed by the user. Attributes that exist in the user's options object over write the ones declared in the list you see above. A user does not have to pass their own for each specific attribute. If the user only wants to change the color of an active tab and the hover color, they just do the following:

  1. var my_options = { active_color: '#000', hover_color: '#5294FC' };
  2. $("#tabs").nktabs(my_options);

Now only those two will override the defaults.

Next we have to apply the css to each of the list elements, below is the code that does just that.

  1. $(this).css('float', options.float).css('padding-bottom', options.padding_bottom).css('padding-left', options.padding_left)
  2. .css('margin-top', options.margin_top).css('margin-right', options.margin_right);
  3.  
  4. $(this).children('li').each(function(){
  5. $(this).css('display', options.display).css('list-style-type', options.list_style_type).css('width', options.width).css('margin', options.margin);
  6. });
  7.  
  8. $(this).children('li').children('a').each(function(){
  9. $(this).css('background', options.a_background).css('border', options.a_border).css('color', options.a_color).css('float', options.a_float)
  10. .css('font-size', options.a_font_size).css('font-weight', options.a_font_weight).css('line-height', options.a_line_height)
  11. .css('margin-right', options.a_margin_right).css('padding', options.a_padding).css('text-decoration', options.a_text_decoration)
  12. .hover(function(){ $(this).css('color', options.hover_color);}, function(){ $(this).css('color', options.a_color);});
  13. if(x == 0)
  14. {
  15. $(this).css('background', options.active_background).css('border-bottom', options.active_border_bottom).css('color', options.active_color);
  16. active = this.id;
  17.  
  18. } x++;
  19. });

It is pretty self-explanitory. We chain .css() calls onto one another until we have applied all of our css to that element. The only complex portion of this code is the if(x == 0) which looks to see if this is the first tab we are styling, if it is we need to set it to be the active tab, since it is the first to load on the page.

A full exmple of how to implement this plugin:

In the head of your html:

  1. <script type="text/javascript" src="js/nktabs.jquery.js"></script>
  2. <script>
  3. $("#tabs).nktabs();
  4. </script>

And your actual tab structure:

  1. <ul id="tabs">
  2. <li><a id="home" href="#" class="tab" >Home</a></li>
  3. <li><a id="about" href="#" class="tab" >About</a></li>
  4. <li><a id="projects" href="#" class="tab" >Projects</a></li>
  5. <li><a id="contact" href="#" class="tab" >Contact</a></li>
  6. </ul>

And there you have it. With this plugin you can now create tabs very little effort. If you have any questions please comment below or email thsteinmetz [at] gmail [dot] com.


Comments

Comments are now closed

Related Articles:

Frameworks, Idioms, and Idiots

By Joshua Clayton

Joshua Clayton examines the upshot of using framework syntax in place of actually learning Javascript, and asks us to stop being lazy.
Read more …


Introducing GenevaJS

By Rick Waldron

Rick Waldron walks us through the first set of methods in the upcoming Javascript extension kit for writing jQuery style syntax with Prototype. Read more …


Putting the Kaibosh on IE6

By Boaz Sender

Boaz sender walks us through serving a message to visitors based on their browser version. Read more …



Information Wants To Be Free

Elegantly Powered by Google