valueChangeListener

Hello,

i'm struggling with JSF.

inside the jsp page there is list of client types, if the user selects some value, then in output fields have to be shown details of this client type.

<t:selectOneMenu

value="#{testapp_clients.filterClient.id}"

styleClass="largeInputField"

valueChangeListener="#{testapp_clients.searchDetails}"

onchange="this.form.submit()" immediate="true">

<f:selectItems value="#{testapp_clients.listClientTypes}" />

</t:selectOneMenu>

publicvoid searchDetails(ValueChangeEvent e)throws Exception{

setFilterClient(searchForClientDetails(e.getNewValue()));

}

But this is not working! The values are not changed.

Only if add these lines of code in end of searchDetails method its working! Why!?

ViewHandler viewHandler = JSFUtil.getFacesContext().getApplicatio.getViewHandler();

UIViewRoot viewRoot = viewHandler.createView(JSFUtil.getFacesContext(),

JSFUtil.getFacesContext().getViewRoot().getViewId());

JSFUtil.getFacesContext().setViewRoot(viewRoot);

JSFUtil.getFacesContext().renderResponse();

[1459 byte] By [Roberts_Va] at [2007-11-27 9:13:04]
# 1

The reason it works when you add the additional code is because you call the renderResponse() method. Thus skipping to the renderResponse phase. The only thing that makes the difference in the additional code is that call.

If you don't skip ahead in the JSF lifecycle after changing values from the valueChangeListener, then the old values are re-set.

When the valueChangeListener runs, the component value has not been altered like you might think. Only the bean value has been altered. Thus, JSF gets to the Update Model phase, and copies the component value into the bean. Unfortunately, the component value is the previous value that was in the bean when the lifecycle began (i.e. before your valueChangeListener ran).

Hope this makes some sense. The bottom line is that the old value overwrites the new one, unless you purposefully skip to the renderResponse phase. It is designed this way and is working correctly.

CowKing

IamCowKinga at 2007-7-12 22:00:08 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 2
Thx you!But i don't really understand, why value-changed events are handled before update-model phase and is it possible that value-changed events are handled after update-model phase (like action-events)
Roberts_Va at 2007-7-12 22:00:09 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 3

There the ValueChangeEvent is not intented for. It is intented to be called right before the update model values phase, while the old value is still available. If you want to process actions after ValueChangeEvent, then just set some toggle and don't skip the invoke application phase using FacesContext#renderResponse(). Or just put the logic in the ValueChangeListener method.

BalusCa at 2007-7-12 22:00:09 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 4

and this will be the way - to move value change event to the update-model phase:

PhaseId phase = e.getPhaseId();

if (phase.equals(PhaseId.APPLY_REQUEST_VALUES)) {

e.setPhaseId(PhaseId.UPDATE_MODEL_VALUES);

e.queue();

}

if (phase.equals(PhaseId.UPDATE_MODEL_VALUES)) {

//code

}

Roberts_Va at 2007-7-12 22:00:09 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...