f:ajax not rendering h:selectManyListbox - ajax

Using f:ajax component with h:selectManyListbox, it is firing the listener method but not refreshing the rendering list.
I have Market. When I select market it needs to display Sub-Markets. Initial page load will have all the Markets and Sub-Markets, but it needs to filter when user selects "Market".
Using below code:
<ui:fragment id="uda2" rendered="#{udaList.index eq 1}">
<div class=" row form-group" >
<label class="col-sm-2" for="sel-service">Market:</label>
<div class="col-sm-10">
<h:selectManyListbox style="width:360px;" multiple="" pt:aria-required="true" required="required" pt:data-toggle="chosen"
disabled="# {licenseSelectionBean.isFieldEnabled(FormFieldsEnum.ITEM_UDA2)}"
id="#{FormFieldsEnum.ITEM_UDA2.getFieldCode()}" size="1"
name="#{FormFieldsEnum.ITEM_UDA2.getFieldCode()}"
value="#{licenseSelectionBean.selectedItemUda2}"
styleClass="sel-chosen">
<f:selectItems var="uda2"
value="#{licenseSelectionBean.selectUda2}" />
<f:ajax event="change" execute="#this" render="#this udalist3"
listener="#{licenseSelectionBean.onChangeFilter()}" />
</h:selectManyListbox>
</div>
</div>
</ui:fragment>
<ui:fragment rendered="#{udaList.index eq 2}">
<div class="row form-group" >
<label class="col-sm-2" for="sel-service">Sub-Market:</label>
<div class="col-sm-10">
<h:selectManyListbox style="width:360px;" multiple="" pt:aria-required="true" required="required" pt:data-toggle="chosen"
disabled="#{licenseSelectionBean.isFieldEnabled(FormFieldsEnum.ITEM_UDA3)}"
size="1"
pt:name="udalist3"
value="#{licenseSelectionBean.selectedItemUda3}"
pt:id="udalist3"
styleClass="sel-chosen">
<f:selectItems var="uda3"
value="#{licenseSelectionBean.selectUda3}" />
<!-- <f:ajax render="#{FormFieldsEnum.ITEM_UDA4.getFieldCode()}"
listener="#{licenseSelectionBean.onChangeFilter()}" /> -->
</h:selectManyListbox>
</div>
</div>
</ui:fragment>
Used "pt" for pass-through because JSF prefixing dynamic id.
How to resolve this problem?

Simple solution. Replace
<f:ajax event="change" execute="#this" render="#this udalist3"
listener="#{licenseSelectionBean.onChangeFilter()}" />
with
<f:ajax event="change" execute="#this" render="#form"
listener="#{licenseSelectionBean.onChangeFilter()}" />
This might cause some unnecesarry traffic. You can also encapsulate the second ui:fragment in a panelgroup, e.g.
<h:panelGroup id="wrapper">
<ui:fragment rendered="#{udaList.index eq 2}">
....
</h:panelgroup>
and add replace "udalist3" with "wrapper" in the f:ajax render attribute.

Related

JSF Primefaces input values reset upon SelectOnemenu

