Techblog Careesma Just another Network site

25Oct/10Off

FBJS tabs

Last week I had to work on a Facebook page that requested a second level of tabs. I was completely new to FBML and FBJS, but with modern javascript libraries you can do a tabbed interface with a couple of lines of code, so I thought it would have been a quick thing. With my great disappointment, I found out that doing such a simple thing in FBJS can be a horribly complicated task, so I decided that nobody else in the world had to suffer the same pain I did, and wrote down this tutorial. The final code goes against all my principles, it's not semantic nor sintactically correct. But it works.

First of all, let's take a look at what we are going to achieve, so please check the final results. It's a Facebook page with a second level of tabs (the first one is the typical Facebook's menu with the Wall, etc...). The content of each tabs opens in the page without reload.

The final result

The tutorial is made of 2 parts:

  1. Basic code
  2. Extra CSS and javascript, or how I prefer to call it: “An active tab must look like an active tab”
    • CSS
    • Javascript and final code

I'll assume you know how to create a static FBML tab in a Facebook page. If not, follow the previous link, read the post, then come back here :D

Basic code

Our starting markup doesn't look that bad. It's a normal navigation menu, plus 2 FBML tags: clicktoshow and clicktohide. I don't think I need to explain what they do... The whole code is taken from a really smart post on Snipe.net called Extending Facebook Static FBML Tabs with Dynamic Content. The best thing is that... it already works! You can past it in a FBML page to check it:

<ol id="sub-nav">
     <li><a id="link1" clicktoshow="tab1" clicktohide="tab2,tab3,tab4" title="Willkommen" class="active">First tab</a></li>
     <li><a id="link2" clicktoshow="tab2" clicktohide="tab1,tab3,tab4" title="Team">Second tab</a></li>
     <li><a id="link3" clicktoshow="tab3" clicktohide="tab1,tab2,tab4" title="Jobsuche">Third tab</a></li>
     <li><a id="link4" clicktoshow="tab4" clicktohide="tab1,tab2,tab3" title="Download">Fourth tab</a></li>
</ol>
<!-- Start #tab1 -->
<div id="tab1">
     <p>Here goes the content of the First Tab</p>
</div>
<!-- End #tab1 -->
<!-- Start #tab2 -->
<div id="tab2" style="display:none">
     <p>Here goes the content of the Second Tab</p>
</div>
<!-- End #tab2 -->
<!-- Start #tab3 -->
<div id="tab3" style="display:none">
     <p>Here goes the content of the Third Tab</p>
</div>
<!-- End #tab3 -->
<!-- Start #tab4 -->
<div id="tab4" style="display:none">
     <p>Here goes the content of the Fourth Tab</p>
</div>
<!-- End #tab4 -->

I just made minor changes to the original code. The most notable of them is that I got rid of the href attribute. I know this is horrible, but I had to: the href, even if you set as value the ids of the divs (which is the correct option), or just #, or even NOTHING AT ALL, causes the page to reload in Explorer 8 when the user is not logged in Facebook. Would you believe it?!?! I also added an id to every link, we will need it in the second part of the tutorial.

That was easy, wasn't it? You can stop here if you want, or read the second part and learn how to make tabs out of the navigation menu and stylize the active tab.

Extra CSS and javascript: “An active tab must look like an active tab”

CSS

First of all, let's take a look at the css. If you use images, you must use the absolute path, and they cannot be on Facebook's servers:

#sub-nav {
     float:left;
     width:520px;
     height:20px;
     margin:0 0 30px;
     padding:0
     font-weight:bold;
     border-bottom:1px solid #999;
}
#sub-nav li {
     position:relative;
     float:left;
     height:21px;
     line-height:19px;
     margin:0 2px -1px;
     padding:0;
     list-style-type:none;
     overflow:hidden;
     cursor:pointer;
}
#sub-nav a {
     display:block;
     margin:0;
     padding:0px 10px;
     color:#333338;
     text-decoration:none;
     font-size:12px;
     background:url('http://yourabsolutepath/bg_tabs.png') 0 -25px repeat-x;
     border:1px solid #999;
     cursor:pointer;
}
#sub-nav a:hover, #sub-nav a.active {background:#fff;border-bottom-color:#fff;}

It's a very simple css: it makes &lt;ol&gt; appear like a tabbed menu; the active tab and the :hover status have a different style. Surprisingly, I had to force the cursor of the mouse to be shown as a pointer, but I must say the final result is well integrated with Facebook's interface.

