0

I am trying to write a simple JSF page that initially includes two subviews/includes, and pass the backing bean to one of the includes because the include is meant to be reusable (and possibly included more than once in a larger application).

This is the relevant code:

page1.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:p="http://xmlns.jcp.org/jsf/passthrough"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:pf="http://primefaces.org/ui"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    template="templates/template1.xhtml">

    <ui:define name="subheader">
        Person Details
    </ui:define>

    <ui:define name="bodyContent">
        <h:form>
            <c:forEach items="#{page1Bean.blockNames}" var="blockName">
                <c:choose>
                    <c:when test="#{blockName} eq 'block1'">
                        <ui:include src="block1.xhtml" >
                            <ui:param name="bean" value="#{page1Bean.myBean}"/>
                        </ui:include>
                    </c:when>
                    <c:otherwise>
                        <ui:include src="#{blockName}.xhtml" />
                    </c:otherwise>
                </c:choose>
            </c:forEach>
            <pf:commandButton value="Ajax Button" action="#{page1Bean.ajaxSubmit()}"/>
        </h:form>

    </ui:define>
</ui:composition>

block1.xhtml

<ui:composition 
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://xmlns.jcp.org/jsf/passthrough"
    xmlns:pf="http://primefaces.org/ui">

    <h3>This is the first block</h3>
    <h:panelGrid columns="3" style="margin-bottom:10px" cellpadding="5">

        <pf:outputLabel for="firstName" value="Nombre:" />
        <pf:inputText id="firstName" value="#{bean.firstName}" />
        <h:message id="firstNameMessage" for="firstName" />

    </h:panelGrid>
</ui:composition>

Page1Bean.java

package com.views.prototype;

import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;

@ManagedBean
public class Page1Bean {

    private List<String> blockNames;

    private Block1Bean myBean;

    public Page1Bean() {
        blockNames = new ArrayList<String>();

        blockNames.add("block2");
        blockNames.add("block1");

        myBean = new Block1Bean();
    }

    public void ajaxSubmit() {
    }

    @SuppressWarnings("unchecked")
    public static <T> T findBean(String beanName) {
        FacesContext context = FacesContext.getCurrentInstance();
        return (T) context.getApplication().evaluateExpressionGet(context, "#{" + beanName + "}", Object.class);
    }

    public List<String> getBlockNames() {
        return blockNames;
    }

    public void setBlockNames(List<String> blockNames) {
        this.blockNames = blockNames;
    }

    public Block1Bean getMyBean() {
        return myBean;
    }

    public void setMyBean(Block1Bean myBean) {
        this.myBean = myBean;
    }
}

Block1Bean.java

package com.views.prototype;

import javax.faces.bean.ManagedBean;

@ManagedBean
public class Block1Bean {
    private String firstName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    @Override
    public String toString() {
        return "Block1Bean [firstName=" + firstName + "]";
    }   
}

The page renders ok but when I click submit I get:

value="#{bean.firstName}": Target Unreachable, identifier 'bean' resolved to null

As far as I can see I am using the same syntax as the solutions to these examples:

Reusing the same page multiple times

Passing the backing bean as a parameter to a Facelet include

Any ideas on where I am going wrong?

Community
  • 1
  • 1
Patata Pequeña
  • 115
  • 1
  • 11

2 Answers2

1

The problem turns out to be the clash between JSTL and JSF, as noted on several threads:

JSTL c:choose c:when not working in a JSF page

Specify conditional rendering of element inside <ui:repeat>? The <c:if> does not seem to work

So I've rewritten the loop not to use JSTL and it gets rid of the immediate problem in the original question:

        <ui:repeat var="blockName" value="#{page1Bean.blockNames}" varStatus="status">
            <ui:fragment rendered="#{blockName == 'block1'}">
                <ui:include src="#{page1Bean.theBlockName}" >
                    <ui:param name="bean" value="#{page1Bean.myBean}"/>
                </ui:include>
            </ui:fragment>

            <ui:fragment rendered="#{blockName != 'block1' }">
                <ui:include src="block2.xhtml" />
            </ui:fragment>

        </ui:repeat>

(This isn't functionally equivalent to the intended purpose of the broken one however the point is it doesn't use JSTL).

Community
  • 1
  • 1
Patata Pequeña
  • 115
  • 1
  • 11
0

It probably happens because you are passing a request scoped bean to the other page. Once the request is finished, the bean exists no more. Try to use a larger scope like view to your bean. It should work fine.

@ManagedBean
@ViewScoped
public class Block1Bean {

}

Otherwise, you will have to extend the request scope by using a feature such as keepAlive.

RafaelTSCS
  • 1,234
  • 2
  • 15
  • 36
  • 1
    I actually tried setting the scope to SessionScoped just to rule this one out, and I still got the same problem. So far I seem to have narrowed the problem down to something to do with using the JSTL tag, as without that the tag seems to work fine. I'm trying to replace it with the tag although it doesn't seem to match the condition within... When I get a solution I'll post it up (or if somebody else posts one up I'll mark it as correct). – Patata Pequeña Jun 30 '14 at 13:01
  • 1
    Perhaps [this thread](http://stackoverflow.com/questions/7248439/can-i-specify-conditional-rendering-of-an-element-inside-uirepeat) can help you – RafaelTSCS Jun 30 '14 at 13:15
  • Thanks, I had just seen we have several threads like that one, it does seem like yet another JSF/JSTL incompatibility. – Patata Pequeña Jun 30 '14 at 13:31