The entered input values reset upon manually selecting the values of selectOneMenu id="format"
The render of selectOneMenu id="format" works fine. But upon selection of the drop down values of selectOneMenu id="format" the entered field input values are blank.
Page
Employee name[Mark] Employee Type [New]
Format [Select some drop down value]
.
Current Output
Employee name[Entered Value Disappeared/null] Employee Type [Selected value disappeared/null]
Format [Selected some drop down value]
Expected Output
Employee name[Mark] Employee Type [New]
Format [Selected Value]
.
I have tried to add
<p:ajax event="valueChange" immediate="true" process="#form" />
The rendering fails if I add it for the selectOneMenu
I have the code below
main.xhtml
<h:form id="newFormBank" enctype="multipart/form-data">
<h:panelGroup id="id">
<p:growl id="growl" sticky="true" showDetail="true" />
<p:wizard id="newBankWizard" showNavBar="true" widgetVar="bankWiz" flowListener="#{javaMB.wizardFlow}">
<p:tab id="pro" title="Banks">
<ui:include src="/jsf/xyz.xhtml" />
<ui:include src="/jsf/employeeloan.xhtml" />
</p:tab>
</p:wizard>
</h:panelGroup>
</h:form>
employeeloan.xhtml
<p:panel id="employeeLoan" styleClass="panelNoBorder">
<div class="ui-g"> <div class="ui-g-1"><p:outputLabel value="Employee Name" /></div>
<div class="ui-g-3"> <p:row> <p:inputText id="employeeName" maxlength="50" style="width: 65%;" value="#{javaMB.visaDetailsEntity.employeeName}" > </p:inputText> </p:row> </div>
<div class="ui-g-1"><p:outputLabel value="Employee Type" /></div>
<div class="ui-g-3">
<p:row> <p:selectOneMenu id="employeeTypeList" value="#{javaMB.visaDetailsEntity.employeeTypeCode}" >
<f:selectItem itemLabel="Select Release Type" itemValue=""> </f:selectItem>
<f:selectItem itemLabel="New" itemValue="1" />
<f:selectItem itemLabel="Existing" itemValue="2" /> </p:selectOneMenu> </p:row> </div> </div>
<div class="ui-g"> <div class="ui-g-1"><p:outputLabel value="CREDIT" /></div>
<div class="ui-g-3">
<p:row>
<p:selectOneMenu id="format" value="javaMB.visaDetailsEntity.visaType.visaId">
<f:selectItem itemLabel="VISA" itemValue="1" />
<f:selectItem itemLabel="MASTER CARD" itemValue="2" />
<f:selectItem itemLabel="DISCOVER" itemValue="3" />
<f:selectItem itemLabel="AMERICAN EXPRESS" itemValue="4" />
<f:ajax render="#form" />
</p:selectOneMenu>
</p:row>
</div>
</div>
<div class="ui-g">
<div class="ui-g-1"><p:outputLabel value="VISA" rendered="#{javaMB.visaDetailsEntity.visaType.visaId == '1'}"/></div>
<div class="ui-g-3"> <p:row>
<p:inputText id="visaeg" maxlength="9" size="30" value="#{javaMB.visaDetailsEntity.malaustin}" label="VISA1" rendered="#{javaMB.visaDetailsEntity.visaType.visaId == '1'}">
</p:inputText>
</p:row>
</div>
<div class="ui-g-1"><p:outputLabel value="VISA" rendered="#{javaMB.visaDetailsEntity.visaType.visaId == '1'}"/></div>
<div class="ui-g-3">
<p:row>
<p:inputText id="visaegg" maxlength="11" size="30" value="#{javaMB.visaDetailsEntity.malecinyc}" label="VISA2" onchange="negateLongitude()" rendered="#{javaMB.visaDetailsEntity.visaType.visaId == '1'}">
</p:inputText>
</p:row>
</div>
</div>
<div class="ui-g">
<div class="ui-g-1"><h:outputLabel value="MASTER CARD" style="overflow: hidden" rendered="#{javaMB.visaDetailsEntity.visaType.visaId == '3'}"/></div>
<div class="ui-g-3">
<p:row>
<p:inputText id="masterd" maxlength="7" size="30" value="#{javaMB.visaDetailsEntity.atepmo}" rendered="#{javaMB.visaDetailsEntity.visaType.visaId == '3'}">
</p:inputText>
</p:row>
</div>
<div class="ui-g-1"><h:outputLabel for="masterdt" value="MASTER CARD DETAILS" rendered="#{javaMB.visaDetailsEntity.visaType.visaId == '3'}"/></div>
<div class="ui-g-3">
<p:row>
<p:inputText id="datilsmast" maxlength="8" size="30" value="#{javaMB.visaDetailsEntity.atepllanyc}" rendered="#{javaMB.visaDetailsEntity.visaType.visaId == '3'}">
</p:inputText>
</p:row>
</div>
</div>
<div class="ui-g">
<div class="ui-g-1"><h:outputLabel value="DISCOVER" rendered="#{javaMB.visaDetailsEntity.visaType.visaId == '4'}"/></div>
<div class="ui-g-3">
<p:row>
<p:inputText id="ltdiscover" maxlength="2" size="30" value="#{javaMB.visaDetailsEntity.egrssfo}" rendered="#{javaMB.visaDetailsEntity.visaType.visaId == '4'}">
</p:inputText>
</p:row>
</div>
<div class="ui-g-1"><h:outputLabel value="DISCOVER Details" rendered="#{javaMB.visaDetailsEntity.visaType.visaId == '4'}"/></div>
<div class="ui-g-3">
<p:row>
<p:inputText id="lodiscover" maxlength="4" size="30" value="#{javaMB.visaDetailsEntity.eongtx}" rendered="#{javaMB.visaDetailsEntity.visaType.visaId == '4'}">
</p:inputText>
</p:row>
</div>
</div>
<div class="ui-g">
<div class="ui-g-1"><h:outputLabel value="AExp AZ" rendered="#{javaMB.visaDetailsEntity.visaType.visaId == '2'}"/></div>
<div class="ui-g-3">
<p:row>
<p:inputText id="azaexp" maxlength="2" size="30" value="#{javaMB.visaDetailsEntity.aexpaz}" rendered="#{javaMB.visaDetailsEntity.visaType.visaId == '2'}">
</p:inputText>
</p:row>
</div>
<div class="ui-g-1"><h:outputLabel value="AExp FL" rendered="#{javaMB.visaDetailsEntity.visaType.visaId == '2'}"/></div>
<div class="ui-g-3">
<p:row>
<p:inputText id="flaexp" maxlength="4" size="30" value="#{fvLocationMB.coordinateForm.aexpazfl}" rendered="#{javaMB.visaDetailsEntity.visaType.visaId == '2'}">
</p:inputText>
</p:row>
</div>
</div>
</div>
</p:fieldset>
</p:panel>
</ui:composition>
javaMB
getters setters
Entity
getters setters
Your p:ajax statement is wrong, it should probably read something like:
<p:ajax event="valueChange" update="#form" />
Find an exhaustive explanation of the inner workings here:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes

