Wednesday, January 20, 2010

An Implementation of the ExtJs TabPanel

So the first component I implemented was the ExtJs Tab Panel.




So how did I go about this?

I set my tabs up in HTML...
<div id="app_tabs">
    <div class="x-hide-display" id="current_month">
        Dashboard
    </div>
    <div class="x-hide-display" id="months">
        Months Tab
    </div>
    <div class="x-hide-display" id="categories">
        <uc1:categoriestabcontent id="CategoriesTabContent1" runat="server" />
    </div>
    <div class="x-hide-display" id="income">
        <uc1:incomestabcontent id="IncomesTabContent1" runat="server" />
    </div>
    <div class="x-hide-display" id="history">
        Tab Content
    </div>
</div>


Then I turned them into a TabPanel...
$(document).ready(function() {

 $.namespace("def", {

  InitialisePage: function() {

   var tabs = new Ext.TabPanel({
    renderTo: 'app_tabs',
    activeTab: 3,
    autoShow: true,
    plain: true,
    defaults: { autoHeight: true },
    items: [
     { contentEl: 'current_month', title: 'Current Month' },
     { contentEl: 'months', title: 'Months' },
     { contentEl: 'categories', title: 'Categories' },
     { contentEl: 'income', title: 'Income' },
     { contentEl: 'history', title: 'History' }
    ],
    listeners: {
     'tabchange': function(tabpanel, tab) {
      // empty all the tabs
      $("#IncomesContainer").children("#TabContent").empty();
      $("#CategoriesContainer").children("#TabContent").empty();
      // only render the appropriate tab content
      switch (tab.contentEl) {
       case 'income':
        $.fn.income.InitialiseControl();
        break;
       case 'categories':
        $.fn.category.InitialiseControl();
        break;
      }
     }
    }
   });
  },

  RenderTabContent: function() {
  }

 });

 $.fn.def.InitialisePage();
});
easy! Right? But was exactly is the javascript doing?

The first line you should recognise, the second one maybe not. Thanks go to Gilberto Saraiva for putting together jQuery.Namespace. Funnily enough this namespace behaves like a namespace.

I have one function that creates the tabs and defines what happens when the user interacts with them. The creation of the tabs can be broken into two sections, firstly the configuration of the tabs and secondly listeners for user interaction.

First up: Configuration...
To get an understanding of what each config option is doing visit the ExtJs API site. However what's important to note is that the tabs are configured to utilise the HTML divs (as shown above), I then define the items (or tabs) by indicating what HTML element each tab should use and then give it a title.

Lastly Interaction...
The ExtJs framework has this concept of listeners that listen for events being fired. The list of events available to hook into is quite extensive, but in this case we're only listening to one event and that is "tabchange". When the TabPanel initialises all the tabs are inactive, but by specifying the active tab in the config options you force this event to fire, so this allows us to control exactly what happens when ever a tab is activated.

So what's happening? This is where I utilise the jQuery framework. I empty the content of each tab then depending on the tab that is selected I call the appropriate InitialiseControl method. In this way I'm ensuring that the DOM does not contain any unwanted html.

You'll notice that I'm calling the empty() method for each tab. But it's just occurred to me that I should be able to do this in one line. Something like: $("#TabContent").empty();

Enjoy.

1 comment:

  1. Ok so I checked my suspicions and I was right (to a certain degree). I changed the internal div within each control to use have the class TabContent not an Id, as Ids are supposed to be unique throughout the html document.

    ReplyDelete