2

I have problem with ui:repeat in h:dataTable tag. I have one collection with names of the field ant another with data. So I am matching them by indexes. When I load the page, exception OutOfBoundsException is thrown. But when i put filingCabinetManagerBean.filingCabinet.schema.fields.indexOf(schemaField) outside ui:repeat, it displays correct indexes. So I have tried to split it and declared ui:param and also c:set as variables but same problem. cardData attribute of actualCard is not null, nor empty, it has 7 items in it, I've already debugged it. So do you have any idea what might be the problem?

PS: When I change ui:repeat for h:dataTable, it is working. And best of all, identical construction is used on another JSF page and it is working, there is only one difference - I get cardData from card which is referenced in one outer dataTable, so it is not Bean(dot) property and so on, but only variable(dot) so on.

Any ideas? Thank you for your help. :)

<p:panel header="#{fileUploadBean.actualCard.id}">

        <h:dataTable value="#{filingCabinetManagerBean.filingCabinet.schema.fields}" var="schemaField" style="vertical-align: top">

            <h:column><h:outputText value="#{schemaField.fieldTitle}:" style="font-size: 20px;font-weight: bold"/></h:column>
            <h:column>
                <ul>
                    <ui:repeat value="#{fileUploadBean.actualCard.cardData.get(filingCabinetManagerBean.filingCabinet.schema.fields.indexOf(schemaField)).data}" var="data">
                        <li><h:outputText value="#{data.string}"/></li>
                    </ui:repeat>
                </ul>     
            </h:column>
        </h:dataTable>

Bence Kaulics
  • 7,066
  • 7
  • 33
  • 63
Xenon
  • 189
  • 1
  • 1
  • 14
  • Which JSF impl/version? Tried latest? had many bugs in Mojarra most of which should already be eliminated with current latest 2.2.12. The current answer only shows a work around not a solution. Nonetheless, doing business logic in a getter is a bad idea. You'd better rework your controller to prepopulate exactly the model the view expects rather than letting the view populate the model via getters (which is plain inefficient). See also a.o. http://stackoverflow.com/questions/2090033/why-jsf-calls-getters-multiple-times – BalusC Oct 23 '15 at 14:18

1 Answers1

0

The <ui:repeat> doesn't work inside <h:dataTable> because the value of the <ui:repeat> is retrieved using the var of the <h:dataTable>.

For an obscure reason, the <h:dataTable> iterates correctly on all the objects of the list plus one last time with a null value. This last iteration breaks the <ui:repeat>.

Solution is to handle this while getting the value of the ui:repeat. For instance, if you have something like :

<h:dataTable value="#{someBean.parentObjList}" var="obj">
  <h:column>
    <ui:repeat value="#{someBean.getChildren(obj)" var="child" >
       ...
    </ui:repeat>
  </h:column>
</h:dataTable>

And in the controller :

public List<ChildObj> getChildren(ParentObj obj) {
  return parentObjService.findAllFor(obj);
}

Then you need to replace it by :

public List<ChildObj> getChildren(ParentObj obj) {
  if (obj == null)
    return new ArrayList<ChildObj>(); // return empty ArrayList to avoid crashing
  else 
    return parentObjService.findAllFor(obj);
}
ForguesR
  • 3,558
  • 1
  • 17
  • 39