ajax validation error message [duplicate]

This question already has an answer here:
Custom JSF validator message for a single input field
(1 answer)
Closed 7 years ago.
how to add my own message for the client side validation in JSF.
<div class="ui-grid-row">
<div class="ui-grid-col-3" align="left">
<h:outputLabel for="cmpny" value="Company Name:" style="font-weight:bold" />
</div>
<div class="ui-grid-col-2">
<p:inputText id="cmpny" value="#{userData.cmpny}">
<f:validateLength minimum="10" />
<p:ajax execute="currentInput" update="company" event="blur" />
</p:inputText>
</div>
<div class="ui-grid-col-1" />
<div class="ui-grid-col-1">
<p:message for="cmpny" id="company" display="icon" />
</div>
<div class="ui-grid-col-5"></div>
</div>
</div>
<div class="ui-grid-col-3" align="left">
<h:outputLabel for="fnm" value="First Name:*" />
</div>
<div class="ui-grid-col-2">
<p:inputText id="fnm" value="#{userData.fnm}" validatorMessage="First Name cannot be left blank and must be greater than 3 characters" >
<f:validateLength minimum="4" />
<p:ajax execute="currentInput" update="firstname" event="blur" process="#this" />
</p:inputText>
</div>
<div class="ui-grid-col-7"><p:message for="fnm" id="firstname" display="icon,text"/></div>
With the help of "validatorMessage" attribute, I am able to show customized messages when ever the validation fails for the primeface elements like (inputText,calendar etc..,),.
You need to supply a message bundle via javascript. See PrimeFacesLocales for examples.
PrimeFaces User Guide, 7. Client Side Validation / 7.4 Messages.

Redirecting with return statement influences the rendering process in next page

