0

I have a h:selectOneMenu, and when its value changes to specific value (say "2"), it supposes to show hidden fields then(which hasn't been rendered). Noting that they are linked to the same value of a property in the managed bean.

<h:outputText value="Function:"></h:outputText>
<h:selectOneMenu id="funDrp" converter="FunctionConv" value="#{cardBean.card.functionId}">
    <f:selectItems value="#{commonData.functions}" var="c" itemLabel="#{c.description}" itemValue="#{c.functionId}" />
    <f:ajax render="@form" execute="@form" event="valueChange" />
</h:selectOneMenu>

<h:outputText value=" Profile Id:" rendered="#{(cardBean.card.functionId.functionId==2)}"></h:outputText>
<h:inputText id="card_refillProfileId"rendered="#{(cardBean.card.functionId.functionId==2)}" label="Refill Profile Id" required="true" value="#{cardBean.card.refillProfileId}"></h:inputText>

<h:outputText value="Origin Type:" rendered="#{(cardBean.card.functionId.functionId==2)}"></h:outputText>
<h:inputText id="card_originType" rendered="#{(cardBean.card.functionId.functionId==2)}" label="Origin Node Type" required="true" value="#{cardBean.card.originType}"></h:inputText>

They works fine if the "card" object is assigned to an existing entity, but if it is a new one - it doesnt work as expected.

Marwa Dosoky
  • 406
  • 7
  • 19

4 Answers4

0

This is a fully anticipated behaviour. Using <f:ajax> you can rerender HTML elements that are present in your DOM, but by specifying rendered="false" in your JSF components they won't appear in your DOM. And, as ajax needs to find the element by its id, and replace it afterwards, this job apparently can't be done.

Your job, however, can be handled by embracing your components (all of which use the rendered attribute) in a container, for example in <h:panelGroup id="to-be-rerendered">, which is always rendered, but its children - not. Thus, ajax will be able to rerender the panel which will include all of your components with rendered="true" if the condition is met, and they will appear in your view.

As a side note, your ajax behaviour might be very expensive if your view/form grows. So, if all you want is to rerender some components, specify it in your <f:ajax> tag: <f:ajax render="to-be-rerendered" /> (a list of space-separated ids of components to be rendered).

skuntsel
  • 11,624
  • 11
  • 44
  • 67
  • OP is using `render="@form"`, so I don't see a problem. – BalusC Feb 21 '13 at 12:09
  • @BalusC I didn't mean it is a problem, but I wanted to point Marwa's attention towards escaping unnesessary renders because it unnecessarily increases the ajax response size. – skuntsel Feb 21 '13 at 12:13
0

The problem was that the value attached to the select one menu was null "card.functionId" .so initializing it just before checking it.as i have tried to initialize it before constructing the bean but it didnt help.

so to do that , initialization was done by attaching a "ValueChangeListener" for the selectOneMenu

<h:selectOneMenu id="funDrp" converter="FunctionConv" valueChangeListener="#     {cardBean.changeCardFunc}"
                                            value="#{cardBean.card.functionId}">
                                            <f:selectItems value="#{commonData.functions}" var="c"
                                            itemLabel="#{c.description}" itemValue="#{c.functionId}" />
                                            <f:ajax render="@form" execute="funDrp" event="change" />
                                          </h:selectOneMenu>

and in the Managed Bean:

public void changeCardFunc(ValueChangeEvent e) {
//  object newFunc= e.

    if(card!=null){
    card.setFunctionId((Function)e.getNewValue());
    }else {
        card= new Card();
        card.setFunctionId((Function)e.getNewValue());
        System.err.println(e.getNewValue());
    }
}
Marwa Dosoky
  • 406
  • 7
  • 19
-1

try

<f:ajax render="card_refillProfileId card_originType" execute="@form" event="valueChange" />
psi
  • 269
  • 2
  • 13
  • I cant render something that doesnt exist http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html#AjaxRenderingOfContentWhichIsByItselfConditionallyRendered – Marwa Dosoky Feb 21 '13 at 10:13
-1

Your

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

Should be (event can be omitted)

<f:ajax render="@form" execute="@form" event="change" />

It seems there is mismatch between selectOneMenu.value, your converter and the rendered EL. There is twice functionId.functionId. And selectOneMenu.value is bind to cardBean.card.functionId. I may be wrong if functionId is a function.

Nicolas Labrot
  • 4,017
  • 25
  • 40
  • They works fine if the "card" object is assigned to an existing entity it works fine ,but if it a new one it doesnt – Marwa Dosoky Feb 21 '13 at 10:14
  • What do you mean by `if the "card" object is assigned to an existing entity`? Do you mean if `cardBean.card` is initialized ? – Nicolas Labrot Feb 21 '13 at 10:38
  • well I have initialized it everywhere, when i declare it and in @PostConstructor but that didnt solve it – Marwa Dosoky Feb 21 '13 at 12:01
  • `valueChange` event is valid. Even more, it's the default event of ``. It can even be omitted altogther. See also http://stackoverflow.com/questions/7886453/what-values-can-i-pass-to-the-event-attribute-of-the-fajax-tag/7889098#7889098 – BalusC Feb 21 '13 at 12:11
  • @MarwaDosoky I do not have enough information on the code context to help you. – Nicolas Labrot Feb 21 '13 at 13:20
  • The problem was in the initialization , i have solved with something else i am gonna write it down – Marwa Dosoky Feb 21 '13 at 15:20