Search code examples
jsfjsf-2javabeansfaceletsuirepeat

Access previous/next item when iterating over a ListDataModel using JSF 2 facelets <ui:repeat> tag


I'm iterating over a list and want certain attributes of the current element to be rendered only when they're different from the previous element. Right now I have:

<ui:repeat value="#{myBean.myListDataModel}" var="item" varStatus="itemStatus">

  <ui:fragment rendered="#{
      itemStatus.first 
      or (myBean.myListDataModelUnwrapped[itemStatus.index-1].category ne item.category)
  }">
      <h1>
          <h:outputText value="#{item.category}"/>
      </h1>
      <!-- can't open a ul here -->
  </ui:fragment>

          <li>
              <h:outputText value="#{item.name}"/>
          </li>

  <ui:fragment rendered="#{
      itemStatus.last or 
      (myBean.myListDataModelUnwrapped[itemStatus.index+1].category ne item.category)
  }">
      <!-- can't close a ul here -->
  </ui:fragment>

</ui:repeat>

where

Object[] myListDataModelUnwrapped = 
    (Object[]) ((new ArrayList((List) myListDataModel.getWrappedData())).toArray());
  • What's a better way to access the previous/next element when iterating over a ListDataModel?

  • How can I embed the list elements on <ul></ul> tags, rendering a valid unordered list below each category header?


Solution

  • well, you have 2 questions and i don't have a better solution for the 1st one. i've always used your way to do it.

    for the 2nd one, as a work-around, you can open and close <ul></ul> using h:outputText, as below:

    xhtml code:

    <h:outputText value="#{testMB.ulStartTag}" escape="false"/>
    ...
    <h:outputText value="#{testMB.ulEndTag}" escape="false"/>
    

    managed bean code:

    public String getUlStartTag() {
        return "<ul>";
    }
    
    public String getUlEndTag() {
        return "</ul>";
    }
    

    ps: don't try to write "<ul>" as the value of h:outputText directly into the xhtml, it will fail at runtime because of the "<" and ">" characters.