Skip to content Skip to tags Skip to twitter news Skip to blog roll Skip to categories Skip to archives Skip to recent posts

November 20, 2008

5 Comments

Slide in tab window using jQuery

by in jQuery,Tips,Tutorials,Web Development on November 20, 2008 @ 12:03 am

Say you want to wanted to put little tabs – you know, the ones like what you get from a lawyer or a realestate again to point out important things – off the side of your page so that your users can click, bring that tab into view to see what important information you want to point out.  Yeah, I know, you’ve seen these “tabs” a millions times and that is fine, but you have not seen it from my site and most likely you were not secretly brainwashed into learning about other jQuery methods that you don’t already use or know about.

So, let the brainwashing education begin!

The Tabs

Take a look off to the left I moved the demo here, do you see the three tabs that are there, they are so spectacularly named “tab 1″, “tab2″ and, yup you guessed it, “tab3.”  The html structure is pretty straight forward:

  1. <div id="sideTabs">
  2.     <div class="tab">
  3.         <h3>Tab 1</h3>
  4.         <div class="gut">
  5.             <p>Some text</p>
  6.         </div>
  7.     </div>
  8.     <div class="tab">
  9.         <h3>Tab 2</h3>
  10.         <div class="gut">
  11.             <ul>
  12.                 <li>link</li>
  13.             </ul>
  14.         </div>
  15.     </div>
  16.     <div class="tab">
  17.         <h3>Tab 3</h3>
  18.         <div class="gut">
  19.             <ul>
  20.                 <li>link</li>
  21.             </ul>
  22.         </div>
  23.     </div>
  24. </div>

You will notice that there are no links for the tabs and this is because we will create them on the fly.  Why?  Well, other then that I have a plan to show you some new tricks, imagine that you have JavaScript turned off, those will just be pointless links with a hash in them.  You can probably argue that we can put an ID with each tab and that link will be a link hash to that ID, and I will say that you are being brainwashed educated to my thinking.

The CSS

This part is actually completely open to you to format how ever you want, my initial thought was to do a bunch of “progressive enhancements” – don’t you love buzzwords for not truly supporting older browsers – that would entail some gradients, rounded corners and dropshadows, but the point of this post was not to show off my CSS3 prowest.  The point was to show you some fancy methods so here is the CSS I am using:

  1. #sideTabs.closed{
  2.     left:-310px;
  3. }
  4. #sideTabs{
  5.     position:fixed;
  6.     left:0;
  7.     top:100px;
  8.     width:300px;
  9.     height:300px;
  10.     border: 10px solid #000000;
  11.     background:#fff;
  12. }
  13. #sideTabs a.tabLinks{
  14.     position:absolute;
  15.     right:0;
  16.     top:0;
  17.     outline:none;
  18.     display:block;
  19.     border: 10px solid #000000;
  20.     border-width:1px 1px 1px 0px;
  21.     -moz-border-radius: 0px 200px 200px 0px;
  22.     -webkit-border-radius: none 200px 200px none;
  23.     margin:0;
  24.     padding:0 5px 0;
  25.     color:#000;
  26.     text-decoration:none;
  27.     font:12px/25px Verdana, Arial, Helvetica, sans-serif;
  28.     background:#000;
  29.     color:#fff;
  30.     z-index:20;
  31. }
  32. #sideTabs a.tabLinks.active{
  33.     font:bold 14px/25px Verdana, Arial, Helvetica, sans-serif;
  34.     background:#fff;
  35.     color:#000;
  36.     z-index:21;
  37. }

The jQuery

