Akheloes
Akheloes

Reputation: 1372

AJAX not firing in JSF

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 ?

Upvotes: 0

Views: 116

Answers (1)

BalusC
BalusC

Reputation: 1108557

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>

Upvotes: 3

Related Questions