1
votes

I have a field that is rendered conditionally, based on a dropdown. All of that goes without problem, but when I submit the form of which the newly rendered component should be part of, it doesn't get submitted.

The code is fairly straightforward:

<h:form id="form">
    <p:layout id="layout">
        ...
        <p:layoutUnit id="layoutUnit">
            ...
            <p:panel id="panel">
                <p:outputPanel id="container1">
                    <p:selectOneMenu id="value1" value="#{bean.value1}">
                        <f:selectItem itemValue="1"/>
                        <f:selectItem itemValue="2"/>
                        <f:selectItem itemValue="3"/>
                        <f:selectItem itemValue="18"/>
                        <p:ajax event="change" update="container2"/>
                    </p:selectOneMenu> 
                </p:outputPanel>

                <p:outputPanel id="container2">
                    <p:inputText id="value2" 
                                 value="#{bean.value2}" 
                                 rendered="#{bean.value1 eq 18}"
                                 >
                    </p:inputText>
                </p:outputPanel>
            </panel>

            <div id="buttons">
                <p:commandButton id="commandButton" action="#{bean.save}" value="save" />
            </div>
        </layoutUnit>
    </layout>
</form>

Tried possible solutions:

I can think of a few scenarios causing this behaviour:

  1. 'Rendered' seems to re-evaluate based on values in the backing bean, rather than the new values given in the UI (if it defaults to 1, it is 1 again on submit, not 18). The component therefore doesn't get submitted.
  2. The added component isn't correctly added to the form, and therefore not submitted.
  3. ?

Option 1 seems to be the most likely one, but could anyone point me in the right direction?

I work with WAS8.5 (so JSF2.0), Primefaces and CDI.

1
"because it clashes with CDI" Hm? In other words, you aren't on JSF 2.2 yet and you can't upgrade? JSF 2.2 has namely a CDI compatible @ViewScoped annotation.BalusC
Describe how the UI is supposed to work, what you're doing in UI, and at what moment your expectations fail. It's not clear what your rendered binding is supposed to accomplish.Vsevolod Golovanov
@VsevolodGolovanov: OP's case fails because his bean is request scoped instead of view scoped. Now, OP is basically asking how to maintain view scoped state without making the bean view scoped. The "few scenarios" list makes no sense. It's already explained for long in particularly the 2nd link mentioned by the OP (which is thus essentially a duplicate of the question in its current form as long as OP don't elaborate his concrete problem with @ViewScoped)BalusC
We're working with WAS8.5 and therefore JSF2.0. I'm not sure if it's possible to upgrade to 2.2, so I'm looking for another solution. When using @Viewscoped, a change in an AJAX-component results in an error like javax.faces.FacesException: Exception while validating component with path ... Or is that unrelated?hhschoone
Why did you initially tag question with (unnecessary) [java-ee-7] tag while you're actually using WAS 8.5 (which is not Java EE 7)? Are you managing beans by JSF @ManagedBean or CDI @Named? With that "clash" you thus actually meant that you faced specifically that exception? (which is indeed potentially related and answerable while keeping @ViewScoped btw) How exactly is that exception related to "clashes with CDI"?BalusC

1 Answers

0
votes

Using CDI's @ConversationScoped in addition to @Named is a solution. That scope works comparable to the @ViewScoped from JSF.

To get it working I've simply added code from the example here. So in short:

Bean.java

@Named
@ConversationScoped
public class Bean implements Serializable{

    @Inject
    private Conversation conversation;

    Bean values, getters & setters

    public void initConversation(){
        if (!FacesContext.getCurrentInstance().isPostback() && conversation.isTransient()) {         
            conversation.begin();
        }
    }

    public String endConversation(){
        if(!conversation.isTransient()){
            conversation.end();
        }
    }

    public String navigateAwayFromScreen(){
        endConversation();
    }
}

beanOutput.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui"
    xmlns:ui="http://java.sun.com/jsf/facelets">

    <f:event listener="#{bean.initConversation}" type="preRenderView"/>

    <h:form id="form">
        <p:layout id="layout">
            ...
            <p:layoutUnit id="layoutUnit">
                ...
                <p:panel id="panel">
                    <p:outputPanel id="container1">
                        <p:selectOneMenu id="value1" value="#{bean.value1}">
                            <f:selectItem itemValue="1"/>
                            <f:selectItem itemValue="2"/>
                            <f:selectItem itemValue="3"/>
                            <f:selectItem itemValue="18"/>
                            <p:ajax event="change" update="container2"/>
                        </p:selectOneMenu> 
                    </p:outputPanel>

                    <p:outputPanel id="container2">
                        <p:inputText id="value2" 
                                     value="#{bean.value2}" 
                                     rendered="#{bean.value1 eq 18}"
                                     >
                        </p:inputText>
                    </p:outputPanel>
                </panel>

                <div id="buttons">
                    <p:commandButton id="commandButton" action="#{bean.navigateAwayFromScreen}" value="Go away!" />
                </div>
            </layoutUnit>
        </layout>
    </form>
</html>

Now, a conversation gets started when you open the page (due to the initConversation being called from the top of beanOutput.xhtml), and ended when you click the button navigateAwayFromScreen.

(However, if you are able to work with JSF2.2, it should be possible to use the @ViewScoped in combination with CDI. (I say 'should': I am not in the situation to upgrade. But it may be useful to others to examine)).