Adding and Removing Tabs with jQuery and jQuery UI
Using the tabs UI functionality in jQuery can be amazingly easy, assuming you just want to convert some basic content into a tab layout. However, once you start trying to dynamically add/remove tabs (as you will often run into on advanced layouts) it gets a little hairy. As with everything injQuery UI in my experience so far, you can do what you want its just neither straightforward or well documented. This tutorial will show the ways you can add/remove or show/hidejQuery tabs and some of the gotchas and drawbacks associated with those methods.
Adding and Removing Tabs
The tab functionality in jQuery UI includes methods for adding and removing tabs. To add a tab you simply do $("#mytabs").tabs("add","tabContent.htm","New Tab") for a tab that is populated via Ajax or $("#mytabs").tabs("add","#tabContent","NewTab") for a tab that is populated by the contents of a Div on that page, for instance. Killing a tab is also straightforward, $("#mytabs").tabs("remove",1). Nonetheless, there are a number of "gotchas" when using this.
Firstly, there doesn't appear to be any built in method to get what tabs already exist within any tabs list or which tab is selected(other than searching the DOM). In addition, if you add a tab in this manner, populate it with the contents of a local div and then remove it, that content cannot be re-added (I assume because that portion of the DOM is blown away when it is removed). If you need to remove and add the content again, you will need to load the content via the Ajax method. This would be fine, except that if you had populated content or selected an option, for example, this will not be retained when the content is reloaded. For example, in sample code (see below), I have a select box which, when reloaded, will obviously always reset back to the default option. This isn't always an acceptable solution.
Showing and Hiding Tabs
Unfortunately, there is also no built-in method for hiding/showing specific tabs via the tabs UI API. In addition, if you simply hide the div content of the tab, it will not hide the tab. In fact, to hide a tab, you need to hide the list item associated with that tab rather than the Div content. In this way the tab always exists, but is simply displayed conditionally and any changes to the content of that tab, like our select box, will be retained.
While you can parse through the DOM using jQuery and pick a tab to show or hide, in order to show/hide specific tabs you will likely need to assign each list item a unique ID, as in the example code below. Once your tab list item has a unique ID, you can simply hide it by using $("#tabs-1-tab").css("display","none") or $("#tabs-1-tab").css("display","list-item") to show it again. One trick in this case is that if you hide the currently selected tab, you will need to refresh the displayed content by deliberately selecting another tab or the content of the closed tab will still show. You can easily do this using a built in method of tabs, $("#mytabs").tabs("select",0), which would select the first tab, for example.
Helper Methods
If you look at the example code below, you'll see some helper methods that I am using to handle hiding/showing tabs. For example I have a method I use often when I want to change which tabs are displayed that uses one line to hide all the tabs, after which I selectively display the tabs I want - $("#tablist").children().css("display","none"). Also, you can make a single method to hide/show tabs by passing in the tab ID string as in theopenTab () method below. This also takes care of selectively hiding all the other tabs and ensuring that the newly opened tab is selected. These aren't the most complex examples of helper methods for hiding/showing tabs but it should give you some guidance on where to go from here.
Going Forward
Personally, I hope that the jQuery UI tabs implementation adds some built-in methods for handling things like hiding/showing tabs, getting the selected tab, and getting an array of tabs that exist (rather than simply parsing the DOM that is). Still, hopefully this post provides some level of documentation on how to achieve some of these results via alternative methods as I wasn't able to find much out there yet.
Full code for the tabs sample page:
<html>
<head>
<title>jQuery UI Tabs Demo</title>
<link type="text/css" href="css/smoothness/jquery-ui-1.7.1.custom.css" rel="stylesheet" />
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="jquery-ui-1.7.1.custom.min.js"></script>
<script type="text/javascript">
function init() {
$("#mytabs").tabs();
// wipe all the tabs so we can programatically show the ones we want
removeAllTabs();
// if {condition}, then show relevant tab. this is just for example purposes
if (true) {
$("#tabs-1-tab").css("display","list-item");
}
// now show the tabs area
$("#mytabs").css("display","block");
}
function openTab(tabNum,closeOthers) {
if (closeOthers != false) {
removeAllTabs();
}
$("#tabs-"+tabNum+"-tab").css("display","list-item");
$("#mytabs").tabs("select",tabNum-1);
}
function removeAllTabs() {
$("#tablist").children().css("display","none");
}
function createTab4() {
// this will add a tab via the standard method
$("#mytabs").tabs("add","#tabs-4","Fourth Tab");
$("#tabs-4").css("display","block");
}
function removeTab4() {
// this will add a tab via the standard method. part of the problem here is I don't know the index...just assuming its on the end
$("#mytabs").tabs("remove",$("#mytabs").tabs("length")-1);
// reselect the 2nd tab or it will show tab 3
$("#mytabs").tabs("select",1);
}
function createTab5() {
// this will add a tab via the standard method
$("#mytabs").tabs("add","tabs5.htm","Fifth Tab");
}
function removeTab5() {
// this will add a tab via the standard method. part of the problem here is I don't know the index...just assuming its on the end
$("#mytabs").tabs("remove",$("#mytabs").tabs("length")-1);
// reselect the 2nd tab or it will show tab 3
$("#mytabs").tabs("select",1);
}
$(document).ready(init);
</script>
</head>
<body>
<div id="mytabs" style="display:none;">
<ul id="tablist">
<li id="tabs-1-tab"><a href="#tabs-1">First Tab</a></li>
<li id="tabs-2-tab"><a href="#tabs-2">Second Tab</a></li>
<li id="tabs-3-tab"><a href="#tabs-3">Third Tab</a></li>
</ul>
<div id="tabs-1">
<p>This is my first tab. It should show by default when the page is ready.</p>
<p>If you select option 2 in this select box, it will still be selected when reopened</p>
<p><select name="foo">
<option>Option 1</option>
<option>Option 2</option>
</select></p>
<p>Click the button to open tab 2 and close this tab.</p>
<input type="button" name="openTab2" value="Open Tab 2" onclick="openTab(2)" />
</div>
<div id="tabs-2">
<p>This is my second tab. It shows when you click the button in tab 1. Tab 1 and 2 should never appear together.</p>
<p>Click the button to open tab 3. This tab will remain open.</p>
<input type="button" name="openTab3" value="Open Tab 3" onclick="openTab(3,false)" />
<p>Click this button to "create" tab 4 using the create method on a local div.</p>
<input type="button" name="createTab4" value="Create Tab 4" onclick="createTab4()" />
<p>Click this button to "create" tab 5 using the create method using ajax for content.</p>
<input type="button" name="createTab5" value="Create Tab 5" onclick="createTab5()" />
</div>
<div id="tabs-3">
<p>This is my third tab tab. It shows when you click the button in tab 2. It can show along with tab 2.</p>
<p>Click the button to open tab 1 again. Any other open tabs will close.</p>
<input type="button" name="openTab1" value="Open Tab 1" onclick="openTab(1)" />
</div>
</div>
<div id="tabs-4" style="display:none;">
<p>This tab is created using the create method but when I remove you won't be able to add it again with this content.</p>
<p>Click the button to kill this tab.</p>
<input type="button" name="killTab4" value="Kill This Tab" onclick="removeTab4()" />
</div>
</body>
</html>
Code for Tab5.htm:
<div id="tabs-5">
<p>This is my fifth tab. It should show by default when the page is ready.</p>
<p>If you select option 2 in this select box, it will reset when the tab is reloaded</p>
<p><select name="foo">
<option>Option 1</option>
<option>Option 2</option>
</select></p>
<p>Click the button to kill this tab.</p>
<input type="button" name="killTab5" value="Kill This Tab" onclick="removeTab5()" />
</div>
I think you are addressing something I have struggled to find docs for on the web. A really useful post! However, you've provided no css for your example so I can't test it. Could you not include the css in the header or set up a demo? Would be really helpful.
Thanks!
css/smoothness/jquery-ui-1.7.1.custom.css
jquery-1.3.2.min.js
While trying to run this example by simply copy and past, my program was not running. What may be the problem can u please suggest?
