Recently, someone asked a very good question on the Grails mailing lists about GrailsUI. How can someone add a button within each tab in a tabView that switches to the next tab? Well, there is nothing within the GrailsUI API that allows such custom behavior, so it’s not like you can just add addButtonToEachTabThatNavigatesToTheNextButton=”true” to the tabView attributes ;).
But there definitely is a way to access the YUI TabView component that the GrailsUI tabView tag creates. And if you can access this component and you refer to the YUI API for TabView, it turns out to be pretty easy to hook up this functionality.
For this example, lets create a simple tabbed pane with tabView first, then we’ll put buttons in each tab that will activate the next tab within the pane.
<gui:tabView id="myTabView">
<gui:tab label="tab 0" active="true">
<h2>TAB at index 0</h2>
</gui:tab>
<gui:tab label="tab 1">
<h2>TAB at index 1</h2>
</gui:tab>
<gui:tab label="tab 2">
<h2>TAB at index 2</h2>
</gui:tab>
<gui:tab label="tab 3">
<h2>TAB at index 3</h2>
</gui:tab>
</gui:tabView>This produces a plain old tab view:

We want to put a button within each tab that will switch to the next tab, so let’s add the buttons with unique ids:
<gui:tabView id="myTabView">
<gui:tab label="tab 0" active="true">
<h2>TAB at index 0</h2>
<button id='button0' value='1' type='button'>Next</button>
</gui:tab>
<gui:tab label="tab 1">
<h2>TAB at index 1</h2>
<button id='button1' value='2' type='button'>Next</button>
</gui:tab>
<gui:tab label="tab 2">
<h2>TAB at index 2</h2>
<button id='button2' value='3' type='button'>Next</button>
</gui:tab>
<gui:tab label="tab 3">
<h2>TAB at index 3</h2>
<button id='button3' value='0' type='button'>Next</button>
</gui:tab>
</gui:tabView>Now each tab has a button that we want to activate the next tab, but it does nothing. Note the value of each button is the index of the tab it should activate.

Nothing special yet… but now we get to the component accessibility portion of the tutorial.
What we need to do now is add event listeners to the buttons we created that will select specific tabs on the YUI TabView object that GrailsUI created for us. So after our
YAHOO.util.Event.onDOMReady(function(){
var buttons = ['button0','button1','button2','button3'];
for (i in buttons) {
YAHOO.util.Event.on(buttons[i], ‘click’, function(e) {
GRAILSUI.myTabView.set(’activeIndex’, e.target.value);
});
};
});This little script is looping through the button ids and attaching an even listener to each. On click, the code within this listener will be evaluated. The important line is GRAILSUI.myTabView.set(’activeIndex’, e.target.value);, because this is where we access the YUI TabView directly. When this line is executed within the listener, the tabView active index it set by the value of the button.
That’s it. Pretty simple, really. Yes, you do have to get you hands a little dirty with some JavaScript, but if you are a UI developer nowadays, JavaScript is a pretty sharp tool in your toolbox. So get used to it ;).

4 Comments
I had to jump through some hoops to get this to work on IE (go figure, right?). Instead of e.target I had to use e.srcElement based on the work found here http://www.quirksmode.org/js/events_properties.html
@Chet I’m sorry to hear that. I’m trying to make things browser compatible, but it is hard with the current IE environment. If you have major issues, please log a JIRA for it. Thanks for using Grails-UI!
I want to ask you about a problem that faced me when using dynamic tabs which rely on a controller to render a template back to it ,
the problem is that these template contains G-UI modal dialogs , when making the loader action of the tab render the template , the modal dialogs did not work and the contents of it appeared as a HTML inside the tab without the dialog, i included the GUI-resources inside the template but still do not work , even if i used tab inside the dialog, the modal dialog works well but i donot want to render the contents of all tabs each time
I think what you’ll have to do if you handle your own dynamic tab loading that contains JavaScript to evaluate is call the GRAILSUI.util.replaceWithServerResponse() function with the div you want replaced and the server response. You can see an example here.