1
votes

I have problem with converting this code from JSF 1.2 application to equivalent in JSF 2.x application

<h:selectOneMenu id="type" value="#{bean.type}">
    <f:selectItems value="#{bean.typeList}"/>
    <a4j:support event="onchange"
                 ajaxSingle="false"
                 immediate="true"
                 reRender="myForm">
        <a4j:actionparam name="type" 
                         value="this.value" 
                         assignTo="#{bean.type}" 
                         noEscape="true"/>
    </a4j:support>
</h:selectOneMenu>

How this code snippet works.

Depending on selected value in #{bean.type}, my page display different fields. When User change "type" field the whole form is rerendered, but without form validation (ajaxSingle="false", immediate="true", reRender="myForm").

I don't want to validate filds here, I just want to set new value to the #{bean.type} and rerender the page in order to show different fields (depending on #{bean.type}). Thats why i need to manualy set #{bean.type} inside a4j:actionparam.

The nice feature about this code is that submited values in other fileds are preserved after rerendering.

I am trying to do the same thing in JSF 2.x with no success:

<h:selectOneMenu iid="type" value="#{bean.type}">
    <f:selectItems value="#{bean.typeList}"/>
    <a4j:ajax event="valueChange" render="@form" execute="@this"/>
</h:selectOneMenu>

This:

<a4j:ajax event="valueChange" render="@form" execute="@this"/>

will rerender whole form and I will lose submited values form other fields

This:

<a4j:ajax event="valueChange" render="@form" execute="@form"/>

will submit, validate and rerender whole form (i want just submit without validation like in JSF 1.2)

This:

<a4j:ajax event="valueChange" render="@form" execute="@form" immediate="true"/>

also does not work (work same as above)

So my question is how can I achive the same behavior in JSF 2.x ?

Thanks

1
Since you have fields in the form you don't want to be rerendered why are you rerendering the whole form in the first place? - Makhiel
Makhiel i want to rerender whole form to show different fields depending on selected value in type field . Some fileds are rendered always, and some only for special types (its very dynamic). And i want to preserve any values that user entered in any field that is still visible after rerendering. - bary
Well, rerendering simply replaces the elements, so unless you save the values locally they will be lost. Wouldn't this be better solved entirely on the client side, hiding/showing the fields with JavaScript? - Makhiel
This works fine with JSF 1.2 and RichFaces 3.x. where a4j:support with ajaxSingle="false" immediate="true" submit whole form and sets submited values in components (skiping validation and update model phase) so after rerendering values in other fields are not lost. I am simply looking for equivalent funcionality in JSF 2.x and RichFaces 4.x - bary
@bary After looking deeper - immediate="true" actually skips validation, but execute="@form" brings it back. Adding listener="#{facesContext.renderResponse}" to a4j:ajax may help. - Andrey

1 Answers

0
votes

Thanks to Andrey comment I found solution:

<h:selectOneMenu id="type"
                 value="#{bean.type}"
                 valueChangeListener="#{bean.typeChangeListener}"
                 immediate="true">
    <f:selectItems value="#{bean.typeList}"/>
    <a4j:ajax execute="@form" render="@form" listener="#{facesContext.renderResponse}" immediate="true"/>
</h:selectOneMenu>

and:

public void typeChangeListener(ValueChangeEvent event) {
  type = (String) event.getNewValue();
}

immediate on a4j:ajax causes that listener="#{facesContext.renderResponse}" is called during apply request values phase, and renderResponse skips validation.

immediate on h:selectOneMenu causes that valueChangeListener is also called during apply request values phase.

So I can submit whole form without validation, set type, rerender new fields based on changed type, and preserve submited values in other fileds.