简体   繁体   中英

Nested ajax in JSF and ui:repeat

<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>

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. Eg:

<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?

See also:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM