1

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.

Community
  • 1
  • 1
hhschoone
  • 19
  • 1
  • 5
  • 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 Jul 22 '15 at 11:13
  • 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 Jul 22 '15 at 11:22
  • @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 Jul 22 '15 at 11:28
  • 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 Jul 22 '15 at 11:43
  • 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 Jul 22 '15 at 11:55
  • Yeah, excuse me - I should've mentioned I'm relatively new to the Java-world, learning on the job so to say. Regardless, I'm using CDI's `@Named`. Changing that to `@ViewScoped` results in the exception mentioned above. However, you say the issue should be solvable using `@ViewScoped` instead of `@Named`, thus not being induced by working with both JSF and CDI? – hhschoone Jul 22 '15 at 12:21
  • Using `@ConversationScoped` in addition to `@Named` seems to be a (the?) solution - doing something comparable to `@ViewScoped`. I've simply added code from the example [here](http://www.javacodegeeks.com/2013/04/java-ee-cdi-conversationscoped-example.html). Only thing I'm not sure about now, is whether or not the conversation gets closed correctly. tbc – hhschoone Jul 22 '15 at 13:45
  • `@ViewScoped` and `@Named` are not mutually exclusive. `@ManagedBean` and `@Named` are. You can just use `@Named @ViewScoped`, you only need to watch out that you use CDI `@ViewScoped` and not JSF `@ViewScoped`. Only, CDI `@ViewScoped` is available since JSF 2.2 only, or you have to grab OmniFaces. – BalusC Jul 23 '15 at 13:24
  • PS: in case more than one people have commented on a post, use `@nickname` (without code tags) to reply on a specific person (otherwise the person of interest won't be notified of a comment-reply and will only see it later "by coincidence"). – BalusC Jul 23 '15 at 13:25

1 Answers1

0

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)).

hhschoone
  • 19
  • 1
  • 5