1

I'm trying to make a partial rendering navigation for an application. The code bellow is a concept test that works well with exception of the commandbutton on x.xhtml file. It does't fire the actionListeneron a click. This is used to change the url for the included part.

index.xhtml

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui">
    <f:view contentType="text/html">
        <h:head>
            <f:facet name="first">
                <meta content='text/html; charset=UTF-8' http-equiv="Content-Type"/>
                <title>PrimeFaces</title>
            </f:facet>
            <style type="text/css">
                .ui-layout-north {
                    z-index:20 !important;
                    overflow:visible !important;;
                }

                .ui-layout-north .ui-layout-unit-content {
                    overflow:visible !important;
                }
            </style>
        </h:head>
        <h:body>
            <p:layout fullPage="true">
                <p:layoutUnit position="north" size="100" header="Top" resizable="true" closable="true" collapsible="true">  
                    <h:form>
                        <p:menubar>
                            <p:submenu label="File" icon="ui-icon-document">
                                <p:menuitem value="XXX" update=":wrapper" actionListener="#{tbean.doNav}">
                                    <f:attribute name="xxx_page" value="x.xhtml" />
                                </p:menuitem>
                                <p:menuitem value="YYY" update=":wrapper" actionListener="#{tbean.doNav}">
                                    <f:attribute name="xxx_page" value="y.xhtml" />
                                </p:menuitem>
                            </p:submenu>
                        </p:menubar>
                    </h:form>
                </p:layoutUnit>
                <p:layoutUnit position="center">
                    <p:outputPanel id="wrapper">
                        <ui:include src="#{tbean.url}"/>
                    </p:outputPanel>
                </p:layoutUnit>
            </p:layout>
        </h:body>
    </f:view>
</html>

x.xhtml

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<ui:component xmlns="http://www.w3.org/1999/xhtml"
              xmlns:h="http://java.sun.com/jsf/html"
              xmlns:f="http://java.sun.com/jsf/core"
              xmlns:ui="http://java.sun.com/jsf/facelets"
              xmlns:p="http://primefaces.org/ui" 
              xmlns:c="http://java.sun.com/jsp/jstl/core">
    <h:form>
        <p:commandButton value="zzz" update=":wrapper" actionListener="#{tbean.doNav}">
            <f:attribute name="xxx_page" value="z.xhtml" />
        </p:commandButton>

        <p:dataTable var="car" value="#{tbean.cars}">
            <p:column>
                <f:facet name="header">  
                    Name
                </f:facet>
                <h:outputText value="#{car.name}" />
            </p:column>
        </p:dataTable>
    </h:form>
</ui:component>

y.xhtml

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<ui:component xmlns="http://www.w3.org/1999/xhtml"
              xmlns:h="http://java.sun.com/jsf/html"
              xmlns:f="http://java.sun.com/jsf/core"
              xmlns:ui="http://java.sun.com/jsf/facelets"
              xmlns:p="http://primefaces.org/ui" 
              xmlns:c="http://java.sun.com/jsp/jstl/core">
    <h:outputText value="yyy"/>
</ui:component>

z.xhtml

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<ui:component xmlns="http://www.w3.org/1999/xhtml"
              xmlns:h="http://java.sun.com/jsf/html"
              xmlns:f="http://java.sun.com/jsf/core"
              xmlns:ui="http://java.sun.com/jsf/facelets"
              xmlns:p="http://primefaces.org/ui" 
              xmlns:c="http://java.sun.com/jsp/jstl/core">
    <h:outputText value="zzz"/>
</ui:component>

tbean.java

package com.teste;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.event.ActionEvent;

@ManagedBean
@RequestScoped
public class tbean {

    private String url = "y.xhtml";
    private List<Car> cars = new ArrayList<>();

    public tbean() {
        for (int i = 0; i < 10; i++) {
            cars.add(new Car(i));
        }
    }

    public void setUrl(String url) {
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "setUrl :{0}", this.url);
        this.url = url;
    }

    public String getUrl() {
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "getUrl :{0}", this.url);
        return this.url;
    }

    public void doNav(ActionEvent event) {
        this.url = (String) event.getComponent().getAttributes().get("xxx_page");
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "doNav :{0}", this.url);
    }

    public List<Car> getCars() {
        return cars;
    }
}
André G. Andrade
  • 501
  • 11
  • 21

1 Answers1

1

Your backing bean is request scoped. This means that it's created on every HTTP request. So the url property will default to y.xhtml on every request.

Submitting the form by the command button creates a new HTTP request. So it gets a new instance of the request scoped bean with the url property defaulted to y.xhtml. When JSF needs to process the form submit, it can't figure the button pressed because it's not present in y.xhtml. So JSF cannot invoke the action associated with the button pressed.

Placing the bean in view scope should fix your problem.

@ManagedBean
@ViewScoped
public class tbean {

This will remember the url property properly across the HTTP requests on the very same view (by returning null or void on every action).

See also:


As to the whole design, you need to make absolutely sure that all the ajax actions are been invoked by PrimeFaces components, not by the standard JSF <f:ajax> ones, otherwise the commandbutton would still not be invoked due to a bug in JSF JS.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Hi BalusC, I had read you links sugestion and tried the ViewScoped bean, but I contine with the same result the actionlisterner isnt beeing called. – André G. Andrade Aug 02 '12 at 14:59
  • I solved thi issue changing bean scope from **@RequestScoped** to **@SessionScoped** and updating my Mojarra to 2.1.11. My enviroment is Glassfish-3.1.2 and Primefaces-3.3.1 – André G. Andrade Aug 04 '12 at 03:10
  • hi I had done just the same after a similar answer by @BalusC: using a SessionScoped. But viewscoped is indeed more correct and can work, check the import statements and see if you don't mix faces and enterprise import statements (Netbeans mixes the two I've found). See my question and the replies: http://stackoverflow.com/questions/12349255/conditionally-rendered-input-component-does-not-update-value – seinecle Sep 26 '12 at 19:34