Alright, we are at the meat and potatoes the corn and the cob the Larry and Moe (and Curly)… sadly that is the best I can do with those analogies.  Any who, we are at the JavaScript, what I will do is post the code and the try to explain what is happening line by line:

  1. var jqsideTabs;
  2. var tabs, h = 50, r = 0,ra = 0;
  3. $(document)
  4. .ready(function(){
  5.     jqsideTabs = $('#sideTabs').addClass('closed');
  6.    
  7.     tabs = jqsideTabs
  8.     .find('.tab h3')
  9.     .clone()
  10.     .appendTo(jqsideTabs)
  11.     .each(function(i){
  12.         var that = $(this), cls = '',ow,newThis, newEl;
  13.        
  14.         if( i == 0 ) cls = ' active';
  15.         newEl = $('<a href="#" class="tabLinks'+cls+'">' + that.text() + '</a>');
  16.         that.replaceWith(newEl);
  17.        
  18.         ow = newEl.outerWidth();
  19.        
  20.         if( i == 0 ) ra = ow;
  21.         else r = ow;
  22.        
  23.         h = newEl.css({'top':h , 'right': -ow }).height() + h;
  24.        
  25.         newThis = newEl.get(0);
  26.         newThis.jq = newEl;
  27.         newThis.i = i;
  28.        
  29.         newEl.click(function(){
  30.             var el = this.jq;
  31.            
  32.             if( jqsideTabs.hasClass( 'closed' ) ){
  33.                 jqsideTabs.removeClass('closed');
  34.             }
  35.             else if( !jqsideTabs.hasClass( 'closed' ) && el.hasClass('active') ){
  36.                 jqsideTabs.addClass('closed');
  37.             }
  38.            
  39.             el
  40.             .siblings()
  41.                 .removeClass('active')
  42.                 .css({'right': -r })
  43.             .end()
  44.             .addClass('active')
  45.             .css({'right': -ra });
  46.            
  47.             tabs.eq( this.i ).show().siblings('.tab').hide();
  48.            
  49.             return false;
  50.         });
  51.     })
  52.     .end()
  53.     .parent()
  54.         .eq(0)
  55.         .addClass('active')
  56.     .end()
  57.         .filter(':not(:eq(0))')
  58.         .hide()
  59.     .end();
  60.  
  61.     jqsideTabs.bind("mouseleave",function(){
  62.         jqsideTabs
  63.         .animate({left:-310}, 'fast', function(){
  64.             jqsideTabs.addClass('closed').removeAttr('style');
  65.         });
  66.     });
  67. });

Update: Moved the demo to a separate page.

The Explanation

Lines 1 and 2 are just some variables that I will be setting and reusing through-out the code.

Line 5 I set the “jqsideTabs” variable to reference the jQuery object for the element with an ID of sideTabs and I also add a class of “close”.

Line 7 a reference is being set and I will point a little later below what that is actually being referenced too.

Line 8 we look inside the jqsideTabs DIV for the H3 elements that are inside the “.tab” DIVs.  I can just as easily do jqsideTabs.find(‘.tab > h3′) to make sure to the H3 tag directly below the “.tab” element or jqsideTabs.find(‘.tab h3:first-child‘) to make sure I grabbing the first H3 that is the first element under ‘.tab’.

Line 9 we clone() those H3 elements, if we do .clone(true) we will also clone any events that are bound to the H3.

Line 10 we append the cloned H3s to “jqsideTabs”

Line 11 through to 51 we are looping through those H3s to do some fanciness.  Notice the “i” in the function?  That will be returning the index of the loop starting at zero (0).

Line 12 some variables are set up.

Line 14 we check if we are on the first index, which is zero (0), and then set the “cls” variable to “active”.

Line 15 we set up a reference to a new DOM element/jQuery object that has the text of the H3 element by using “that.text()“.

Line 16 we replace the H3 with the newly create DOM element, the A element/tag/

Line 18 we get the outer width (.outerWidth()) of the element, outerWidth() will get the full width of the element including border and padding, if you were to do outerWidth(true) you would also get the margins.

Line 20 we check if it is the first index again and if so, set the variable “ra” to the outer width

Line 21 is the else part of line 20 and here we set the “r” variable.  Both “ra” and “r” will be used for “right active” and “right”.  You will see their purpose shortly.

Line 23 is doing a few things, 1) it is setting the top and right positions of the element and returning the .height() of the element plus the previously stored height at the same time.

