0

I was taking a look at this question and tried to find an answer, I was trying, I made this code

JSF :

 <h:form id="form">
            <h:inputText id="text1" rendered="#{managedBean1.isRendered}"/>
            <h:outputLabel id="label1" rendered="#{!managedBean1.isRendered}" value="No"/> 
            <h:selectOneRadio value="#{managedBean1.option}"  >
                <f:selectItem itemValue="Yes" itemLabel="Yes" />
                <f:selectItem itemValue="No" itemLabel="No" />
                <f:ajax event="click" execute="@form" render="label1 text1" />
            </h:selectOneRadio>
        </h:form>

The bean :

@ManagedBean
@ViewScoped
public class ManagedBean1 implements Serializable {

    private boolean isRendered = false;
    private String option ;

    public void renderingMethod() {
        if(option.compareTo("Yes")==0) isRendered = true ;
        if(option.compareTo("No")==0) isRendered = false ;
    }

    public String getOption() {
        return option;
    }

    public void setOption(String option) {
        this.option = option;
    }

    public boolean isIsRendered() {
        return isRendered;
    }

    public void setIsRendered(boolean isRendered) {
        this.isRendered = isRendered;
    }


    /**
     * Creates a new instance of ManagedBean
     */
    public ManagedBean1() {
    }
}

Problem is it doesn't fire the ajax in the <h:selectOneRadio>, on the other hand it works just fine with a submit <h:commandButton>, why is that ? What am I missing ?

Community
  • 1
  • 1
Akheloes
  • 1,352
  • 3
  • 11
  • 28
  • What do you mean by *it's not working*? I don't see you execute the `renderingMethod` method anywhere in your ajax action (probably causing your problem). – Luiggi Mendoza Jun 11 '13 at 17:48
  • I've added a comment in that answer for both OP and answerer for providing wrong information for future readers. – Luiggi Mendoza Jun 11 '13 at 17:52
  • 1
    @Luiggi: OP isn't using the answerer's code. He just tried to figure at its own. Check the conditionally rendered components in OP's code. Related: http://stackoverflow.com/questions/9010734/why-do-i-need-to-nest-a-component-with-rendered-some-in-another-component-w/9010771#9010771 Answerer's code is doing it right in that case. – BalusC Jun 11 '13 at 17:54
  • Sorry for being late, @BalusC is right : didn't try to give an answer to that thread, just worked on it on my own (and stumbeled), so I thought why not ask. – Akheloes Jun 11 '13 at 22:00

1 Answers1

3

Ajax updating works roughly like this in JavaScript:

  • Find the element in HTML DOM by ID using document.getElementById(id).
  • Replace that element by new element as specified in ajax XML response.

However, if a JSF component does not render its HTML output, then there's nothing in the HTML DOM tree which can be found and replaced. You need to wrap conditionally rendered JSF components in a component whose HTML representation is always rendered and update it instead. The accepted answer of that question did exactly that right.

See also:


Unrelated to the concrete problem, comparing strings (and objects in general) by value should not be done by compareTo() method, but by equals() instead.

public void renderingMethod() {
    isRendered = option.equals("Yes");
}

(I'd by the way rename isRendered to rendered, it makes no sense to prefix them with is)

Even then, it's easier, less code and more self-documenting to do it entirely in EL.

<h:form id="form">
    <h:panelGroup id="group">
        <h:inputText id="text1" rendered="#{bean.option == 'Yes'}" />
        <h:outputLabel id="label1" rendered="#{bean.option == 'No'}" value="No" />
    </h:panelGroup>
    <h:selectOneRadio value="#{bean.option}"  >
        <f:selectItem itemValue="Yes" />
        <f:selectItem itemValue="No" />
        <f:ajax render="group" />
    </h:selectOneRadio>
</h:form>
Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • I somehow thought of this but I used a `
    ` tag to wrap the two rendered components, I guess it must be an `` tag for it work ? As for `equals` : doesn't it compare the String objects not their values (which can be dangereous at times) ?
    – Akheloes Jun 11 '13 at 22:13
  • It needs to be a JSF component because it needs to be findable by `UIViewRoot#findComponent()` in JSF side in order to get the updated content. As to equals, what you're describing is true for `obj1 == obj2`. So apparently you're confusing `==` with `equals`. – BalusC Jun 12 '13 at 09:49
  • I sure did confuse those, made some research about compareTo and equals and got to know the difference now. Would ask you one last question : I am using JSF 2.0 (server library is JSF 2.0 and registrated labraries is JSF 2.1, this is in NetBeans), and `` didn't work for me, replaced it with `` which did well, is it only a matter of JSF versions or is it something else ? – Akheloes Jun 12 '13 at 10:22
  • Sorry, I unintentionally mixed it with PrimeFaces, which I work daily with. I fixed the answer. The `update` is the PrimeFaces naming of `render`. – BalusC Jun 12 '13 at 10:25
  • Yep expected that but I thought maybe something I should be aware of, anyway thanks for the knowledge. – Akheloes Jun 12 '13 at 10:35