Sunday, July 12, 2009

jQuery Tabs - Get'em while they're hot!

So, you've mastered the art of j-quer-fu and now you're looking to take on its UI partner in crime - excellent! Tabs are a great place to start... They can help with real estate issues, reduce clutter, and create a better overall end user experience . Like all tools, however, tabs should not be used just because they're "cool" (even though they are). There are some general best practices that should be followed with their implementation. For a great primer on tabs, check out this article from Smashing Magazine:

To lean about jQuery tabs in general have a look here:

Tabs look easy enough to implement but getting things just right in Apex can be a bit tricky the first time. In this post I'm going to explain how to take a busy Apex page with 5 regions and clean it up a bit with tabs. The page contains the following region types:  1 report, 1 calendar, 2 charts, and 1 help.

Here are the before and after demo links:

  1. Before
  2. After

 

Still interested??? Then let's get started!

  1. Download jQuery UI and include it in your application or page. This is obviously a prerequisite. I posted about Installing jQuery a while back. The concept here is the same but a bit more involved as you need to include jQuery, jQuery UI, and the UI theme. If enough people ask, I'll update that old doc and include some more details ;)
  2. Create a new region template. Many region templates display the region title in them. When we use tabs this may be unwanted as the tab text should suffice. At the same time, however, we will need the region attributes. The following can be used to create a generic region template that gives us what we need; I named it "Basic Div". You can modify the template as needed.
    <div id="#REGION_STATIC_ID#" #REGION_ATTRIBUTES# class="basic_div">
    #BODY#
    </div>
  3. Prep the regions that you would like to be tabbed:
    1. Change the templates to the template you created in step 2.
    2. Make sure that all of your regions are in column 1.
    3. Give each region a unique ID via the Static ID attribute.
    4. Make sure they are sequential - regions that will not be tabbed should come before or after.
  4. Enclose regions you want to group together under one tab with two new regions. By "enclose", I simply mean that you'll put one region before the set of regions that should be tabbed and then one after as well. Most of the time you'll want a one to one ratio of tabs to regions. However, sometimes you'll want to put more than one region under a tab. To do this you need to make sure that the regions are sequential and enclosed with some HTML that will group them. In my example, I grouped two chart regions under one tab by putting this HTML in the source of an HTML region (no template) right before the first chart:
    <div id="charts_reg">

    And this in another HTML region (no template) right after the second:
    </div>

  5. Enclose the regions you want to turn into tabbed regions with two new regions. This step is similar to the last but here the code we are adding will enclose all of our regions to be tabbed. Both of these regions should be HTML regions with no template assigned to them. The first of the two regions includes the mark up that jQuery UI will use to create the tabs. If you have regions that are conditionally displayed, you'll want to make this a PL/SQL region and generate you're HTML dynamically:
    <div id="tabs_start_reg" style="display:none;">
       <ul>
          <li><a href="#employees_reg">Employees</a></li>
          <li><a href="#anniversaries_reg">Anniversaries</a></li>
          <li><a href="#charts_reg">Charts</a></li>
          <li><a href="#help_reg">Help</a></li>
       </ul>

    And the second:
    </div>
  6. Add the following JavaScript to the HTML header of the page to bring everything to life:
    <script type="text/javascript">
    //<![CDATA[
       
       $(function(){  
          $tabs = $("#tabs_start_reg");
          $tabs.tabs();
          $tabs.parents('td').eq(0).removeAttr('width');
          $tabs.show();   
       });
    
    //]]>
    </script>