Alleviating client-side back-button issues with Ajax4JSF and RichFaces

Date 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.

Enjoyed this post? Share it!

  • description
  • del.icio.us
  • Digg
  • Google
  • Technorati
  • StumbleUpon
  • Furl
  • Reddit

18 Responses to “Alleviating client-side back-button issues with Ajax4JSF and RichFaces”

  1. Karsten Wade said:

    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.

  2. jacob.orshalick said:

    Thanks Karsten :)

  3. ml said:

    It is so helpfull. Thx!!!

  4. John Weidner said:

    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" ;
    };

  5. John Weidner said:

    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.

  6. jacob.orshalick said:

    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!

  7. thiagu said:

    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

  8. jacob.orshalick said:

    Discussion on Seam forum

  9. Craig Sherstan said:

    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.

  10. Craig Sherstan said:

    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.

  11. Serbia said:

    Thank you, thank you, thank you!!!

  12. Recent Faves Tagged With "ajax4jsf" : MyNetFaves said:

    […] 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 […]

  13. anjani said:

    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

  14. alex said:

    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:

  15. thiagu said:

    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

  16. jacob.orshalick said:

    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).

  17. saurav said:

    I actually got back and forward working in RichFaces and Ajax4JSF. For more information see .

  18. saurav said:

    Sorry the link didn’t go through. Here is it … http://sauravbiswas.blogspot.com/2009/08/back-and-forward-buttons-working-in.html

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>