I have a problem with the rendering of a datatable.
In my application I have this navigation bar:
<h:form>
<ul class="nav nav-tabs">
<li class="active" role="presentation">
<h:commandLink value="Veranstaltungen" action="#{eventController.redirect('veranstaltung.xhtml')}"/>
</li>
<li role="presentation">
<h:commandLink value="Beacons" action="#{beaconcontroller.redirect('beacon.xhtml')}"/>
</li>
[...]
</ul>
</h:form>
Redirect (beaconcontroller):
public String redirect(String link) {
beacons = database.getAllBeacons();
return "./" + link;
}
The navigation works perfectly, but when I submit the form beaconData in the beacon.xhtml my datatable won't be rendered.
<h:form id="beaconsTable">
<p:dataTable value="#{beaconcontroller.beacons}" var="b"
tableStyleClass="table table-striped"
emptyMessage="Keine Beacons verfügbar"
style="font-size:14px"
rowIndexVar="rowIndex"
rowStyleClass="#{(rowIndex mod 2) eq 0 ? 'first-row' : 'second-row'}"
>
<p:column style="float:left;border:none;">
<f:facet name="header">
<h:commandLink actionListener="#{beaconcontroller.sortBeacons}">
<f:ajax execute="#this" render="beaconsTable"/>
Beacons
</h:commandLink>
</f:facet>
<h:commandLink>
<f:ajax listener="#{beaconcontroller.fillFields(b)}" execute="#this" render=":beaconData beaconsTable :delete"/>
<h:outputText value="#{beaconcontroller.getCompleteString(b)}" style="#{beaconcontroller.currentBeacon == b ? 'color:#337AB7' : 'color:#555555'}"></h:outputText>
</h:commandLink>
</p:column>
</p:dataTable>
</h:form>
</div>
<div class="col-lg-6">
<h:form role="form" id="beaconData" enctype="multipart/form-data">
<div class="form-group">
<label>UUID*</label>
<h:inputText id="id_uuid" binding="#{uuidAttribute}" class="form-control" value="#{beaconcontroller.uuid}" p:placeholder="Unternehmen" required="true" requiredMessage="Bitte UUID angeben" validatorMessage="Bitte nur Zahlen und Buchstaben angeben">
<f:validateRegex pattern="[0-9a-zA-Z]+"/>
</h:inputText>
<h:message styleClass="errMessage" for="id_uuid" style="color: red"/>
</div>
[...]
<h:commandButton type="submit" value="Speichern" actionListener="#{beaconcontroller.saveData}" class="btn btn-primary" disabled="#{beaconcontroller.currentBeacon == null}">
<f:ajax render="beaconData :beaconsTable" execute="#form"/>
</h:commandButton>
</h:form>
</div>
Clicking on an other entry in the datatable, solves the problem. Then the table will be rendered on submit. But why dosen't it work on the first time?
When I now change action="#{beaconcontroller.redirect('beacon.xhtml')}" in the navigation bar to action="beacon.xhtml" it works all correct. I thought these expressions are meaning the same?

AJAX on an included page through AJAX

