Wednesday, May 11, 2011

Using jQuery to switch Richfaces tabs

The requirement is to have a 'next' button at the bottom of each tab to forward to the next tab (wizard-like). The tabs are implemented with as vanilla rich:tab.  An additional requirement is to not have any onclick/oncomplete/etc attributes on the commandButton.  I'll post the solution first and then go into the explanation for those who had the same issues I did.

<script type="text/javascript">
jQuery(document).ready(function(){
jQuery('[id=form:next_button]').click(function() {
jQuery('[id=form:tab2_shifted]').click();
});
});
</script>


The first problem is the ids.   If you've used JSF, you know that JSF doesn't just use the id that you set on the tag.  It creates ids like 'form:tab2' instead of the 'tab2' that you set.  Not a huge deal at first.  The other thing you won't guess, is that the tab doesn't use your id either.  It adds a '_shifted' suffix resulting in 'form:tab2_shifted'.  So, if you only need to solve the first part, just do this:

<h:commandButton id="next_button" value="Next" action="next" onclick="document.getElementById('form:tab2_shifted').onclick();"/>


If you want to keep your javascripty stuff out of the tags, you need to be able to 'listen' to javascript events on tags.  The only way I know how to do that is with jQuery.  However, those colons in the ids cause a lot of people problems with jQuery.  Normally you look up a tag in jQuery like this:

$('#tab2_shifted').click();


That won't work in JSF, because the real id is 'form:tab2_shifted'.  So you'd think that this would work:

$('#form:tab2_shifted').click();


But it won't.  After LOTS of trial and error, I determined the correct way to do it:

$('[id=form:tab2_shifted]').click();


I can't remember what that's called, but you need to do it.

Adding the 'listener' (called an event handler in jQuery) was very easy to find.  This will call a popup every time the next button is clicked.

$('[id=form:next_button]').click(function() {
alert('hello');
});


Of course, if you just put this in the a <script> tag, it won't do anything.  For some reason you have to wrap it in $(document).ready.  I didn't get this forever.

$(document).ready(function(){
$('[id=form:next_button]').click(function() {
alert('hello');
});
});



The last part is pretty simple if you've got all this.  You just find the tab and click it.  We can do it with jQuery though to make it a bit prettier than document.getElementById.  See final result above.

Also, because I'm using the built in jQuery that comes with Richfaces, we use the jQuery variable instead of $ so that it doesn't conflict with other javascript libraries likey prototype that use $.

Here are some links that motivated me or helped me to write all this down:

No comments:

Post a Comment