JSF Backing Bean State Being Lost Prior to Submit

ISSUE

I have an attribute in a backing bean for a drop-down list in a JSF that loses its state before I submit the page, which causes data updates to the backing bean dependent upon its state to be ignored.

CONTEXT

The JSF in question has a selectOneMenu drop-down list that determines whether or not several inputText fields will be rendered. The selectOneMenu is bound to an enum in the backing bean, and there are conditional accessors allowing the JSF to determine which inputTexts should be included in the current view. The three valid values of the drop-down are "ALL", "RANGE" and "SINGLE". The page is request scoped, a requirement of this project.

Here is the JSF tag for the selectOneMenu drop-down list:

<h:selectOneMenu disabled="#{not backingBean.newEntry}"

id="tCriteria"

value="#{backingBean.tCriteria}"

onchange="submit()">

<f:selectItems value="#{backingBean.possibleTCriteria}" />

</h:selectOneMenu>

And here are the RANGE selection-specific inputText controls:

<h:inputText disabled="#{not backingBean.newEntry}"

rendered="#{backingBean.tRange}"

id="startTIndex"

value="#{backingBean.tIndex}" />

<h:inputText disabled="#{not backingBean.newEntry}"

rendered="#{backingBean.tRange}"

id="endTIndex"

value="#{backingBean.endTIndex}" />

Here is how I initialize the backing bean for the drop-down list attribute:

/**

* The current "t" criteria.

*/

private TCriteria tCriteria = TCriteria.ALL;

And there are basic accessor/mutator methods for it. All of this works pretty well, with one problem. If I select "RANGE" in the drop-down, the appropriate inputText fields appear in the view. When I submit the page with values in the inputText fields, the value of the drop-down in the backing bean has been reset to its default initial value ("ALL") without having been updated through its mutator. Thus, when values in the backing bean are updated from the JSF, the conditional inputText fields are ignored, as they appear to have been deemed irrelevant during the update phase by the invalid state of the backing bean for the drop-down.

To test my theory, I changed the default value of the backing bean attribute for the drop-down to be "RANGE", and made it final. The page behaves perfectly in updating the backing bean with the values entered for the conditionally-displayed inputText controls. This tells me that the invalid state of the backing bean drop-down list attribute must be the problem. Furthermore, I have tried using "disabled=", "readonly=" and "rendered=" on the conditional inputText fields, and none of that seems to make a difference. I also tried using a ValueChangeHandler, but that didn't do anything about it.

Note - the backing bean does realize that the correct state for the drop-down should be "RANGE", but only AFTER the backing bean has received its updated values from the page controls.

Has anyone seen anything like this? I haven't read anything in previous posts about an issue like this, but it has to be something someone has seen before. Maybe related to using the enum type? Thanks.

[3646 byte] By [shinolaJLAa] at [2007-11-26 21:18:35]
# 1
Make backingBean session scoped.CowKing
IamCowKinga at 2007-7-10 2:57:39 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 2

It's a project requirement that all beans are request scoped. But I did give it a try, and even changing the bean scope to session does not fix the problem - the data for the inputText controls that are rendered based on the state of the drop-down list are still ignored, and the drop-down list state returns to "ALL".

Any other thoughts would be appreciated. This is really bizarre behavior.

shinolaJLAa at 2007-7-10 2:57:39 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 3

I think I may have found an answer. We are using MyFaces here, and I tried "saveState" on the attribute holding the state of the drop-down list box. That appears to have done the trick.

Here's the tag used:

<t:saveState value="#{backingBean.tCriteria}" />

Thanks to anyone who gave this a look.

shinolaJLAa at 2007-7-10 2:57:39 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 4

You do realise that in the jsf-config.xml you can specify where

state is saved, that being either on the server or on the client

and that with a submit of changed information back to the same

URL page you could accidently restore the default value of the

page through returning to the same URL dependent the

instantiation sequence?

JSP and JSF are servlets in actuallity and everything done

occurs on the server. The client state is crypted and stored in

a special html hidden form field.

nicephotoga at 2007-7-10 2:57:39 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 5
Note to correct above:Sorry, jsf-config.xml should be faces-config.xml file.
nicephotoga at 2007-7-10 2:57:39 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 6
I have a dude, i think i read somewhere in the net when state is saved in server the <t:saveState .../> doesn't work. Am I correct?Greetings.Ricardo MontoyaMessage was edited by: MogaRick
MogaRicka at 2007-7-10 2:57:39 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 7

Hi,

did your web.xml file had any parameter regarding explicitly indicating the way to save state?

I mean something like

<context-param>

<param-name>javax.faces.STATE_SAVING_METHOD</param-name>

<param-value>server</param-value>

</context-param>

One last question: did you stay with request scope beans or session ones?

Greetings.

MogaRick

MogaRicka at 2007-7-10 2:57:39 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 8
MogaRick,Sorry for the delayed response. Our web.xml file does indeed have the exact clause you mention, where state saving method is assigned to the server.We stayed with request-scoped beans.Hope that helps.
shinolaJLAa at 2007-7-10 2:57:39 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 9

Hi,

suppose you set savestae for 'calcForm' object,

<x:saveState id="saveCalcForm" value="#{calcForm}" />

you can use your saved object in backing bean using

FacesContext facesContext = FacesContext.getCurrentInstance();

VariableResolver vr = facesContext.getApplicatio().getVariableResolve();

and you can acces your object with

CalcForm calcForm = (CalcForm )vr.resolveVariable(facesContext, "calcForm ");

Thanks,

Dhana

DhanaLaxmia at 2007-7-10 2:57:39 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...