Sunday, August 26, 2012

jQuery/jQueryUI Help: Tabs | Get Currently Selected Tab

Update! Please note: In newer versions of jQueryUI (1.9+), `ui-tabs-selected` has been replaced with `ui-tabs-active`.
So I've noticed a major need for further explanation on how to work with jQueryUI Tabs. It is probably one of the most popular features I've seen used and "mis-used" due simply to lack of understanding of some very simple code.
The question is often proposed, "How do I get the currently selected tab?" or "tab index?". The documentation actually answers the later, but people still seemed to be confused. I've noticed many coders also have trouble understanding what to do with the Tab Index once they have it.
Well let's get started shall we!?
First of all, the documentation on the sight states:
[jQueryUI Reference]
...retrieve the index of the currently selected tab
var $tabs = $('#example').tabs();
var selected = $tabs.tabs('option', 'selected'); // => 0

That seems all well and dandy, but what if you need to do more? What if you need the "panel" that is open in order to manipulate data within? What if you need the current tab itself in order to make some text change or promote a specific "pop-up"?
Their next suggestion is found a little hidden in the documentation via the "tabs events". Within events like "tabsshow" you can retrieve required info via the bonded return parameter "ui".
For examnple:
$("#tabsElementID").tabs({
    show: function(e, 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
    }
});
But what if you need to access these items outside the tabs events?!?

Whatever your scenario may be, I have the answer!Keep Reading



I'll try to break things down and keep this as easy to follow as possible, so please read all the way through.
First of all, getting the currently selected tab and the currently selected panel is easy. However, let's break this up.
By "tab", I am referring to the ACTUAL TAB the user clicks on to change the screen.
By "panel", I am referring to the PANEL where your ACTUAL CONTENT exist. In other words, the change the user sees with his/her eyes.
Now, let's get those current items and see how easy we can make this:
//  To retrieve the current TAB and assign it to a variable ...
var curTab = $('.ui-tabs-selected'); // in NEWER jQueryUI, this is now ui-tabs-active
//  To retrieve the current PANEL and assign it to a variable ...
var curTabPanel = $('.ui-tabs-panel:not(.ui-tabs-hide)');
Now of course, if you have multiple tabs sections, you may need to inquire the encapsulating div element ID for the specific tabs group you want the current tab from. Such as:
//  if you have 2 tabs areas created as follows ...
$('#example-1').tabs();
$('#example-2').tabs();

//  and you want the current tab or panel for the tabs of example-2
//  then you would simpley include the element ID to the code I previously mentioned ...
var curTab = $('#example-2 .ui-tabs-selected');//  To retrieve the current TAB and assign it to a variable ...
var curTabPanel = $('#example-2 .ui-tabs-panel:not(.ui-tabs-hide)');//  To retrieve the current PANEL and assign it to a variable ...

YAY! I have what I need! Now what can I get from it?


In short, "Anyting yu want..."
That's right! You now have the power to go forth and do good work! I'll of course give you some examples. Remember earlier, how I showed you on the jQueryUI site, they mentioned how to get the index. See below on how to do that with this new piece of code ... and much ... MUCH MORE!
//  First, lets grab the panel for example-1
var curTabEx01 = $('#example-1 .ui-tabs-panel:not(.ui-tabs-hide)');

//  Now, to get the index just simply ...
curTabEx01.index();
//  To get the ID property of the current panel
curTabEx01.prop("id");
//  To get an attribute for the currently selected panel
curTabEx01.attr("class");
//  to get to something inside the panel and hide it
curTabEx01.find(".some-class-to-hide").hide();
//  and so forth and so on, I really hope you get the point by now
One Last thing to elaborate on. If you create your tabs exactly as seen in the jQueryUI examples, then your panel index will be on a 1-index value. This is not too much of a problem unless you expect 0-index value as with most things in coding. Just subtract one like: curTabEx01.index() - 1;
This is because the "ul" containing your "tabs" is technically index number 0.
HOWEVER!
If you want to have the panels be on a zero index value, and you don't want to subtract one every time you get the index, then you can place you panels inside their own encapsulating div element and it will not hurt anything. Like so:
<div class="demo">
    <div id="tabs">
        <ul>
            <li><href="#tabs-1">Nunc tincidunt</a></li>
            <li><href="#tabs-2">Proin dolor</a></li>
            <li><href="#tabs-3">Aenean lacinia</a></li>
        </ul>
        <div class="panels-area">
            <div id="tabs-1">
                <p>Proin elit ...</p>
            </div>
            <div id="tabs-2">
                <p>Morbi tincidunt, ...</p>
            </div>
            <div id="tabs-3">
                <p>Mauris eleifend ...</p>
            </div>
        </div>
    </div>
</div>

Now you have the power, and hopefully the know-how to use it. G'luck coders and enjoy!

jsFiddle with example of this code in action

4 comments:

  1. Nice man. This is useful on my own blog.

    ReplyDelete
  2. For some reason this didn't work for me
    var curTabPanel = $('.ui-tabs-panel:not(.ui-tabs-hide)');
    I saw in Firebug that there didn't seem to be any class .ui-tabs-hide added to the hidden tabs.
    However this worked:
    var curTabPanel = $('.ui-tabs-panel:visible');

    (I'm using the current version of jquery at the point of this writing)

    ReplyDelete
  3. This does not seem to work for me, and I am not sure why. Here is what I have :
    var $tabs = $('#tabs').tabs();
    alert($tabs.tabs('option', 'active'));

    the alert returns "false" always...

    ideas?

    Thanks!

    ReplyDelete