Tabs are generally used to break content into multiple sections that can be swapped to save space, much like an accordion.
By default a tab widget will swap between tabbed sections onClick, but the events can be changed to onHover through an option. Tab content can be loaded via Ajax by setting an href on a tab.
A series of events fire when interacting with a tabs interface:
Event binding example:
$('#example').bind('tabsselect', function(event, ui) { // Objects available in the function context: ui.tab // anchor element of the selected (clicked) tab ui.panel // element, that contains the selected/clicked tab contents ui.index // zero-based index of the selected (clicked) tab });
Note that if a handler for the tabsselect event returns false, the clicked tab will not become selected (useful for example if switching to the next tab requires a form validation).
Tabs supports loading tab content via Ajax in an unobtrusive manner.
The HTML you need is slightly different from the one that is used for static tabs: A list of links pointing to existing resources (from where the content gets loaded) and no additional containers at all (unobtrusive!). The containers' markup is going to be created on the fly:
<div id="example"> <ul> <li><a href="ahah_1.html"><span>Content 1</span></a></li> <li><a href="ahah_2.html"><span>Content 2</span></a></li> <li><a href="ahah_3.html"><span>Content 3</span></a></li> </ul> </div>
Obviously this degrades gracefully - the links, e.g. the content, will still be accessible with JavaScript disabled.
Note that if you wish to reuse an existing container, you could do so by matching a title attribute and the container's id:
<li><a href="hello/world.html" title="Todo Overview"> ... </a></li>
and a container like:
<div id="Todo_Overview"> ... </div>
(Note how white space is replaced with an underscore)
This is useful if you want a human readable hash in the URL instead of a cryptic generated one.
Tabs 2 already supported this functionality, although the history plugin needs a rewrite first (it doesn't support Safari 3 and is in general a little inflexible) before it can be build back into the tabs. It is planned and Klaus is working on it whenever he finds the time. Actual bugs in the UI Tabs plugin itself always have higher priority though.
var $tabs = $('#example').tabs(); var selected = $tabs.tabs('option', 'selected'); // => 0
"Hijax" links after tab content has been loaded:
$('#example').tabs({ load: function(event, ui) { $('a', ui.panel).click(function() { $(ui.panel).load(this.href); return false; }); } });
var $tabs = $('#example').tabs(); // first tab selected $('#my-text-link').click(function() { // bind click event to link $tabs.tabs('select', 2); // switch to third tab return false; });
Returning false in the tabs select handler prevents the clicked tab from becoming selected.
$('#example').tabs({ select: function(event, ui) { var isValid = ... // form validation returning true or false return isValid; } });
var $tabs = $('#example').tabs({ add: function(event, ui) { $tabs.tabs('select', '#' + ui.panel.id); } });
Note that opening a tab in a new window is unexpected, e.g. inconsistent behaviour exposing a usablity problem (http://www.useit.com/alertbox/tabs.html).
$('#example').tabs({ select: function(event, ui) { location.href = $.data(ui.tab, 'load.tabs'); return false; } });
Add the necessary classes to hide an inactive tab panel to the HTML right away - note that this will not degrade gracefully with JavaScript being disabled:
<div id="example" class="ui-tabs"> ... <div id="a-tab-panel" class="ui-tabs-hide"> </div> ... </div>
Any component that requires some dimensional computation for its initialization won't work in a hidden tab, because the tab panel itself is hidden via display: none
so that any elements inside won't report their actual width and height (0 in most browsers).
There's an easy workaround. Use the off-left technique for hiding inactive tab panels. E.g. in your style sheet replace the rule for the class selector ".ui-tabs .ui-tabs-hide" with
.ui-tabs .ui-tabs-hide { position: absolute; left: -10000px; }
For Google maps you can also resize the map once the tab is displayed like this:
$('#example').bind('tabsshow', function(event, ui) { if (ui.panel.id == "map-tab") { resizeMap(); } });resizeMap() will call Google Maps' checkResize() on the particular map.
.ui-tabs .ui-tabs-hide { display: none; }
$("#tabs").tabs();
<!DOCTYPE html> <html> <head> <link type="text/css" href="http://jqueryui.com/latest/themes/base/ui.all.css" rel="stylesheet" /> <script type="text/javascript" src="http://jqueryui.com/latest/jquery-1.3.2.js"></script> <script type="text/javascript" src="http://jqueryui.com/latest/ui/ui.core.js"></script> <script type="text/javascript" src="http://jqueryui.com/latest/ui/ui.tabs.js"></script> <script type="text/javascript"> $(document).ready(function(){ $("#tabs").tabs(); }); </script> </head> <body style="font-size:62.5%;"> <div id="tabs"> <ul> <li><a href="#fragment-1"><span>One</span></a></li> <li><a href="#fragment-2"><span>Two</span></a></li> <li><a href="#fragment-3"><span>Three</span></a></li> </ul> <div id="fragment-1"> <p>First tab is active by default:</p> <pre><code>$('#example').tabs();</code></pre> </div> <div id="fragment-2"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </div> <div id="fragment-3"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </div> </div> </body> </html>
This event is triggered when clicking a tab.
select
event as an init option.
$('.selector').tabs({
select: function(event, ui) { ... }
});
select
event by type: tabsselect
.
$('.selector').bind('tabsselect', function(event, ui) {
...
});
This event is triggered after the content of a remote tab has been loaded.
load
event as an init option.
$('.selector').tabs({
load: function(event, ui) { ... }
});
load
event by type: tabsload
.
$('.selector').bind('tabsload', function(event, ui) {
...
});
This event is triggered when a tab is shown.
show
event as an init option.
$('.selector').tabs({
show: function(event, ui) { ... }
});
show
event by type: tabsshow
.
$('.selector').bind('tabsshow', function(event, ui) {
...
});
This event is triggered when a tab is added.
add
event as an init option.
$('.selector').tabs({
add: function(event, ui) { ... }
});
add
event by type: tabsadd
.
$('.selector').bind('tabsadd', function(event, ui) {
...
});
This event is triggered when a tab is removed.
remove
event as an init option.
$('.selector').tabs({
remove: function(event, ui) { ... }
});
remove
event by type: tabsremove
.
$('.selector').bind('tabsremove', function(event, ui) {
...
});
This event is triggered when a tab is enabled.
enable
event as an init option.
$('.selector').tabs({
enable: function(event, ui) { ... }
});
enable
event by type: tabsenable
.
$('.selector').bind('tabsenable', function(event, ui) {
...
});
This event is triggered when a tab is disabled.
disable
event as an init option.
$('.selector').tabs({
disable: function(event, ui) { ... }
});
disable
event by type: tabsdisable
.
$('.selector').bind('tabsdisable', function(event, ui) {
...
});
Remove the tabs functionality completely. This will return the element back to its pre-init state.
Disable the tabs.
Enable the tabs.
Get or set any tabs option. If no value is specified, will act as a getter.
Add a new tab. The second argument is either a URL consisting of a fragment identifier only to create an in-page tab or a full url (relative or absolute, no cross-domain support) to turn the new tab into an Ajax (remote) tab. The third is the zero-based position where to insert the new tab. Optional, by default a new tab is appended at the end.
Remove a tab. The second argument is the zero-based index of the tab to be removed.
Enable a disabled tab. To enable more than one tab at once reset the disabled property like: $('#example').data('disabled.tabs', []);
. The second argument is the zero-based index of the tab to be enabled.
Disable a tab. The selected tab cannot be disabled. To disable more than one tab at once use: $('#example').data('disabled.tabs', [1, 2, 3]);
The second argument is the zero-based index of the tab to be disabled.
Select a tab, as if it were clicked. The second argument is the zero-based index of the tab to be selected or the id selector of the panel the tab is associated with (the tab's href fragment identifier, e.g. hash, points to the panel's id).
Reload the content of an Ajax tab programmatically. This method always loads the tab content from the remote location, even if cache is set to true. The second argument is the zero-based index of the tab to be reloaded.
Change the url from which an Ajax (remote) tab will be loaded. The specified URL will be used for subsequent loads. Note that you can not only change the URL for an existing remote tab with this method, but also turn an in-page tab into a remote tab. The second argument is the zero-based index of the tab of which its URL is to be updated. The third is a URL the content of the tab is loaded from.
Retrieve the number of tabs of the first matched tab pane.
Terminate all running tab ajax requests and animations.
Set up an automatic rotation through tabs of a tab pane. The second argument is an amount of time in milliseconds until the next tab in the cycle gets activated. Use 0 or null to stop the rotation. The third controls whether or not to continue the rotation after a tab has been selected by a user. Default: false.
The jQuery UI Tabs plugin uses the jQuery UI CSS Framework to style its look and feel, including colors and background textures. We recommend using the ThemeRoller tool to create and download custom themes that are easy to build and maintain.
If a deeper level of customization is needed, there are widget-specific classes referenced within the ui.tabs.css stylesheet that can be modified. These classes are highlighed in bold below.
Note: This is a sample of markup generated by the tabs plugin, not markup you should use to create a tabs. The only markup needed for that is
<div id="tabs">
<ul>
<li><a href="#tabs-1">Nunc tincidunt</a></li>
<li><a href="#tabs-2">Proin dolor</a></li>
<li><a href="#tabs-3">Aenean lacinia</a></li>
</ul>
<div id="tabs-1">
<p>Tab 1 content</p>
</div>
<div id="tabs-2">
<p>Tab 2 content</p>
</div>
<div id="tabs-3">
<p>Tab 3 content</p>
</div>
</div>.