Search code examples
javahtmlcollectionsstruts2ognl

How to draw multiple HTML Tables from a single Collection with <s:iterator>?


Assume I have two tables, Monday and Tuesday. I want to populate these tables according to a property of the object. Thus:

<s:iterator value="trainings">
 <table>
   <tr><th>Monday</th></tr>

   <s:if test="weekday.toString().equals('MONDAY')">
     <tr>
       <td>
          <s:property value="title" />
       </td>
    </tr>
   </s:if>
 </table>

 <table>
   <tr><th>Tuesday</th></tr>

   <s:if test="weekday.toString().equals('TUESDAY')">
     <tr>
       <td>
          <s:property value="title" />
       </td>
    </tr>
   </s:if>
 </table>

</s:iterator>

How can I make this work correctly? Thank you

EDIT:

public class Training {    
    private Weekday weekday;        
    ....        
}

public Enum Weekday {        
    MONDAY,
    TUESDAY,
    ...        
}

Solution

  • To populate two different tables from a single source (that should be better to split server-side, in the action), you usually need to iterate the collection twice:

        <table>
            <tr><th>Monday</th></tr>
      <s:iterator value="trainings">
          <s:if test="weekday.toString().equals('MONDAY')">
            <tr><td><s:property value="title" /></td></tr>
          </s:if>
      </s:iterator>
        </table>
    
        <table>
            <tr><th>Tuesday</th></tr>
      <s:iterator value="trainings">
          <s:if test="weekday.toString().equals('TUESDAY')">
            <tr><td><s:property value="title" /></td></tr>
          </s:if>
      </s:iterator>
        </table>
    

    To avoid executing the <s:if> multiple times, you can use OGNL's List Selection:

        <table>
            <tr><th>Monday</th></tr>
      <s:iterator value="trainings.{? #this.weekday.toString() == 'MONDAY' }">
            <tr><td><s:property value="title" /></td></tr>
      </s:iterator>
        </table>
    
        <table>
            <tr><th>Tuesday</th></tr>
      <s:iterator value="trainings.{? #this.weekday.toString() == 'TUESDAY' }">
            <tr><td><s:property value="title" /></td></tr>
      </s:iterator>
        </table>
    

    that results in a smaller and cleaner HTML code.