Readers familiar with writing gadgets for iGoogle are probably familiar with the built-in tabs feature, but may not know that this same feature, with some new syntax, is included within OpenSocial. By including the tabs feature in your code, and making some small adjustments to the default code, your application can have tabs that behave just like they are part of the orkut UI. This little bit of polish will go a long way towards making your application look at home inside of orkut.
The first thing your gadget needs to do is to include the appropriate files. The tabs feature is built into gadgets, so adding it to your application is easy. Include <Require feature="tabs" /> in your <ModulePrefs> section, and all of the appropriate JavaScript will be loaded with your application.
Now, create a global variable tabs to hold the tab object, and an initialization function that can be used as a jumping off point once the DOM has been loaded. Inside the function, call the gadgets.TabSet constructor to initialize the tabs.
var tabs = null;
gadgets.util.registerOnLoadHandler(onLoadHandler);
function onLoadHandler() {
tabs = new gadgets.TabSet(__MODULE_ID__, null, document.getElementById('tabs_div'));
}
The initialization code passes in a number of parameters. The first two, __MODULE_ID__ and null are simply placeholder values that must be specified in order to specify a third parameter. The third parameter instructs the tab feature to insert tabs within the DOM object given, in this case, a tag with id of tabs_div. You should add such a tag to your XML file.
<div id="tabs_div"></div>
Lastly create new tab objects inside of the onLoadHandler function for each of the tabs you'd like to see on the page. As an example, here are two tabs, one called "friends" and another called "messages."
var params = {
callback: changeSelectedTab
};
params.contentContainer = document.getElementById('friends');
tabs.addTab('Friends', params);
params.contentContainer = document.getElementById('messages');
tabs.addTab('Messages', params);
The addTab function takes two arguments. The first argument is the name of the tab. The second argument is a list of optional parameters. The first of the two optional parameters is the callback function that's executed whenever a tab is clicked, to make visual modifications to the tabs. The second parameter is the DOM element that contains each tab's content. Because both tabs have their content held within distinct div tags, the DOM element is changed before the addition of each tab.
You should make sure to add <div> tags in your XML for each of these tabs. The HTML for the above tabs would look like this:
<div id='friends'>Hi!</div> <div id='messages'>Hey!</div>
When the "friends" tabs is selected, the message "Hi!" appears, because that is the content of the <div id='friends'> DOM element. Likewise, when "messages" is clicked, the word "Hey!" appears.
Now that you've constructed your tabs, you'll need to start making some changes to their display to match orkut's look and feel. First, make the tabs align to the left of the page.
tabs.alignTabs('left', 2);
Next, you'll need to iterate through each of the created tab elements to properly assign styles to the new tabs (to create the rounded look of orkut tabs). The tabs_div_header element is created automatically when you create new tabs, so you do not need to add this to your code. The CSS classes that the code is using to make visual modifications are also part of the generated tabs.
var tabHeaders = document.getElementById('tabs_div_header').rows[0].cells;
var value = null;
var html = null;
for (var i in tabHeaders) {
if (tabHeaders[i].className && tabHeaders[i].className.match(/tablib_selected/)) {
value = tabHeaders[i].innerHTML;
html = "<span class='tablib_extension_left_selected'></span> " + value;
tabHeaders[i].innerHTML = html;
}
if (tabHeaders[i].className && tabHeaders[i].className.match(/tablib_unselected/)) {
value = tabHeaders[i].innerHTML;
html = "<span class='tablib_extension_left_unselected'></span> " + value;
tabHeaders[i].innerHTML = html;
}
}
Now, include the code of the callback function changeSelectedTab. This function is called when you change tabs.
function changeSelectedTab() {
if (document.getElementById('tabs_div_header')) {
var tabHeaders = document.getElementById('tabs_div_header').rows[0].cells;
for (var i in tabHeaders) {
if (tabHeaders[i].className && tabHeaders[i].className.match(/tablib_selected/)) {
if (tabHeaders[i].childNodes[0].className) {
tabHeaders[i].childNodes[0].className = 'tablib_extension_left_selected';
}
}
if (tabHeaders[i].className !== undefined && tabHeaders[i].className.match(/tablib_unselected/)) {
if (tabHeaders[i].childNodes[0].className) {
tabHeaders[i].childNodes[0].className = 'tablib_extension_left_unselected';
}
}
}
}
}
This function behaves similarly to the code executed just after your gadget creates tabs. When a tab change occurs, it iterates through each of the existing tabs and swaps the styles of the previously selected and unselected tabs. The tabs feature itself handles part of this swap, but a second function call is required to handle the rounded edges.
The only remaining change is to include appropriate CSS styles and images to skin the tabs. All of these styles are defined in your application when you include tabs. The following CSS just overwrites the default settings to make the tabs look like orkut's tabs.
These can be copied and pasted directly into your existing stylesheet or into your gadget (when properly wrapped as CSS). Alternatively, you can link directly to the stylesheet.
.tablib_extension_left_selected, .tablib_extension_left_unselected {
height: 23px;
width: 6px;
float: left;
}
.tablib_extension_left_selected {
background-image: url(http://opensocial-resources.googlecode.com/svn/samples/orkut_ui/img/tabsel_l.gif);
}
.tablib_extension_left_unselected {
background-image: url(http://opensocial-resources.googlecode.com/svn/samples/orkut_ui/img/tabnotsel_l.gif);
}
.tablib_selected, .tablib_unselected {
font-size: 12px;
font-height: 23px;
text-transform: lowercase;
height: 23px;
line-height: 23px;
font-family: Verdana,Arial,sans-serif;
font-weight: 700;
margin: 0px;
padding: 0px;
padding-right: 6px;
width: auto;
border: 0px;
border-bottom: 1px solid #86A1C4;
}
.tablib_selected {
background: url(http://opensocial-resources.googlecode.com/svn/samples/orkut_ui/img/tabsel_r.gif) no-repeat center right;
color: #FFFFFF;
}
.tablib_unselected {
background: url(http://opensocial-resources.googlecode.com/svn/samples/orkut_ui/img/tabnotsel_r.gif) no-repeat center right;
color: #02679C;
}
td.tablib_unselected:hover {
color: #00344F;
text-decoration: underline;
}
.tablib_spacerTab, .tablib_emptyTab {
border-bottom: 1px solid #86A1C4;
}
.tablib_emptyTab {
width: 500px;
}
Note that the image references are pointing to the opensocial-resources code project, but you can copy the images locally (just make sure to change the URLs in the styles).
Also note that the .tablib_emptyTab style has a set width of 500px. This width should be adjusted based on the number of tabs you wish to display and the width of each tab. If you wish to change the number or names of visible tabs after the gadget is loaded, you should also adjust the width in this style.
Now, if you load up your gadget, you should see a set of fully-functional tabs that look and feel just like tabs in orkut's UI. You're now one step closer to having an application that looks right at home. To see this code in action, load the gadget XML within the orkut sandbox.