I have a page in which through AJAX I include other pages conditionally. On one included page I would like to do another ajax call.
My initial page:
<ui:composition template="../../templates/template.xhtml">
<ui:define name="title">
Pay
</ui:define>
<ui:define name="content">
<h:form>
<div id="loginDiv">
<div class="homeDiv" style="text-align: left;">
<h:form>
<h:outputText value="#{strings.paymentMainSpeech} " />
<ul id="grileList">
<li>#{strings.payThroughSMS}</li>
<li>#{strings.payThroughCard}</li>
<li>#{strings.payThroughPayPal}</li>
</ul>
<h:outputText value="#{strings.bellowYouHavePaymentOptions}" />
</h:form>
</div>
<h:selectOneRadio value="#{payment.option}" immediate="true">
<f:selectItem itemValue="#{strings.payThroughSMS}"
itemLabel="#{strings.payThroughSMS}" />
<f:selectItem itemValue="#{strings.payThroughCard}"
itemLabel="#{strings.payThroughCard}" />
<f:selectItem itemValue="#{strings.payThroughPayPal}"
itemLabel="#{strings.payThroughPayPal}" />
<f:ajax event="change" listener="#{payment.changeListener()}"
render="payment" />
</h:selectOneRadio>
</div>
<h:panelGroup id="payment">
<!-- PayPal -->
<h:panelGroup rendered="#{payment.option == 'PayPal'}">
<ui:include src="../payments/paypal/paypal.xhtml" />
</h:panelGroup>
<!-- CARD -->
<h:panelGroup rendered="#{payment.option == 'Card'}">
<ui:include src="../payments/card/mobilPay.xhtml" />
</h:panelGroup>
</h:panelGroup>
</h:form>
</ui:define>
I select from the radio buttons the pages which I want to include through an ajax listener. That works well.
On one included page (on mobilPay.xhtml)
<ui:composition>
<ui:define name="title">
Pay Card Mobil Pay
</ui:define>
<div id="loginDiv">
<h:panelGroup id="next">
<h:panelGroup rendered="#{not mobilPayInitBean.forward}">
<h:outputText value="#{strings.paymentSpeech} " />
<h:outputText value="#{strings.paymentSpeech} " />
<h:outputText value=" #{strings.paymentSpeech2}" />
<br />
<br />
<h:form>
<h:selectOneMenu value="#{mobilPayInitBean.options}">
<f:selectItem itemValue="five" itemLabel="#{strings.fiveEuro}" />
<f:selectItem itemValue="seven" itemLabel="#{strings.sevenEuro}" />
<f:selectItem itemValue="ten" itemLabel="#{strings.tenEuro}" />
</h:selectOneMenu>
<br />
<br />
<f:ajax render="next">
<h:commandButton value="#{strings.nextStep}"
action="#{mobilPayInitBean.nextStep()}"
rendered="#{not mobilPayInitBean.forward}" />
</f:ajax>
</h:form>
</h:panelGroup>
<h:panelGroup rendered="#{mobilPayInitBean.forward}">
<div id="loginDiv">
<form name="frmPaymentRedirect" method="post"
action="#{mobilPayInitBean.paymentURL}">
<input type="hidden" name="env_key"
value="#{mobilPayInitBean.paymentURL}" /> <input type="hidden"
name="data" value="#{mobilPayInitBean.paymentURL}" />
<p>
If not reditect in 5 seconds <input type="image"
src="images/12792_mobilpay-96x30.gif" />
</p>
</form>
</div>
<script type="text/javascript" language="javascript">
window.setTimeout(document.frmPaymentRedirect.submit(), 3000);
</script>
</h:panelGroup>
</h:panelGroup>
</div>
I want to select from the select one menu an item and click on the command button and I want the whole selectonemenu and the command button to disaper and the last form (name="frmPaymentRedirect")to appear.
Now the problem:
I include the mobilPay.xhtml page and the whole page with the radiobuttons and the mobilPay.xhtml page appears, BUT when I click on the command button the hole mobilPay.xhtml disappears and so does the selection in the radio button.
Thank you for your time.
It was the nested forms!!!
I used a master template -> child template -> included page.
In the child template a had a form and inside the form I inserted the pages and in the one inserted page I had another set of form.
Thank you for pointing that obvious thing out!!!

AJAX within nested JSF Composite Component

