Building on my first article in this series, we're now going to add bookmarkable URL's and back button support to our AJAX driven pages.

 

For our specific usecase, we want to render an AJAX region within the same page which includes an external page (via ui:include). Again, this is to keep the smooth native look and feel of sliding transitions.

 

Here, we mimic the same AJAX call which drives our main navigation (rich:panelMenu) with a4j:jsFunction.

 

<a4j:jsFunction name="handleHashChange" render="@form" oncomplete="slideTo('component-page')">
            <f:param name="demo" value="param1"/>
            <f:param name="sample" value="param2"/>
</a4j:jsFunction>

 

This says, when our JavaScript function "handleHashChange()" receives the 2 parameters (param1 and param2), we render the same form as in (part1) and call our transition.

 

Now that we have the JavaScript tie into the AJAX driven JSF page, we can use some quick code to give us bookmarkability and back button support.

 

function locationHashChanged() {
 if(location.hash === "#home"){
     slideTo('home-page')
 }else{
//let's see if we have an acceptable hash
     var hashArray = location.hash.split(':');
     var id;
     var sample;
     if(hashArray.length === 2){
//it's good so format it for our a4j:javascript function
         id = hashArray[0].replace('#','');
         sample = hashArray[1];
//call the a4j:javascript method
         handleHashChange(id,sample);
     }
 }
}

//every time the app changes the hash, call the method above 
window.onhashchange = locationHashChanged;

window.addEventListener('load', function(e) {
if(location.hash == ''){
//it's the initial load, so let's go home
     slideTo('home-page');
     location.hash='home';
}else{
//page has been bookmarked, so take em there 
    locationHashChanged();
}
}, false);
         

 

Now, every time the hash changes on an AJAX call it goes into our mobile page history. So from our original navigation handler rich:panelMenu, we would do the following "location.hash=" after the AJAX call completes:

 

<rich:panelMenuItem oncomplete="location.hash='#{d.id}:#{demoNavigator.currentSample.id}'" render="@form" ...

 

That's it!

The user can hit the back button, refresh, or bookmark the page and the correct markup will be rendered.

You will see this code in action in the upcoming RichFaces Mobile Showcase.