bjedrzejewski
bjedrzejewski

Reputation: 2436

Redirecting browser back button in jsf 2.0

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

Answers (3)

Ajay
Ajay

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

Dar Whi
Dar Whi

Reputation: 822

We are using @ConversationRequired for it.

Upvotes: 1

bjedrzejewski
bjedrzejewski

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

Related Questions