Question

Can anyone tell me how to automatically set <h:selectOneMenu> (or any other component) with values depending on another <h:selectOneMenu> if there empty elements with 'required' set to 'true' on the form? If to set <a4j:support event="onchange" reRender="anotherElement" immediate="true" /> then nothing is changed because changed value isn't set. But without immediate="true" I always have message that this or that element cannot be empty. Here's code example that doesn't work.

<h:outputLabel value="* #{msg.someField}: "/>
<h:panelGrid cellpadding="0" cellspacing="0">
    <h:selectOneMenu id="someSelect"
            value="#{MyBean.someObj.someId}"
            required="true" label="#{msg.someField}"
            >
        <a4j:support event="onchange" reRender="anotherSelect" limitToList="true" immediate="true"/>
        <f:selectItem itemValue=""/>
        <f:selectItems value="#{MyBean.someList}"/>
    </h:selectOneMenu>
    <rich:message for="someSelect" styleClass="redOne"/>
</h:panelGrid>

<h:outputLabel value="* #{msg.anotherField}: "/>
<h:panelGrid cellpadding="0" cellspacing="0">
    <h:selectOneMenu id="anotherSelect"
            value="#{MyBean.someObj.anotherId}"
            required="true" label="#{msg.anotherField}"
            >
        <f:selectItem itemValue=""/>
        <f:selectItems value="#{MyBean.anotherList}"/>
    </h:selectOneMenu>
    <rich:message for="anotherSelect" styleClass="redOne"/>
</h:panelGrid>

<h:outputLabel value="* #{msg.name}: "/>
<h:panelGrid cellpadding="0" cellspacing="0">
    <h:inputText id="myName" value="#{MyBean.someObj.myName}" 
            required="true" label="#{msg.name}"/>
    <rich:message for="myName" styleClass="redOne"/>
</h:panelGrid>

So, here (I repeat), if I try to change 'someSelect' then 'anotherSelect' should update its values but it doesn't because either when it tries to get value of 'someSelect' it gets null (if immediate set to true) or form validation fails on empty elements. How can I skip validation but get this changed value from 'someSelect'?

Was it helpful?

Solution

Have you tried adding ajaxSingle="true" to the someSelect a4j:support element? Remove the immediate="true"

OTHER TIPS

The following solution works in JSF 2.0

<h:outputLabel
    value="* Country: "/>
<h:selectOneMenu
    id="someSelect"
    value="#{testController.countryName}"
    required="true">
    <f:selectItem
        itemLabel="Select Country"
        itemValue=""/>
    <f:selectItems
        value="#{testController.countryNamesSelectItems}"/>
    <!-- This will only update "someSelect" and repaint "anotherSelect" -->
    <f:ajax
        execute="@this"
        render="anotherSelect"/>
</h:selectOneMenu>

<h:outputLabel
    value="* State: "/>
<h:selectOneMenu
    id="anotherSelect"
    value="#{testController.stateName}"
    required="true">
    <f:selectItem
        itemLabel="Select State"
        itemValue=""/>
    <f:selectItems
        value="#{testController.stateNamesSelectItems}"/>
</h:selectOneMenu>

The f:ajax call will submit an ajax request to the server onchange of "someSelect". The model update for only the "someSelect" component will happen (because of execute="@this"). In the render response phase, only "anotherSelect" will be re-rendered (thus invoking testController.stateNamesSelectItems with the updated country name).

As a result of all this, the states of the selected country will get updated as an when country is changed...the ajax way.

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top