Reputation: 677
<h:form>
<fieldset>
<h:selectManyListbox id="listbox" value="#{form.items}">
<f:selectItems value="#{form.allItems}">
</h:selectManyListbox>
</fieldset>
<h:commandButton value="Get Table" action="#{form.getTable}">
<f:ajax render="result_table" execute="listbox" />
</h:commandButton>
<h:panelGrid id="result_table">
<table>
<thead></thead>
<tbody>
<ui:repeat var="table" value="#{form.resultTable}">
<tr>
<td>#{table.name}</td>
<td>
<h:selectBooleanCheckbox binding="#{showMore}">
<f:ajax render="inner" />
</h:selectBooleanCheckbox>
</td>
</tr>
<tr>
<td>
<h:panelGrid id="inner" rendered="#{not empty showMore.value and showMore.value}">
<table></table>
</h:panelGrid>
</td>
</tr>
</ui:repeat>
</tbody>
</table>
</h:panelGrid>
</h:form>
I followed the checkbox sample code from BalusC here.
When I click the command button, based on the list box values, it generates a table result which I display in h:panelGrid id="result_table"
. This command button works. Inside the generated table, I have some sub-tables I want to display, but only if I check the box to show them. For the checkbox if I use render="@form"
it collapses my outer parent table. If I use render="inner"
checking/unchecking box does nothing.
How do I get this to work? Is it because the two ajax are in conflict?
FYI, I also tried using a bean property instead but got the same result. When I tried using the javascript method mentioned in the same link, but checking/unchecking the box has no effect.
Updated to add example snippet and <ui:repeat></ui:repeat>
above:
<h:selectBooleanCheckbox binding="#{showMore}">
<f:ajax render="inner" />
</h:selectBooleanCheckbox>
<h:panelGrid id="inner">
<h:outputText value="always" />
<h:outputText value="hidden" rendered="#{not empty showMore.value and showMore.value}" />
</h:panelGrid>
Upvotes: 3
Views: 4079
Reputation: 1109625
The culprit is here:
<h:panelGrid id="inner" rendered="#{not empty showMore.value and showMore.value}">
<table></table>
</h:panelGrid>
The f:ajax
uses JavaScript to locate the element-to-be-rendered in the client side. JavaScript won't be able to locate the HTML representation of the inner
panelgrid when it's not rendered to the client side by JSF. Put the inner
id in a parent component instead which is always rendered to the client side, so that Ajax/JavaScript can locate it regardless of the rendered
condition. E.g.:
<h:panelGroup id="inner">
<h:panelGrid rendered="#{not empty showMore.value and showMore.value}">
<table></table>
</h:panelGrid>
</h:panelGroup>
Update: as per the comments, using the ui:repeat
should not form a problem here. Even more, to be sure I have copypasted your example to my playground environment and it works fine (using Mojarra 2.0.3 on Tomcat 6.0.29). The bean is by the way marked @ViewScoped
. Maybe yours was @RequestScoped
and the loading of the value for the ui:repeat
was based on some request scoped condition which wasn't retained in the subsequent ajax calls?
@ViewScoped
- explains the value of @ViewScoped
Upvotes: 3