RichFacesTwoInputText

How to update the value in the second h:inputText changing the value in the first h:inputText

 

You should not send the value of the second input in an Ajax request when you submit the first inputText value. One possible way is wrapping the first inputText with <a4j:region>

 

 

Read the explanation:

 

if you have an h:inputText value="{foo.bar}" there are 4 (four!) places where the value is stored during the lifecycle.

 

One is the 'bar' property of the 'foo' bean. It is easy. Where are three others?

 

h:inputText is a component. The instance of it belongs to the component tree. Does this instance contain the value? Yes! It names 'local value'. It has the same type, the 'bar' property has. Thus, if 'bar' is java.util.Date, the local value has the same type.

What if a user types and submits some garbage, but not a date? Hey, JSF is not so stupid. It reserved the 'submitted value' for this case. This is a third placeholder.

 

The fourth place is a request parameters map. The typed value comes with a request before it the submitted value is assigned.

 

Ideally: The submitted value should be checked against the converter and only, if it is OK, the local value is updated and the submitted value is cleaned up.

Then, only if validation and update phases are passed successfully, the model value (ie. foo.bar itself) is updated and the local value is cleaned up.

 

Why I said "Ideally"? Because JSF is not stupid, but its implementations are buggy (from version to version in a different degree). Sometimes, the local value or submitted value is not cleaned up.

 

This does not matter if the navigation brings to the news view page. In this case, the old component tree is void, and a new fresh tree is created.

 

However, if the lifecycle comes to the RENDER RESPONSE phase with the same tree (and this is always true for Ajax Request/Response), the component renderer should be smart enough to resolve the situation.

 

Assume, a user enters the wrong date. The page after reload should show the value user entered, but not the old one from the model. Right?

 

Ideally, the algorithm is the following:

  • if a submitted value is not empty, grab it and show

  • otherwise, if a local value is not null, show it

  • otherwise, call a getter of the model value and show it

 

To make a long story short, I am not going to explain why I said 'Ideally' again. It is up to your imagination.

 

Conclusion: there are too many 'if', 'only if', 'ideally' should be matched before what is obvious from your point of view (taking value from the model) can happen.

 

Hence, do not play with the fire. Be proactive. There are many ways:

 

1. do not submit the value at all. You can do it using ajaxSingle attribute.

 

This does not work for select type components (Why? This is a theme for another tale)

 

2. do not process the other input. This is achieved with surrounding the first input with a4j:region

 

3. use binding on the second input. The binding allows you to access the component object. You can clean up the submitted and local values to make updating from the model works OR put the new value to the local value directly and let a component renderer to feel how much it is smart.