Example 4-6 shows a JSP page (struts_table.jsp) that uses Struts tags to display tabular data where the background colors alternate between orange and yellow.
Example 4-6. Alternating table row colors using Struts
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix= "bean" %> <%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix= "logic" %> <html> <head> <title>Struts Cookbook - Chapter 4 : Tables</title> <style> /* Even row */ .row1 {background-color:orange;} /* Odd row */ .row0 {background-color:yellow;} </style> </head> <body> <jsp:useBean id="weeklyWeather" class="com.oreilly.strutsckbk.ch04.WeeklyWeather"/> <table> <tr> <th>Day of Week</th> <th>Chance of Precipitation</th> <th>Expected Precipitation (inches)</th> </tr> <logic:iterate id="forecast" indexId="count" name="weeklyWeather" property="weekForecast"> <tr> <td class='row<%= count.intValue( ) % 2 %>'> <bean:write name="forecast" property="day"/> </td> <td class='row<%= count.intValue( ) % 2 %>'> <bean:write name="forecast" property="chancePrecip"/> </td> <td class='row<%= count.intValue( ) % 2 %>'> <bean:write name="forecast" property="rainfall"/> </td> </tr> </logic:iterate> </table> </body> </html>
Example 4-7 (jstl_table.jsp) shows a cleaner solution that uses JSTL EL instead of relying on JSP scriptlet.
Example 4-7. Alternating table row colors using JSTL
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <html> <head> <title>Struts Cookbook - Chapter 4 : Tables</title> <style> /* Even row */ .evenRow {background-color:orange;} /* Odd row */ .oddRow {background-color:yellow;} </style> </head> <body> <jsp:useBean id="weeklyWeather" class="com.oreilly.strutsckbk.ch04.WeeklyWeather"/> <table> <tr> <th>Day of Week</th> <th>Chance of Precipitation</th> <th>Expected Precipitation (inches)</th> </tr> <c:forEach var="forecast" items="${weeklyWeather.weekForecast}" varStatus="loop"> <c:set var="tdclass" value="oddRow"/> <c:if test="${loop.count % 2 == 0}"> <c:set var="tdclass" value="evenRow"/> </c:if> <tr> <td class='<c:out value="${tdclass}"/>'> <c:out value="${forecast.day}"/> </td> <td class='<c:out value="${tdclass}"/>'> <c:out value="${forecast.chancePrecip}"/> </td> <td class='<c:out value="${tdclass}"/>'> <c:out value="${forecast.rainfall}"/> </td> </tr> </c:forEach> </table> </body> </html>
It doesn't take a usability expert to show you that
alternating the color or style of tabular data rows makes the table
more readable. Both approaches shown in the Solution—the first
using Struts tags and the second using JSTL—render a table with
alternating row colors. In each approach, the
style
element in the head
defines two styles for alternation. In the first approach, the styles
are identified as row1
and
row0
. The logic:iterate
loop iterates over the data Collection. The
indexId
attribute creates a scripting variable
that holds the current value of the loop index. This value starts at
and increments by one on each iteration of the loop. The modulus
(remainder) operation is used to calculate a 0 or 1. The style to use
is specified by concatenating row to the calculated modulus:
class='row<%= count.intValue( ) % 2 %>
Since count
is a
java.lang.Integer
object, you must use the
intValue( )
method when performing the
calculation. The calculation returns the remainder from dividing
count
by 2. Therefore, if the loop index is an
even number—2, 4, etc.—then the style ID for the
class
attribute will be
row0
. If the loop index is an odd number,
row1
will be used. The result is that the
rows alternate in color. Figure 4-4 shows the
rendered page generated by the first approach.
The use of Cascading Style Sheet (CSS) styles makes this solution flexible. The style allows for a myriad of presentation effects to be applied in addition to the basic background color. However, this solution does force you to name each style in a contrived fashion—the name must end in a 0 or 1.
The second approach uses JSTL only, and no Struts tags are used. The
generated HTML is identical to the first, but three significant
differences occur between the JSTL approach and the Struts-based one.
First, the remainder calculation to determine if a row is odd or even
is handled using EL instead of scriptlet. Second, the
c:if
tag directly determines the style to apply;
you aren't forced to name the styles
row0
and row1
.
The third difference is subtle, yet important. When the
varStatus
attribute is used, the
c:forEach
loop exposes an object that indicates
the status of the loop. This object has properties that represent the
index
of the underlying collection and the
count
of the number of loops that have occurred.
This property is useful if the c:forEach
iterates
over a portion of a collection by specifying the
begin
, end
, or
step
attributes. For example, consider the
following c:forEach
loop:
<c:forEach var="bar" items="fooList" begin="3" step="2" varStatus="loopStat"> Index: <c:out value="${loopStat.index}"/><br /> Count: <c:out value="${loopStat.count}"/> <br /> </c:forEach>
This loop starts with the fourth element
(begin="3
") and displays every other element
(step="2
"). The output from this loop would look
something like:
Index: 3 Count: 1 Index: 5 Count: 2 Index: 7 Count: 3 ...
If the index, instead of the count, were used to calculate the modulus, the colors would never alternate.
Recipe 3.1 provides the basics needed to use JSTL in your application. Recipe 4.4 shows how to sort data in an HTML table by clicking on a row header. Recipe 4-6 shows you how to create the effects shown in this recipe using the display tags open source tag library.
Get Jakarta Struts Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.