Now, in order to all browsers to load correctly the css, here what you have to put at the beginning of your FBML:

<link rel="stylesheet" type="text/css" media="screen" href="http://yourabsolutepath/style.css?v=1.0" />

The CSS must be external for Explorer 8 to render it, and the version number is needed to force Facebook to reload it (so everytime you make some change to the style, also remember to update the version number in the FBML). You can also read this note by Hyperarts about correctly setting up your CSS for Facebook.

Javascript and final code

The real pain the neck was that I had set a class for the active tab but I couldn't use a non-obstrusive script with simple selectors like in jQuery, where a $('#subnav a') and a click() function would have made all the work. Beside that, javascript can't be external to work in Facebook. So I took a jump back into the 90's and started writing a different function for each link, using the FBJS' getElementById and firing it with an onClick event attribute. So here's what the complete code should look like:

<link rel="stylesheet" type="text/css" media="screen" href="http://yourabsolutepath/style.css?v=1.0" />
<ol id="sub-nav">
     <li><a id="link1" clicktoshow="tab1" clicktohide="tab2,tab3,tab4" onClick="tab1_active();" title="Willkommen" class="active">First tab</a></li>
     <li><a id="link2" clicktoshow="tab2" clicktohide="tab1,tab3,tab4" onClick="tab2_active();" title="Team">Second tab</a></li>
     <li><a id="link3" clicktoshow="tab3" clicktohide="tab1,tab2,tab4" onClick="tab3_active();" title="Jobsuche">Third tab</a></li>
     <li><a id="link4" clicktoshow="tab4" clicktohide="tab1,tab2,tab3" onClick="tab4_active();" title="Download">Fourth tab</a></li>
</ol>
<script>
     function tab1_active() {
          document.getElementById('link1').addClassName('active');
          document.getElementById('link2').removeClassName('active');
          document.getElementById('link3').removeClassName('active');
          document.getElementById('link4').removeClassName('active');
     }
     function tab2_active() {
          document.getElementById('link2').addClassName('active');
          document.getElementById('link1').removeClassName('active');
          document.getElementById('link3').removeClassName('active');
          document.getElementById('link4').removeClassName('active');
     }
     function tab3_active() {
          document.getElementById('link3').addClassName('active');
          document.getElementById('link1').removeClassName('active');
          document.getElementById('link2').removeClassName('active');
          document.getElementById('link4').removeClassName('active');
     }
     function tab4_active() {
          document.getElementById('link4').addClassName('active');
          document.getElementById('link1').removeClassName('active');
          document.getElementById('link2').removeClassName('active');
          document.getElementById('link3').removeClassName('active');
     }
</script>
<!-- Start #tab1 -->
<div id="tab1" style"display:none&quote;>
     <p>Here goes the content of the First Tab</p>
</div>
<!-- End #tab1 -->
<!-- Start #tab2 -->
<div id="tab2" style="display:none">
     <p>Here goes the content of the Second Tab</p>
</div>
<!-- End #tab2 -->
<!-- Start #tab3 -->
<div id="tab3" style="display:none">
     <p>Here goes the content of the Third Tab</p>
</div>
<!-- End #tab3 -->
<!-- Start #tab4 -->
<div id="tab4" style="display:none">
     <p>Here goes the content of the Fourth Tab</p>
</div>
<!-- End #tab4 -->

Demo download

I prepared a .zip file containing the fbml, the css and the image I used. You can use it freely for commercial and non commercial purposes. Just remember to upload the css and the image to a server of your own, and update the paths in the fbml and the css.

Download the demo

Is there a better alternative?

I do hope so! In fact, I've been surfing the web in search of more elegant solutions, but I didn't find any (apart from some commercial application).

There's an interesting thread on Facebook's developers forum, titled “Good FBJS tabs code example?”, but the code you find there only seems to work properly with two tabs.

A good option could be the one from Webdigi but I didn't have time to check it. Anyway I strongly recommend you “7 script per la tua Applicazione Facebook” on Bigthink.it (in Italian).

A new hope

Facebook is going to allow people to use iframes inside fan pages, giving developers more freedom about the code.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay

About marcello.vicidomini

No description. Please complete your profile.
Comments (0) Trackbacks (1)

Leave a comment