0
votes

I am writing an application with PrimeFaces 5, currently I am writing a screen with a couple of AutoComplete elements, with the idea that the value of one autocomplete influences the selections available in the second autocomplete.

The way I have tried to get this to work is that when the first autocomplete it filled in, an Ajax event is fired to update the backing bean with the value, so that when the second autocomplete is invoked, it had the value from the first autocompleted ready to switch on.

This is the page:

<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">

    <pf:panel id="header" header="Details" style="margin-bottom:20px">
        <h:panelGrid columns="3" style="margin-bottom:10px;border-style:solid;border-width:0.1em;width:100%" cellpadding="5">
            <pf:outputLabel id="input1Label" for="input1" value="Specify Input 1" />
            <pf:autoComplete id="input1" value="#{bean.input1}" completeMethod="#{bean.completeInput1}"
                        var="input1" itemLabel="#{input1}" itemValue="#{input1}" >
                <pf:ajax event="itemSelect" listener="#{bean.input1ItemSelect}"/>
            </pf:autoComplete>
            <pf:message id="input1Msg" for="input1"/>

            <pf:outputLabel id="input2Label" for="input2" value="Input 2?" />
            <pf:autoComplete id="input2" value="#{bean.input2}" completeMethod="#{bean.completeInput2}"
                        var="input2" itemLabel="#{input2}" itemValue="#{input2}" />
            <pf:message id="input2Msg" for="input2"/>
        </h:panelGrid>
    </pf:panel>

</ui:composition>

However when a value is selected in input1, I get this error:

Unreachable, identifier 'bean' resolved to null: javax.el.PropertyNotFoundException: Target Unreachable, identifier 'bean' resolved to null

Now the next thing to point out is that this composition is included in a parent composition and "bean" is passed in as a parameter in the following fashion:

<c:forEach items="#{parentBean.blockNames}" var="blockName" varStatus="loop">

    <f:subview id="block_subview_#{loop.index}">
        <ui:include src="#{blockName}">
            <ui:param name="bean" value="#{parentBean.blockBeans[loop.index]}"/>
        </ui:include>
    </f:subview>
</c:forEach>

What I've been able to establish is that if I change the reference "bean" in the pf:ajax tag to a named bean it is able to resolve the bean reference and attempts to invoke the listener method. So it seems like for some reason the pf:ajax tag is unable to cope with the "bean" reference because it is not the name of an actual bean but rather the name of a bean parameter passed in from the parent. However all the other tags are perfectly able to resolve "bean" here.

Is there a way round this?

Edit:

Changing the pf:ajax to a f:ajax seems to make the error go away, at least the correct listener method is then invoked. I'd rather not use this approach but maybe this information is useful.

3

3 Answers

0
votes

You could try to put the content of the included page in a composite component and then use the composite component instead of the ui:include.

I worked at several complex JSF websites and never had any problems with the composite component technique while those ui:include always created some kind of problems in a loop.

0
votes

Found out the cause, turns out the backing bean (or specifically, the backing bean of the parent page) was using @RequestScoped (or rather it was defaulting to this since no scope was specified), so presumably no longer existed by the time the user invoked the ajax call to it. Changing it to @ViewScoped fixed the problem.

-1
votes

Well,

this is probably happening because of the c:forEach tag. Try to use ui:repeat instead.

c:forEach is not a JSF tag, and it may cause confusion.