Alleviating client-side back-button issues with Ajax4JSF and RichFaces
November 8, 2007
Recently an article I wrote was published on the Seam conversation model and how issues with the back-button can be eliminated through a continuation approach. This aids developers in resolving back-button issues with respect to server-side state, but what about the client-side. Ajax development is a breeze with Seam especially when used in conjunction with Ajax4JSF and RichFaces but the use of Ajax can result in issues with caching of client-side state.
Caching is a common issue with Ajax implementations though many of the concerns of caching are alleviated by using the Ajax4JSF/RichFaces libraries (which I highly recommend). The specific problem I would like to address applies to use of Internet Explorer with Ajax (Firefox does not suffer from the problem). Internet Explorer caches pages when the entire page is refreshed. Ajax implementations allow the page to be altered without a refresh, only re-rendering the applicable section of the page. Thus, if a user submits a page or navigates elsewhere, using the back- or forward-button to return to the page will not display any portions of the page that had been updated by Ajax calls. Instead the page will be shown based on what was cached when the page was originally rendered. Firefox, on the other hand, maintains an up-to-date cache that displays the page as it was rendered after any AJAX updates in response to interaction with the user.
If you don’t believe me, try it yourself! Go to maps.google.com and view a map of your favorite location using Internet Explorer. Now type a new URL into your browser and navigate to it. Press the back button and *poof* you’re back at square one. The map of your favorite location is gone. Now perform the same steps using Firefox. Wow, Firefox still shows the map and you can still see your favorite location!
This is a rather annoying issue and of course could lead to issues with our conversation state (not to mention confusion of the users). Not to fear, the issue can be resolved through a fairly simple solution. Internet Explorer invokes the onload function every time a page is displayed (whether through the initial rendering, the back-, or the forward- button). The following code will resolve your issue using Ajax4JSF which ships with JBoss RichFaces:
<body bgcolor="#FFFFFF" text="#000000"
onload="reloadAjaxPanels()">
<h:form id="myAjaxForm">
<a:jsFunction name="reloadAjaxPanels"
reRender="panelToReload" />
...
<a:outputPanel id="panelToReload">
...
</a:outputPanel>
</h:form>
Now each time the user backs up to the page the Ajax panels will be updated according to the state of the current conversation. The downsides to the solution are that the user will notice a flash each time he or she backs up to the page (when the Ajax components reload) and it causes (what I would consider unnecessary) traffic between the client and the server. If this is acceptable, this solution will help you to use Ajax and Seam together to allow applications to behave according to a user’s expectations rather than the developer’s.








Posted in 


content rss
December 10th, 2007 at 4:47 am
Great follow-up. I didn’t notice that you had started blogging but I caught this link in the trackback to the original article. I posted about it so it’s findable in the Dev Fu categories.
December 10th, 2007 at 2:54 pm
Thanks Karsten
January 5th, 2008 at 9:37 am
It is so helpfull. Thx!!!
January 28th, 2008 at 1:30 pm
I considered using your approach but I ended up using a client side only solution. I added an oncomplete attribute to the a4j:commandLinks that I was using to update the page.
In this method, I saved a copy of the dynamically update section to a hidden input field.
function saveAjaxSection() {
var currentContent = document.getElementById( "tdrContentRegion" ).innerHTML ;
document.getElementById( "ajaxSaveField" ).value = currentContent ;
}
Then when the page reloads, I restore that section by hooking into the window.onload event and have it call the method below:
function reloadAjaxPanels(){
var previousContent = document.getElementById( "ajaxSaveField" ).value ;
if ( previousContent.length > 0 ) {
document.getElementById( "tdrContentRegion" ).innerHTML = previousContent ;
}
document.getElementById( "tdrContentRegionWrapper" ).style.display = "inline" ;
};
January 28th, 2008 at 1:34 pm
I forgot to mention that I also got rid of the “flash” of old content by making that section initially hidden and then enabling it in the window.onload. So both of the “downsides” that you mentioned get eliminated.
January 28th, 2008 at 6:27 pm
John,
Very nice option. The only downside I see is having to create hidden inputs for all sections that need to be reloaded, but in general cases this should be manageable. Thanks for sharing your approach!
April 4th, 2008 at 7:22 am
i have the same problem after try this code.
i am using richface 3.2.0 GA and seam 2.0.1.GA
this is my cample code
this code like a data Tabe filter .
After filter the data table by using Checkbox at the top , visit to the next page then i hit the browser back button , my filter list will be deselected .
how to resolve this problem.
we have this problem in our site. we need to fix this bug.
by
Thiagu.m
April 5th, 2008 at 2:45 pm
Discussion on Seam forum
April 24th, 2008 at 5:24 am
At the risk of sounding like an idiot, John talks about hooking into the window.onload… How do I do that? I don’t have direct access to as I’m using facelets templating and don’t see how I can add the onload attribute to my page without affecting all other pages.
April 24th, 2008 at 5:29 am
Oh, and the problem I’m having is that I have a search page (form fields and search results list) I navigate to one of the search results, hit the back button and all my fields are empty as well as my search results. I’ve confirmed that my backing beans are still alive as certain events on the page trigger reloads of the ajax components - suddenly restoring the fields. The difference I have with what you’ve described here is that it isn’t limited to IE, it’s also happening in firefox. So perhaps this indicates I’ve got other problems.
November 7th, 2008 at 5:14 am
Thank you, thank you, thank you!!!
February 26th, 2009 at 6:35 pm
[…] EE 5 Development using GlassFish Application Server First saved by sohobonobo | 7 days ago Alleviating client-side back-button issues with Ajax4JSF and… First saved by jannideath | 11 days ago AJAX Magic With JSF DataTables in Seam 2.0 First saved […]
March 10th, 2009 at 10:17 pm
This information is very userful.
thanks a lot.
I have a different problem. From the login page, after successful login, i will be navigated to some account page. If i try to come back to the login page, without using logout link, but by clicking browser back button, the identity component is still in the session. Because of this, the user is allowed to navigate to the account page by clicking the forward button without entering credentials. How to ensure that the user gets logged out of the application, if he navigates the login page by clicking the back button
Thanks in advance
March 29th, 2009 at 2:12 am
It is so helpfull.
but it is not work correctly when i am use the non-ajax component with ajax capability. please help to resolve this issue.
Ex:
April 5th, 2009 at 10:42 am
me too try this solution for client side back button in ajax pages.
but it is not working for non ajax component with ajax capability.
for example .
if i use the ajax form component with ajaxSubmit parameter is true
else ajax support component with any event to triger the ajax action.
this two component gives ajax capability to any non ajax component etc h:selectManyMenu, h:commandLink.
in this sinario the given client side back solution was not working what we expect.
by
Thiagu.m
April 7th, 2009 at 1:00 pm
Interesting. Have either of you come up with a solution to this problem? I did not run into this issue.
Have you tried the solution proposed by John Weidner in the comments above? It seems that his solution would not suffer from this issue as it is completely client-side (no ajax dependency).
August 28th, 2009 at 11:55 am
I actually got back and forward working in RichFaces and Ajax4JSF. For more information see .
August 28th, 2009 at 11:56 am
Sorry the link didn’t go through. Here is it … http://sauravbiswas.blogspot.com/2009/08/back-and-forward-buttons-working-in.html