Search code examples
jsffaceletsuirepeat

ui:repeat inside ui:repeat


I have this:

<ui:repeat value="#{orderController.listRequestItem}" var="item">
....
<tbody>
  <tr>
    <td>#{item.product.codigoProduto}</td>
  <td>
    <ui:repeat value="#{item.product.materials}" var="m">
     #{m.description}
    </ui:repeat>
  </td>
...

The listRequestItem is:

public List<RequestItemVO> listRequestItem;

and here I'm populating it:

listRequestItem = new ArrayList<>(requestVO1.getRequestItem());

The item.product.materials is:

public Set<MaterialVO> getMaterials()
{
    //compiled code
    throw new RuntimeException("Compiled Code");
}

When I try to access the m on my inner <ui:repeat>, I can't access its methods.

The #{item.product.codigoProduto} is returning the product code correctly.


Solution

  • The <ui:repeat> doesn't support Set<E>. This support will be introduced in the upcoming JSF 2.2 (also for <h:dataTable>). JSF 2.2 will be released this quarter already.

    In the meanwhile, you need to convert it to List. There are several ways:

    • Change the property to be List<MaterialVO> instead and alter business code accordingly.

      private List<MaterialVO> materials;
      
    • Or add a wrapper property and use it instead.

      public List<MaterialVO> getMaterialList() {
          return new ArrayList<MaterialVO>(materials);
      }
      

      This is only expensive as the getter is invoked on every iteration. You may want to add another property which wraps the original set.

    • Or create a custom EL function which does the job:

      <ui:repeat value="#{util:setToList(item.product.materials)}" ...>
      
    • Or create a custom EL resolver. Detail can be found in this answer: How do I use a java.util.Set with UIData in JSF. Specifically h:datatable?

    This problem is not related to nesting <ui:repeat>.