Line 25 we are using the .get(0) method against the newly created A tag and this will give us the equivalent of doing a getElementById.

Line 26 we set the reference now so that we don’t have to re-look up this element later on, the speed gain is probably minimum at best but I makes me happy to do this and really, that is what it’s all about.

Line 27 and line 26 we are doing something specific and really can’t remember what it is called, maybe “assignment,” but basically we are storing some data directly in the DOM to be used later.

Line 29 we add a .click() event to the A tag we created.

Line 30 just to stick to a decent naming conventions I take the varariable I set earlier and plop it into a new variable call “el” (short for element)

Line 32 to 34 we check to see if the jqsideTabs element has a class (.hasClass()) of “closed”, if so, remove that class.

Line 35 to 37 we check to see if the jqsidetabs element does not have a class of “closed” and the current element has a class of “active”, if so, add the class “close”.

Line 40 we grab all the .siblings(), in this case, all the .tab DIVs and links that were created.

Line 41 each item returns will have the class “active” removed.

Line 42 the default right position is set for those elements.  But let me note something real quick, in this case I am going with the assumption that I did not set the “position” of the .tab elements to anything, meaning, they were not set to relative or absolute.  If I did this I would need to change siblings to only grab items at are A tags to be sure I only grab the, well, A tags.

Line 43 the .end() method is used, this brings the reference back to “el” at line 39.

Line 44 a class of “active” is added.

Line 45 the right position is set to the “ra” variable.

Line 47 with the reference of tabs that was set back at line 7, we find the DIV or .tab that equals what ever that index (i) is match to, in the example it can be either 0, 1 or 2, then we show that one and then hide its siblings that have a class of “.tab”.

Line 49 a return of false is used to stop the default action of the link.

Line 52 end() is used to give reference back to the H3 tags.

Line 53 we use .parent() to grab the parents of the H3 tags.

Line 54 we filter down to the first element in the parents by using .eq(0).

Line 55 a class is added to that returned element from line 54.

Line 56 we go back to all the parents by using .end()

Line 57 filter is used with the combination seletor of “:not()” and “:eq(0)” to grab all the DIVs (the parents of the H3s) that is not equal to the first one.

Line 58 then we hide the returned elements

Line 59 here we use end() to finally set the “tabs” variable that we have way back at line 7.

The Closing

Ok, are you brainwashed educated yet?  Could I have combined a few steps or could I have writen some of my selectors to be a little more precise? Sure I could have.  The beauty of coding with jQuery is that there can be any number of ways to approach the same exact issue.  But do keep in mind that my way is always the right way.

But seriously, there are a lot of ways to use the jQuery framework, you have to find the way the best suits you.  And the only way to find that out is to learn how others do it and read the docs and learn the selectors and traversing methods.

As always, please feel free to check me if I got something incorrect or if you think you can do better.  I am just as open to learning as you should be.

back to beginning of this post back to skip to links
Tags:

If you liked this article why don't you share it:

Stumble it delicious Digg it Reddit it DZone it Bump it Mixx it! Buzz up! E-mail

5 Responses to “Slide in tab window using jQuery”

Not bad, but I’d recommend a second page for demos. When you view your feedburner feed, the tabs show up on that page as well:
http://feeds.feedburner.com/benjaminsterling

Ah, good call, let me see if I can get that up soon.

Nice implementation. I do agree with Andy, it should be on a separate page for demos. I’d also recommend adding a slide back in after a short period of time -or- a click elsewhere and it collapses back option. So that it’s not always open unless you close it.

Thanks James, and you are right, I had gotten another message like via twitter, and I guess I did not put a ton of thought on closing it in other way other than clicking the link again. I am going to put a mouse leave in there in a bit. Thanks for the comments

Trackbacks

  1. Web Tech November Meetup Presentation | The Book and the Cover

Learn from my mistakes, I got burnt by the flame, you don't have to.


RSS Feed Link My Hosting of Choice

69 queries. 0.379 seconds. Powered by WordPress visitor stats