The following JSP code shows how to use a TableInfo component and nested ForEach servlet beans to render a simple table of user profile information. User profile information is stored in a parameter named userProfiles, which can be populated in several ways. For example, you might use a TargetingArray servlet bean to retrieve from the Profile Repository all user profiles that meet the targeting rules you specify—for example, all users who live in Boston and are registered members of your site. You can then set the value of userProfiles to the array of profiles that is the result of the targeting operation, and pass the userProfiles parameter into an included page that renders the profiles in a table using TableInfo:

<dsp:include page="build_table.jsp">
  <dsp:param name="userProfiles" param="element"/>

The following code example shows how to use a TableInfo component to render a simple table. Later sections show how to build more tables, where the user can change the columns on which the table is sorted.

1  <%-- Create table displaying profiles stored in param:userProfiles --%>
2  <%-- using table display information from a bean named TableInfo  --%>
4  <dsp:droplet name="ForEach">
5    <dsp:param name="array" param="userProfiles"/>
6    <dsp:param bean="TableInfo.sortString" name="sortProperties"/>
7    <dsp:oparam name="empty">
8       There are no items in your list.
9    </dsp:oparam>
11  <%-- Generate table start and column headings in outputStart --%>
13    <dsp:oparam name="outputStart">
14       <TABLE border=1 cellspacing=2 cellpadding=2>
15       <TR>
16       <dsp:droplet name="ForEach">
17         <dsp:param bean="TableInfo.tableColumns" name="array"/>
18         <dsp:param name="sortProperties" value=""/>
19         <dsp:oparam name="output">
20           <dsp:setvalue paramvalue="element.heading" 21 param="columnHeading"/>
22           <TD align="center">
23              <dsp:valueof param="columnHeading"/>
24           </TD>
25         </dsp:oparam>
26       </dsp:droplet>
27       </TR>
28    </dsp:oparam>
30  <%-- Generate a row per item in output --%>
32    <dsp:oparam name="output">
33      <dsp:setvalue paramvalue="element" param="currentProfile"/>
34      <TR>
36  <%--
37   Here you are going to iterate over all of the property names you
38   want to display in this row, using the BeanProperty servlet bean to
39   display each value.
40  --%>
42      <dsp:droplet name="ForEach">
43        <dsp:param bean="TableInfo.tableColumns" name="array"/>
44        <dsp:param name="sortProperties" value=""/>
46        <dsp:oparam name="output">
47          <TD>
49          <dsp:droplet name="BeanProperty">
51           <dsp:param name="bean" param="currentProfile"/>
52            <dsp:param name="propertyName" param=""/>
54            <dsp:oparam name="output">
55               <dsp:valueof param="propertyValue"/>
56            </dsp:oparam>
57          </dsp:droplet>
59          </TD>
60        </dsp:oparam>
61      </dsp:droplet>
62      </TR>
63    </dsp:oparam>
65  <%-- Close the table in outputEnd --%>
67    <dsp:oparam name="outputEnd"></TABLE>
68    </dsp:oparam>
70  </dsp:droplet>
Line 4

The outer ForEach servlet bean on line 4 iterates over an array of profiles in userProfiles, passed into the servlet bean in line 5, and renders its output oparam once for each profile in the array.

Line 6

The current sorting instructions for the table are passed into the outer ForEach servlet bean using the sortProperties input parameter. In example, sortProperties is empty by default, so no columns in the table are sorted. Consequently, the profiles in userProfiles are rendered in the table in the order they are listed in the userProfiles array.

In many instances, this behavior is sufficient because array items are already sorted. For example, if a TargetingArray servlet bean is used to populate the userProfiles array, you can specify the sort order for the array set as the result of the targeting operation.

The use of sortString enables the table to be sorted on multiple columns. To sort a table on only a single column, render the table with TableInfo.primarySortString.

Lines 16-26

An inner ForEach servlet bean is embedded in the outputStart oparam of the outer ForEach, and it builds the column headings for the table. The array of Column objects, maintained in TableInfo.tableColumns, is passed into the bean in the array input parameter. During each iteration over this array, the columnHeading parameter is set to the value of the current column’s heading (lines 20-21), then rendered in a table cell in the heading table row (line 22-24).

Explicitly setting a columnHeading parameter in lines 20-21 is unnecessary; you can produce the same result with <dsp:valueof param="element.heading"/>. However, copying the value in this explicitly-named parameter makes the JSP code clearer, particularly in the more complex examples shown later.

Lines 42-57

A second inner ForEach servlet bean is used in the output oparam of the outer ForEach servlet bean. It generates a table row for each item in param:userProfiles. Each row must display a single item’s values for each property associated with a table column.

Each row is built as follows:

Each table cell in the current table row is constructed in this way as the application iterates over the tableColumns array and renders the output (a table cell) once for each Column object in the array. Likewise, each table row in the table is constructed as the application iterates over the param:userProfiles array and renders the output (that is, a table row) once for each profile in the array.

In lines 18 and 44, sortProperties is set to an empty string in both inner ForEach servlet beans, because they are nested inside the outer ForEach servlet bean; consequently, the sortProperties input parameter of the outer bean is visible to both inner beans. Because the sorting instructions should be applied only to the output rendered in the outer ForEach servlet bean, sortProperties must be overridden within the scope of each inner servlet bean.