JSF problem on submit event

Hi to everyone and sorry for my english,

i've created a web form using jsf tecnology.

This form contain 2 combo (selectOneMenu) one of this combo contain the region of Italy, so when an user select a region in this combo, on the second combo i'm load the city of this region, for make this i've an onChange event on the first combo this event meke a submit of form, i've also setted the property "immediate" = true.

So when the first combo chenge value if i've in the form a inputText with property required = "true" the form show me the error message "field required", but i've set immediate = "true"?

How i can bypass this problem.

Thanxs a lot,

Fabio.

[703 byte] By [fabdiba] at [2007-10-3 1:30:33]
# 1

Are you using a ValueChangeListener as well? You will need to.

Make sure that the combo box that submits the form (first one in your example) is the only component with immediate="true" set.

In the ValueChangeListener method, you need to include a call to renderResponse(). Like this:

//Force to render response phase so that any error messages DO NOT get

//displayed. i.e. Skip update model phase. Use immediate="true" on the

//component that calls this valueChangeListener so that it does not

//run any validation.

FacesContext.getCurrentInstance().renderResponse();

That should do it for you!

CowKing

IamCowKinga at 2007-7-14 18:28:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 2

Hi CowKing and thanks for your answers, i'm explain better my problem.

I've a typical form for user identifying, like name, surname ... and region and city where this user live and region and city where user was born.

So i've this situation on two combo (selectOneMenu) (region fire an event for load the respective city) so i don't use the ValueChangeListener the code of my combo is:

<h:selectOneMenu id="region1" value="#{userBean.selectedRegion1}" onchange="submit" immediate="true"> ...</h:selectOneMenu >

the city combo is:

<h:selectOneMenu id="city1" value="#{userBean.selectedCity1}"> ...</h:selectOneMenu >

i'm load the city in the get method of the bean from a DB.

The other two combo is like this (change id and bean property).

This combo function great if i don't have inputTextBox with property required="true".

So can you send me an example for solve this problem? I'm a newbe of this tecnology.

Thanks a lot, Fabio.

P.S. The immediate on a submit button don't vreate this validation problem ... why?

fabdiba at 2007-7-14 18:28:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 3

You should still use a value change listener. Putting db calls into your getters should be a last resort anyways. This is because JSF will call getters multiple times, thus causing you to make multiple DB calls.

Plus, if you don't call renderResponse(), you're going to continue seeing your error message. Setting the immediate attribute doesn't necessarily skip the validation phase, rather, it processes validation in the Apply Request Values phase.

Anyways, messing with the JSF phases can be a tricky concept for a newer person to understand. However, you should learn what you can about the standard JSF lifecycle.

Getting to your problem at hand... The quick version is that you need to create a value change listener, attach it to the first combo box (region1), configure the value change listener to retrieve the appropriate values from DB, then set the second combo box (city1) options, and then call renderResponse().

Here's some code to get you started.

In your jsp:

<h:selectOneMenu id="region1" value="#{userBean.selectedRegion1}"

onchange="submit" immediate="true"

valueChangeListener="#{userBean.regionSelected}">

...

</h:selectOneMenu >

In your UserBean class, create the following method:

public void regionSelected(ValueChangeEvent event)

throws AbortProcessingException {

//Get the selected region from the event

String region = (String)event.getNewValue();

//Set the selected region in your bean

setSelectedRegion(region);

//Call DB to retrieve the city list for the selected region

...

//Build Select Items list from record set

...

//Set the city list with the new select items

setCityList(newCityList);

//Force to render response phase so that any error messages DO NOT get

//displayed. i.e. Skip update model phase. Use immediate="true" on the

//component that calls this valueChangeListener so that it does not

//run any validation.

FacesContext.getCurrentInstance().renderResponse();

}

That should get you good and started.

CowKing

IamCowKinga at 2007-7-14 18:28:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 4

> P.S. The immediate on a submit button don't vreate [sic]

> this validation problem ... why?

This might be a little confusing, but I'll explain as best as I can. Remember how I mentioned that the immediate attribute doesn't "skip" validation, rather, that it processes everything in the Apply Request Values phase? Well, the same is true with commandLinks/commandButtons and components. However, the difference is in what happens when you click a button as opposed to firing an onchange submit from a component.

When the button is clicked, everything the button does is moved into the Apply Request Values phase. Including the process that calls the action. When JSF processes the action from the button, it renders the appropriate page and forwards the user to it. Thus skipping the remaining phases on ALL the other components on the page. Meaning that their validation is not run.

When a component is set to immediate, everything the component does is moved into the Apply Request Values phase as well. However, the component does not render the next page (or rerender the current page). So after the component is finished processing, JSF continues to execute all the other phases on all the other components. Including the validation phase. Thus, validation is run on the other components and could potentially fail.

That's why you need to tell JSF to skip to the renderResponse phase when processing the valueChangeListener. You effectively skip validation on all the other components, because you've forced the lifecycle phase past the validation phase.

Hope that doesn't confuse you further.

CowKing

IamCowKinga at 2007-7-14 18:28:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 5
Hi CowKing, thanks for your answers, but the problem is the same.If i set an inputText the property required = true the event in the combo it's never called, i don't know why.Can you help me for the last time?Thanks, Fabio.
fabdiba at 2007-7-14 18:28:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 6
I'm tryng better your code CowKing and it's work great, thanxs for your help and patience.If you come in Italy, you have a cofee payed :-)))Best Regards, Fabio.
fabdiba at 2007-7-14 18:28:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 7
> If you come in Italy, you have a cofee payed :-)))> > Best Regards, > Fabio.Haha! Thanks. =) I hope to see Italy some day, but not likely in the near future (so you can keep your coffee change ;-) ). Glad I could be of some help!CowKing
IamCowKinga at 2007-7-14 18:28:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 8

hi i am doin the same thing.but what the problem I am facing is...

suppose my first combo box contains India as first country name..

if I want to see the cities under India..then I cant..

because then second combo box is triggered when ever value is changed in the first combo box..

for the first time i cant get the values of cities..

what is the solution for that?

Ragowa at 2007-7-14 18:28:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 9

this one to related same operation

first combo box

<h:selectOneMenu id="cbProduct" value="#{OrderManagment.cbProduct}" immediate="true" onchange="submit()">

<f:selectItem itemLabel="Cash" itemValue="cash"/>

<f:selectItem itemLabel="Margin" itemValue="margin"/></h:selectOneMenu>

seccond one

<h:selectOneMenu id="cbOrder" value="#{OrderManagment.cbOrder}" >

<f:selectItems value="#{OrderManagment.items}"/>

</h:selectOneMenu>

in the bean class do like wise

List items = new ArrayList();

List margin=new ArrayList();

List cash=new ArrayList();

public constructor()

{

cash.add(new SelectItem("Buy"));

cash.add(new SelectItem("Sell"));

margin.add(new SelectItem("Buy"));

margin.add(new SelectItem("But To Cover"));

margin.add(new SelectItem("Sell"));

margin.add(new SelectItem("Short Sell"));

}

public List getItems() {

if("margin".equals(cbProduct)){

items=margin;

}

else

items=cash;

return items;

}

binusaumia at 2007-7-14 18:28:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 10
hi.this solution is fine, but in my case don磘 work :(.I have more than 2 combo in cascade and all is requiered. what solution to this problem ?
ybendeka at 2007-7-14 18:28:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...