Tuesday, August 20, 2013

Easy way to enable, disable & hide jQuery UI tabs

While searching on how to hide a jQuery UI tab, I found that a lot of other people were also looking for ways to easily enable, disable, show and hide tabs using the jQuery UI tabs control. Unfortunately, the built-in way to do it is cumbersome at best (although I know it helps keep the code small). So, I created this small plug-in to make it easier. To use it, just copy the text to a file (I name jquery-ui-tab-utils.js) and reference it in your code.

Scroll to the bottom if you just want to see it work.

/**
 * jQuery-ui-tab-utils.js - Utilities to help with the jquery UI tab control
 * Date: 08/20/2013
 * @author Kyle White - kyle@kmwTech.com
 * @version 0.1
 * Built for and tested with jQuery UI 1.9.2
 * License: Use at your own risk and feel free to use this however you want.
 *
 * USAGE: 
 * $('MyTabSelector').disableTab(0);        // Disables the first tab
 * $('MyTabSelector').disableTab(1, true);  // Disables & hides the second tab
 * $('MyTabSelector').enableTab(1);         // Enables & shows the second tab
 * 
 * For the hide option to work, you need to define the following css
 *   li.ui-state-default.ui-state-hidden[role=tab]:not(.ui-tabs-active) {
 *     display: none;
 *   }
 */
(function ($) {
    $.fn.disableTab = function (tabIndex, hide) {
 
        // Get the array of disabled tabs, if any
        var disabledTabs = this.tabs("option""disabled");
 
        if ($.isArray(disabledTabs)) {
            var pos = $.inArray(tabIndex, disabledTabs);
 
            if (pos < 0) {
                disabledTabs.push(tabIndex);
            }
        }
        else {
            disabledTabs = [tabIndex];
        }
 
        this.tabs("option""disabled", disabledTabs);
 
        if (hide === true) {
            $(this).find('li:eq(' + tabIndex + ')').addClass('ui-state-hidden');
        }
 
        // Enable chaining
        return this;
    };
 
    $.fn.enableTab = function (tabIndex) {
 
        // Remove the ui-state-hidden class if it exists
        $(this).find('li:eq(' + tabIndex + ')').removeClass('ui-state-hidden');
 
        // Use the built-in enable function
        this.tabs("enable", tabIndex);
 
        // Enable chaining
        return this;
    }; })(jQuery);
If you have suggestions on making it better (or making it work for use-cases I haven't tested), please let me know. Here's an embedded JSFiddle to demonstrate how it works:

11 comments:

Khurram said...

This is one useful article, it helped me in disabling a tab. But i did not get the css enabling work. So I used an alternate via js. Which is: $("#tabs").tabs("enable", n);

Kyle White said...

@Khurram, Your method is the way it is supposed to work but didn't for me, which is why I came up with this. What version of jQuery UI are you using? Also, I don't think your method will work if you use the hidden feature because the hidden feature adds a non-standard class that the enable option doesn't know about. Glad to know that it was useful to you.

Unknown said...
This comment has been removed by the author.
Unknown said...

In the enableTab function, you may want to check your usage of splice. On an array with more than one element, passing in one argument to splice will truncate the array. Heres a fiddle: http://jsfiddle.net/NuPM9/

Kyle White said...

Based on the previous feedback, I've modified the enableTab function to be much simpler (almost trivial) because the built-in method DOES work (don't know why I thought it didn't). The new function just removes the class that might have been applied to hide the tab and re-enables it. Thanks for the feedback!

Anonymous said...

Thanks, It worked for me to disable the tab, but somehow I can't hide the disabled tab. (by calling $("#id_here").disableTab(1, true);

Kyle White said...

@Anonymous, most likely you just need to specify a css rule like this:

li.ui-state-default.ui-state-hidden[role=tab]:not(.ui-tabs-active) {
display: none;
}

Anonymous said...

I found that when I passed the tabindex from a variable, it was being interpreted as a string type. The Tabs widget apparently doesn't know what to do with an array of strings. I had to make sure I cast the passed tabIndex parameter as an integer for it to work. (the hiding would work but not the disabling).

Anonymous said...

How will i activate a tab from a link, without clinking on a tab itself?

Kyle White said...

To activate a tab, you can use $('#MyTabSelector').tabs({active :1 });

I've updated the Fiddle

Anonymous said...

Very useful article. It was the first one that came up and Google and actually worked on the first try! Thanks for posting!