Reputation: 2436
I am writing an application using Primefaces 3.4.1, Jboss AS 7.1 and MyFaces CODI. The problem that I got is that I am using conversation scope provided by CODI and I need a way to deal with the browser back button once the conversation ends.
More precisely- when the conversation ends and the user is on a different page (think about it like a wizard finishing and making a commit to database) if the back button is pressed I recieve the following exception:
javax.ejb.EJBTransactionRolledbackException
Ideally, since the conversation is finished I would like this to redirect back to some other page (menu, dashboard).
Can this be done with JSF 2.0 navigation rules?
EDIT:
I have created a navigation rule like this:
<navigation-rule>
<from-view-id>/page1.xhtml</from-view-id>
<navigation-case>
<from-outcome>outcome1</from-outcome>
<to-view-id>/page2.xhtml</to-view-id>
<redirect/>
</navigation-case>
<navigation-case>
<from-outcome>*</from-outcome>
<to-view-id>/dashboard.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
Hoping that this will make the redirection to dashboard.xhtml if we press back button. I assumed that there is a different action fired in the back end when you press it. Clearly I assumed wrong. Is it any way one could catch whatever is sent by the bakc button using these cases? Possibly with tag?
UPDATE 1:
Apparently the back button from the browser will not trigger the JSF navigation case. Is it clear what it will trigger? I implemented the following filter: https://stackoverflow.com/a/10305799/1611957 What wil it trigger now? Does that make the job of catching it easier?
Upvotes: 2
Views: 11864
Reputation: 730
This worked for me.
You can add the below code in between your <head> </head> tag
<script>
window.location.hash = "no-back-button";
window.location.hash = "Again-No-back-button";//again because google chrome don't insert first hash into history
window.onhashchange = function() {
window.location.hash = "no-back-button";
}
</script>
Upvotes: -1
Reputation: 2436
I have finally managed to resolve the issue and it may be helpful for others:
The first thing to do is to make sure that you are not caching pages. You can do it with the filter explained here:
https://stackoverflow.com/a/10305799/1611957
After that you will know that the page is going to be rendered, so you need to do a check before rendering if your conversation beans are instantiated correctly. How to do such a check is explained here:
https://stackoverflow.com/a/7294707/1611957
The code that I used is similar to the code posted by BalusC in this question:
<f:metadata>
<f:event type="preRenderView" listener="#{authenticator.check}" />
</f:metadata>
With the java code:
public void check() {
if (someCondition) {
FacesContext facesContext = FacesContext.getCurrentInstance();
NavigationHandler navigationHandler =
facesContext.getApplication().getNavigationHandler();
navigationHandler.handleNavigation(facesContext, null, "outcome");
}
}
With that you will dispatch the JSF navigation rule for the "outcome"
<navigation-rule>
<from-view-id>*</from-view-id>
<navigation-case>
<from-outcome>outcome</from-outcome>
<to-view-id>/defaultPage.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
And this is how you can gracefuly handle back button with JSF2.
Upvotes: 4