1

I have a screen with 2 JSF Input Components: inputText and inputText with suggestionBox. They are both bound to the same field, but only one can be visible/rendered (mutual exclusion).
The thing is that if I write something in one and then submit, the other component which is not displayed is updating the model (the same field is updated again) with it's value (which is empty string or null). To work around this I created another field in my Class, so that the 2 components don't refer to the same field.
I don't like this, because I'm altering my model to solve a GUI problem.

How can I have 2 mutually exclusive input components referring the same value working as I want ?

Kara
  • 6,115
  • 16
  • 50
  • 57
Cosmin Cosmin
  • 1,526
  • 1
  • 16
  • 34
  • It should be able to work. When you say "component that is not displayed" I assume you are controlling this with rendered="false"? – Dave Maple Jun 07 '11 at 14:15
  • actually is `visible=false`, in ADF Faces. We're not allowed to use rendered for some reason. input texts with visible=false I think are used to pass values through requests not needed in the screen. Any workaround, to get the same behavior like rendered ? visible=false + readonly=true or something like this ? – Cosmin Cosmin Jun 07 '11 at 14:29
  • I don't know anything about ADF Faces but I can't imagine they would remove support for the rendered attribute. It's rather essential to JSF. I'll research a bit as the problem seems to be that your not truly removing the component from the render phase -- you're just making it invisible. – Dave Maple Jun 07 '11 at 14:33
  • the rendered attribute exists, but we can't use it. I know it's rendered in html with some css that makes it hidden. – Cosmin Cosmin Jun 07 '11 at 15:01
  • why can't you use it? It is what will solve the very problem you are posting about? Do you have a team lead that had a bad childhood experience with it? It is really the only elegant way to solve the problem above (and it's super easy to implement). – Dave Maple Jun 07 '11 at 15:12

2 Answers2

1

The key is to use the rendered attribute to show/hide the components so that only one or the other is actually updating the model at a time. Here is a very basic example to illustrate:

<h:form id="exampleForm" prependId="false">

    <h:inputText id="test1" value="#{exampleBean.testString}" rendered="#{exampleBean.toggle}" style="border: 1px solid red;" />
    <h:inputText id="test2" value="#{exampleBean.testString}" rendered="#{!exampleBean.toggle}" style="border: 1px solid blue;" />

    <h:commandButton id="testButton" action="#{exampleBean.toggle()}" />

</h:form>

and the example bean with shared property testString:

@ManagedBean(name = "exampleBean")
@ViewScoped
public class ExampleBean {

    private String testString;

    public String getTestString() { return testString; }

    public void setTestString(String testString) { 
        this.testString = testString; 
        System.out.println(testString);
    }

    private boolean toggle;

    public boolean isToggle() { return toggle; }
    public void setToggle(boolean toggle) { this.toggle = toggle; }

    public void toggle() {
        toggle = (toggle) ? false : true;
    }

}
Dave Maple
  • 8,102
  • 4
  • 45
  • 64
-1

As I stated I can't use rendered, so in this case using readonly true with visible false gives me the behavior I need. Thanks.

Cosmin Cosmin
  • 1,526
  • 1
  • 16
  • 34