4

I have two JSF pages,suppose A and B.From these two pages A and B I can navigate to page C.Now there is a button(OK button) in page C,clicking on which it should navigate back to either A or B depending upon from where(either A or B),page C was called.Any help will be deeply appreciated.

Obl Tobl
  • 5,604
  • 8
  • 41
  • 65
Shaan
  • 67
  • 1
  • 5
  • possible duplicate of [back commandbutton in jsf](http://stackoverflow.com/questions/649834/back-commandbutton-in-jsf) – Matt Handy Feb 28 '13 at 08:01

2 Answers2

6

Solution that utilizes view parameter

The idea is that you can pass the current view id as a get parameter of the next (target) page. From the target page you will be able to use it to navigate back.

Basic example:

Views A & B:

<h:body>
    Hello from page A (B)
    <h:link value="Go to page C via link" outcome="target">
        <f:param name="backurl" value="#{view.viewId}"/>
    </h:link>
    <h:form>
        <h:commandButton value="Go to page C via command button" action="#{baseBean.doAction}"/>
    </h:form>
</h:body>

View C:

<f:metadata>
    <f:viewParam name="backurl" value="#{backBean.backurl}"/>
</f:metadata>
<h:body>
    Hello from page C
    <h:link value="Go back via link" outcome="#{backBean.backurl}">
    </h:link>
    <h:form>
        <h:commandButton value="Go to page C via command button" action="#{backBean.back}"/>
    </h:form>
</h:body>

Bean of pages A / B:

@ManagedBean
@RequestScoped
public class BaseBean {

    public String doAction() {
        String url = FacesContext.getCurrentInstance().getViewRoot().getViewId();
        return "/target?faces-redirect=true&backurl=" + url;
    }

}

Bean of page C:

@ManagedBean
@RequestScoped
public class BackBean {

    private String backurl;

    public String back() {
        return backurl + "?faces-redirect=true";
    }

    public String getBackurl() {
        return backurl;
    }

    public void setBackurl(String backurl) {
        this.backurl = backurl;
    }

}

The last point to mention is that view id may differ from URL in a web browser.

Enhancement to the solution when only <h:link> is used

Taking into consideration the rightful comment by BalusC and his previous answer on the question Cancel button doesn't work in case of validation error, in case you don't need to employ <h:commandButton> in the target page, thus do not need to do any business job when going back to the previous page, you can essentially leave the job to <h:link>. In this scenario the backing bean (of the target view) is not needed at all and the structure of the target view can be minimized to:

<f:metadata>
    <f:viewParam name="backurl"/>
</f:metadata>
<h:body>
    Hello from page C
    <h:link value="Go back" outcome="#{backurl}" rendered="#{not empty backurl}"/>
</h:body>
Community
  • 1
  • 1
skuntsel
  • 11,624
  • 11
  • 44
  • 67
  • Note that in case of `` in C the whole bean is unnecessary. Just get rid of `value` attribute of `` and use `outcome="#{backurl}"`. See also http://stackoverflow.com/questions/13148566/cancel-button-doesnt-work-in-case-of-validation-error/13149506#13149506 – BalusC Feb 28 '13 at 13:18
  • @BalusC Of course, but in that case we'll have to remove the value binding of ``, otherwise it will be empty. Ah, edits, edits :) – skuntsel Feb 28 '13 at 13:34
  • Uhm, did I tell otherwise? – BalusC Feb 28 '13 at 13:35
  • @BalusC By the way, can you check out [what's wrong with my solution with internalization problem](http://stackoverflow.com/a/15121121/1820286), because I can't get it fully working? – skuntsel Feb 28 '13 at 13:40
  • what mean `rendered="#{not empty backurl}"` ? – kuba44 Oct 04 '13 at 12:52
0

You could implement a property comesFrom in your Beanclass. This property you can give the name of your page where you're coming from when navigating to page C (A if it's page A, B if it's page B).
On click on your OK button in your page C you can check your property comesFrom and navigate back to the value of the property.

Obl Tobl
  • 5,604
  • 8
  • 41
  • 65