I'm having a bit of trouble getting AJAX calls to fire properly in a nested composite component with Mojarra 2.0.3 and PrimeFaces.
The child composite component looks something like this:
<cc:interface componentType="therapy">
<cc:attribute name="therapyType" type="java.lang.String" required="true"/>
<cc:attribute name="patientId" type="java.lang.String" required="true"/>
<cc:attribute name="showHistory" type="java.lang.Boolean" required="false" default="true"/>
<cc:attribute name="width" type="java.lang.String" required="false" default="350px"/>
<cc:attribute name="maxHistory" type="java.lang.String" required="false" default="3"/>
<cc:attribute name="collectDoctor" type="java.lang.Boolean" required="false" default="false"/>
<cc:attribute name="collectCareDate" type="java.lang.Boolean" required="false" default="false"/>
<cc:attribute name="important" type="java.lang.Boolean" requred="false" default="false"/>
</cc:interface>
<cc:implementation>
<script>
function #{cc.clientId}Toggle(){
$("##{cc.clientId}_newbutton").toggle();
$("##{cc.clientId}_savebuttons").toggle();
if(#{cc.attrs.collectDoctor}){
$("##{cc.clientId}_doctor").toggle();
}
if(#{cc.attrs.collectCareDate}){
$("##{cc.clientId}_care").toggle();
}
$("##{cc.clientId}_newTherapy").toggle(50);
}
function #{cc.clientId}rowHighlight(event){
if(event.status == 'begin'){
$("##{cc.clientId}_loader").toggle();
}
if(event.status == 'success'){
$("##{cc.clientId}\\:histTable tr:eq(1)").effect("highlight", {color:"#FED17A", easing:"easeInCubic"}, 2000);
}
}
$(function(){
if(#{cc.attrs.important}){
$("div[class~='ui-panel-titlebar'][id^='#{cc.clientId}']").css("background", "#FED17A");
}
});
</script>
<h:form prependId="false">
<p:panel styleClass="mcoPanel" style="width:#{cc.attrs.width};">
<f:facet name="header">
<h:panelGroup>
<span id="#{cc.clientId}_title">#{cc.myType.word}</span>
<span id="#{cc.clientId}_newbutton" class="mcoPanel-controls">
<span onclick="#{cc.clientId}Toggle();">
<h:graphicImage name="page_new.gif" library="images"/>
</span>
</span>
<span id="#{cc.clientId}_savebuttons" class="mcoPanel-controls" style="display:none;">
<span id="#{cc.clientId}_loader" style="display:none;">
<h:graphicImage name="ajax-loader.gif" library="images" height="16" width="16"/>
</span>
<h:commandLink action="#{cc.saveNewTherapy}">
<f:ajax execute="newOnTherapy newExemption newDoctor newCareDate" render="#form" onevent="#{cc.clientId}rowHighlight"/>
<h:graphicImage name="action_save.gif" library="images"/>
</h:commandLink>
<span onclick="#{cc.clientId}Toggle();">
<h:graphicImage name="page_cross.gif" library="images"/>
</span>
</span>
</h:panelGroup>
</f:facet>
<div id="#{cc.clientId}_newTherapy" class="mcoPanel-new" style="display:none;">
<h:outputLabel for="newOnTherapy" value="Satisfied:" style="position:relative; top: -10px;"/>
<p:selectOneMenu id="newOnTherapy" label="Satisfied" value="#{cc.newOnTherapyValue}" style="width: 60px;">
<f:selectItem itemLabel=""/>
<f:selectItems value="#{cc.yesNoList}"/>
</p:selectOneMenu>
<br/>
<h:outputLabel for="newExemption" value="Exemption:" style="position:relative; top: -10px;"/>
<p:selectOneMenu id="newExemption" value="#{cc.newExemption}" style="width: 150px;">
<f:selectItems value="#{cc.exemptions}"/>
</p:selectOneMenu>
<span id="#{cc.clientId}_doctor" style="display:none">
<br/>
<h:outputLabel for="newDoctor" value="Doctor:"/>
<p:inputText id="newDoctor" value="#{cc.newDoctor}"/>
</span>
<span id="#{cc.clientId}_care" style="display:none">
<br/>
<h:outputLabel for="newCareDate" value="Care Date:"/>
<p:calendar id="newCareDate" label="Care Date" value="#{cc.newCareDate}" showButtonPanel="true">
<f:converter converterId="dateOfBirthConverter"/>
</p:calendar>
</span>
</div>
<h:messages id="#{cc.clientId}_messages" errorClass="errorMessage"/>
<p:dataTable id="histTable" value="#{cc.history}" var="item" rendered="#{cc.attrs.showHistory}">
<!-- Table Output -->
</p:dataTable>
</p:panel>
</h:form>
And the parent composite component looks something like this:
<cc:interface>
<cc:attribute name="title" type="java.lang.String" required="true"/>
</cc:interface>
<cc:implementation>
<h:outputScript name="containerpanel.js" library="js/components" target="head"/>
<p:panel toggleable="true" styleClass="contentPanel" toggleSpeed="500" style="width:1100px;">
<f:facet name="header">
#{cc.attrs.title}
<div class="ui-panel-titlebar-icon ui-corner-all ui-state-default contentSaveAll">
Save All
</div>
<div class="ui-panel-titlebar-icon ui-corner-all ui-state-default contentExpandAll">
++
</div>
<div class="ui-panel-titlebar-icon ui-corner-all ui-state-default contentCollapseAll">
- -
</div>
</f:facet>
<cc:insertChildren>
<!-- Child components go here -->
</cc:insertChildren>
</p:panel>
</cc:implementation>
The implementation is supposed to allow for any number of child components inside the container component.
The child components send ajax requests and update their internal components perfectly if they are placed on a page outside of the Container component. In addition, if I use the same structure of the container, but not an actual composite component, everything works just fine.
As soon as I place the child components as children of the Container component, that's where things go wonky. No ajax calls in the child components fire properly (i.e. the save commandLink) Using firebug to help debug this, I've been able to determine the following:
The ajax post request appears to be being sent. The "begin" onevent is firing, and looking at the console in firebug shows a post being made to the server, with the proper component ids and values being sent back.
The action in the backing bean is not being called. I have a print statement as the first line and it's not printing.
The ajax request appears to be completing properly, the "success" onevent is firing.
Nothing is being updated on the page. The form does not refresh, nor does the p:messages object at the top of the page.
Obviously I can do this without the Container component, but I would prefer to be able to of course take advantage of code reuse. Am I missing something obvious here that I need to do to get the ajax to work properly?
I am having the exact same problem with MyFaces 2.1.6.
I can't make AJAX calls from nested Composite Components using ClientBehavior in the interface of the CC.
Like moneyT wrote the server is being notified of the events specified in the ajax tag, but when the lifecycle went to phase 5 - Invoke Application, the event was null and no listener was called. More and more it looks like a bug in the implementation of MyFaces.
EDIT: I have found another solution which is much better than hardcoding ajax in the composite component. I have refactored the outer composite component to be facelet. It loses some of the quirks of the composites but it gets the job done. Also it is reusable.
The only solution (more of a workaraund than solution) I found is to hardcode ajax in the composite component rather than to use ClientBehavior, like this:
<composite:implementation>
<h:panelGroup layout="block" id="listBox" class="list-box-scroll-pane" style="height:#{cc.attrs.visibleLines*27 + 5}px; width:#{cc.attrs.width}px">
<h:inputText id="submit-value" style="visibility: hidden; width:0px; height: 0px;" value="#{cc.attrs.property}">
<f:ajax event="change"
render="carModel"
listener="#{carDetailsMediator.changeCarMake}"
onevent="initComboboxes"/>
</h:inputText>
<ui:repeat value="#{cc.attrs.items}" var="element" varStatus="loop">
<input id="input-#{cc.attrs.customId}-#{loop.index}" type="hidden"
value="#{element.value}" />
<div id="div-#{cc.attrs.customId}-#{loop.index}" class="list-box-row">#{element.label}</div>
</ui:repeat>
</h:panelGroup>
</composite:implementation>
However this workaround is not very good, because the idea behind composite components is that you can reuse them with many different options. Hardcoding ajax in it kind of limits the options.
I believe your problem is this:
<f:ajax execute="newOnTherapy newExemption newDoctor newCareDate" ...
The execute attribute can refer to the special keywords (Eg. #this, #form, etc...) or according to the documentation:
If a literal is specified, it must be a space-delimited String of component identifiers and/or one of the keywords.
When you are inserting this component as a child to the parent component then the component Ids are going to by dynamically determined and can't be referred to absolutely.

Resources