Search code examples
jsf-2primefacesprettyfaces

PrettyFaces navigation on selectOneMenu change


I have an application using PrettyFaces and PrimeFaces. One page is accessed using the URL pattern /#{ location : navigationBean.location }/#{ year : navigationBean.year }.

On that page I have a p:selectOneMenu containing possible values for location. If I change this menu I want the page to be refreshed with the same year and the new location.

I've tested this using AJAX to set the location in the navigationBean and then pressing a p:commandButton with the outcome pretty:view (view being the url-mapping id). This works but I want to get rid of the button.

I've tried the following, but sadly the return String in the method doesn't perform a navigation.

The JSF:

<p:selectOneMenu value="#{navigationBean.location}">
    <p:ajax listener="#{navigationBean.navigate}"/>
    <f:selectItems value="#{locationBean.locations}"/>
</p:selectOneMenu>

Backing bean:

public String navigate(AjaxBehaviorEvent event)
{
    return (location != null) ? "pretty:view" : null;
}

The PrettyFaces config:

<url-mapping id="view">
    <pattern value="/#{ location : navigationBean.location }/#{ /\\d{4}/ year : navigationBean.year }/"/>
    <view-id value="/view.xhtml"/>
</url-mapping>

Solution

  • You can't return a navigation outcome from (ajax) action listeners. You can only return it from real action methods as used in <h:commandButton action>.

    Use NavigationHandler#handleNavigation() instead.

    public void navigate() {
        FacesContext context = FacesContext.getCurrentInstance();
        context.getApplication().getNavigationHandler()
            .handleNavigation(context, null, (location != null) ? "pretty:view" : null);
    }