Search code examples
javajsfrichfaces

Non rendered components do not have values updated


I am using a form with two radio buttons (h:selectOneRadio), two text fields (h:selectOneRadio) and one reset button (a4j:commandButton). I am also using a4j:support to re-render the text fields when the radio buttons are clicked.

The behaviour of this form must be like this:

  • When the user clicks on the first radio button, the first text field must be rendered and the second one, must not;

  • When the user clicks on the second radio button, the situation inverts, only the second text field must be rendered;

  • When the user clicks on the reset button, the content of both text field must be cleaned.

Here is the xhtml page:

<!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:h="http://java.sun.com/jsf/html"
    xmlns:a4j="http://richfaces.org/a4j"
    xmlns:rich="http://richfaces.org/rich"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets">

<head/>
<body>
    <h:form>
        <rich:panel style="width:50%">
            <rich:messages showDetail="false" showSummary="true"/> <br />
            <h:panelGrid columns="1">
                <h:selectOneRadio value="#{updateNotRendered.choice}" label="Choose one">
                    <f:selectItem itemValue="CHOICE1" itemLabel="Choice number 1"/>
                    <f:selectItem itemValue="CHOICE2" itemLabel="Choice number 2"/>

                    <a4j:support event="onclick" reRender="pnlFields"/>
                </h:selectOneRadio>

                <h:panelGroup id="pnlFields">
                    <h:panelGrid columns="2" rendered="#{updateNotRendered.choice1Selected}">
                        <h:outputLabel value="Choice 1 content:" />
                        <h:inputText value="#{updateNotRendered.content1}" />
                    </h:panelGrid>

                    <h:panelGrid columns="2" rendered="#{updateNotRendered.choice2Selected}">
                        <h:outputLabel value="Choice 2 content:" />
                        <h:inputText value="#{updateNotRendered.content2}" />
                    </h:panelGrid>
                </h:panelGroup>
                <a4j:commandButton action="#{updateNotRendered.reset}" value="Reset" reRender="pnlFields"/>
            </h:panelGrid>
        </rich:panel>       
        <a4j:log />
        <f:phaseListener type="poc.jsf.richfaces.PhaseL"/>
    </h:form>
</body>
</html>

And here is the Managed Bean code:

public class UpdateNotRendered {
    private String choice;
    private String content1;
    private String content2;

    public String getChoice() {
        return choice;
    }
    public void setChoice(String choice) {
        this.choice = choice;
    }
    public String getContent1() {
        return content1;
    }
    public void setContent1(String content1) {
        this.content1 = content1;
    }
    public String getContent2() {
        return content2;
    }
    public void setContent2(String content2) {
        this.content2 = content2;
    }

    public boolean isChoice1Selected() {
        return choice != null && choice.equals("CHOICE1");
    }

    public boolean isChoice2Selected() {
        return choice != null && choice.equals("CHOICE2");
    }

    public void reset() {
        content1 = null;
        content2 = null;
    }
}

The problem I am having is: when the user fills both text fields and click on the reset button, only one of the text field, the rendered one, gets cleaned.

This problem can be reproduced with the following steps:

  1. Click on the first radio button and fill the first text field;
  2. Click on the second radio button and fill the second text field;
  3. Click on the reset button;
  4. Click on the first radio button. It will be filled

I suspect that the non rendered text field does not get updated on the Component Tree when the reset button is clicked.

What can I do to clean both textfields?

I am using richfaces 3.3.3

EDITED: Is there a context parameter that ensures the updating of non rendered components?


Solution

  • I suspect you are right.

    A workaround for your problem might be to not exclude the text-fields from being rendered but only to set the visibility to hidden. This could be easily done with code like this:

    <h:panelGrid columns="2"
                 style="visibility:#{updateNotRendered.choice1Selected ? 'visible' : 'hidden'}">
        <h:outputLabel value="Choice 1 content:" />
        <h:inputText value="#{updateNotRendered.content1}" />
    </h:panelGrid>
    

    hth,
    - martin