user1571780
user1571780

Reputation: 13

JSF 2: Ajax not firing in nested composite components

I have the main page with includes testcomponent1 which inturn includes testcomponent2. Ajax call is in testcomponent2. The call is intiated in the javascript but never hits the controller. If the ajax call is moved into testcomponent1, it triggers the call and makes it to the controller. I am including the test code for your reference.

TESTCONTROLLER:

import java.io.Serializable;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.AjaxBehaviorEvent;

@ManagedBean
@ViewScoped
public class TestController implements Serializable {
/** <code>serialVersionUID</code> */
private static final long serialVersionUID = -999213365169849345L;

private int customerkey;

private String customerName;

public void processKeyChange(AjaxBehaviorEvent e){
    System.out.println("I am in the Ajax method and my value is: " + customerkey);
}

//GETTERS AND SETTERS
public int getCustomerkey() {
    return customerkey;
}
public void setCustomerkey(int customerkey) {
    this.customerkey = customerkey;
}
public String getCustomerName() {
    return customerName;
}
public void setCustomerName(String customerName) {
    this.customerName = customerName;
}
}

testPage.xhtml

    <ui:define name="searchCriteria">
        <h:form id="orderHeaderForm" prependId="false">

            <h:panelGroup id="orderDiv" layout="block">
                <com:testcomponent1  id="testComponent1"
                                    customerKey="#{testController.customerkey}"
                                    customerName="#{testController.customerName}"/>

            </h:panelGroup>
        </h:form>
    </ui:define>

</ui:composition>

testcomponent1.xhtml

<cc:interface>
<cc:attribute name="customerKey" type="java.lang.Integer" />
<cc:attribute name="customerName" type="java.lang.String" />
</cc:interface>

<cc:implementation>
<h:panelGroup id="#{cc.clientId}" layout="block">
    <com:testcomponent2 id="testcomponent2" 
                key="#{cc.attrs.customerKey}"
                name="#{cc.attrs.customerName}" />

</h:panelGroup>
</cc:implementation>

testcomponent2.xhtml

<cc:implementation>
<h:panelGrid id="#{cc.clientId}" columns="2" border="0" cellspacing="0"     cellpadding="0">
    <h:outputLabel id="customerid" for="txtcustomerKey"/>
    <h:inputText id="txtcustomerKey" value="#{cc.attrs.key}" onchange="alert (document.getElementById(this.id).value)">
        <f:ajax event="change" listener="#{testController.processKeyChange}" execute="@this" render="txtCustomerName" />
    </h:inputText>
    <h:outputLabel id="customerName" for="txtCustomerName"/>
    <h:outputText value="#{cc.attrs.name}" id="txtCustomerName" />
</h:panelGrid>

</cc:implementation>

thanks

Upvotes: 1

Views: 606

Answers (2)

BalusC
BalusC

Reputation: 1109532

You shouldn't reassign #{cc.clientId} as ID of JSF components, but instead as ID of plain vanilla HTML elements such as <span> or <div>.

<span id="#{cc.clientId}">

or

<div id="#{cc.clientId}">

Upvotes: 0

lu4242
lu4242

Reputation: 2318

I think the problem is in <h:panelGrid id="#{cc.clientId}"...>. By default, a composite component is an instance of UINamingContainer, so instead do that, you can set an id with any name and use it. A good practice is avoid EL expressions in id field.

Upvotes: 1

Related Questions