4 Replies Latest reply on Sep 18, 2007 4:50 AM by Denis Zjukow

    tags c:forEach and ui:repeat

    Denis Zjukow Newbie

      Hello,

      Having struggled for a couple of days I finally gave up and decided to ask for help.

      I use Seam with Facelets. What I want is to show a list of entities in a table cell i.e a single cell may contain a comma-separted list.

      Let's say I have two entity types: Item and Subitem. An instance of type Item may have a number of Subitems. In my case the relation between these two entity types is many-to-many.

      So if I have Item1 with three subitems: Subitem1, Subitem2 and Subitem3, I want to see something like this:

       <table>
      
       ...
      
       <tr>
      
       ...
      
       <td>Subitem1,SubItem2,Subitem3</td>
      
       ...
      
       </tr>
      
       ...
      
       </table>
      


      Please note that I don't want a comma after the last subitem in a cell (Subitem3 in this case). Nothing special, an obvious requierment, isn't it?

      The first thing I tried was ui:repeat:

       <!-- Table, each row represents an item. -->
       <h ataTable value="items" var="item">
      
       ...
      
       <!-- This is my tricky column. -->
       <h:column>
      
       <!-- I want to see all subitems in a single cell. -->
       <ui:repeat value="#{item.subitems}" var="subitem">
      
       <!-- Show a subitem. -->
       <h utputText value="#{item.subItems}" />
      
       <!-- Add separator. -->
       <h utputText value="," />
      
       </ui:repeat>
       <h:column>
      
       ...
      
       </h ataTable>
      


      Everything's fine except for the fact that there is a nasty comma after the last subitem. This made me try c:forEach tag:

       ...
      
       <!-- I want to see all subitems in a single cell. -->
       <c:forEach items="#{item.subitems}" var="subitem" varStatus="stat">
      
       <!-- Show a subitem. -->
       <h utputText value="#{item.subItems}" />
      
       <!-- Add separator for each subitem except for the last one. -->
       <c:if test="#{!stat.last}">
       <h utputText value="," />
       </c:if>
      
       </ui:repeat>
      
       ...
      


      Unfortunately this code won't work! It just leaves my favorite column empty. It seams that c:forEach do not see variable item.
      I then tried to find a way to add the conditional logic to ui:repeat, but haven't managed to find anything like c:forEach's 'varStatus'.

      Any ideas? Thank you all in advance!

        • 1. Re: tags c:forEach and ui:repeat
          mgrouch Expert

          c:forEach is build time tag. So it won't work in your case.
          (It is designed to iterate over components at UI tree build time, and not over data at render time)

          Why don't you put rendered condition on h:outputText which prints ",". You can get size of collection using EL function.

          Or better use t:dataList from tomahawk. It also has index variable.

          ui:repeat is buggy. RichFaces might also have some repeater tag.

          • 2. Re: tags c:forEach and ui:repeat
            mgrouch Expert

            And one more suggestion. For performance reasons just to that
            string concatenation in Java code.

            In this case you do not need any of UI repeat.
            Write a getter on backing bean.

            (or EL function which takes item collection)

            • 3. Re: tags c:forEach and ui:repeat
              Adrian Mitev Master

              Actually List .toString returns the objects comma-separated - [Subitem1,SubItem2,Subitem3] (you just have to cut the first and the last char)

              • 4. Re: tags c:forEach and ui:repeat
                Denis Zjukow Newbie

                Thank you mgrouch and amitev. I like the idea of conditional rendering. I think it suits perfectly in this case.

                Let me ask one more question. Do jstl tags work with Seam scopes such as CONVERSATION, for example. This is not a build-in Servlet API scope, is it? Lets take c:forEach, for example, how can it find a variable if it is not in one of PAGE, REQUEST, SESSION or APPLICATION scopes? Thanks.