Recently I ran into a requirement on an ADF project to present columns in an ADF Faces table component in a clustered (nested) fashion. Out of 12 columns, one group of three columns and another group of four columns formed clusters – columns that together had something in common. And this clustering, column grouping or common-ness should be visualized in the table. For example by giving these groups of three and four columns a common header and visual indication using borders, in addition to their individual header and demarcation.

My first reaction was that it could be done or not in a very simple way. Boy, was I wrong! Yesterday I went through the ADF Faces documentation on Tables and Columns, and I quickly ran into a section on nested columns: "af:column  tags can be nested to produce groups of columns. The header of a column group spans across all the columns it contains. " There it was, exactly what I needed in the easiest way one can imagine!

and this table with nested columns was created from:....

 

Nesting several columns into one cluster with a joint header – as for example was done with Email and Phone Number inside Contact – is very easily achieved by nesting the af:column element for Email and Phone Number inside a new af:column element Contact. In stripped code that looks like:

   <af:column>     <f:facet name="header">         <af:outputText value="Employee"/>     </f:facet>     ...     <af:column >       <f:facet name="header">         <af:outputText value="Contact"/>       </f:facet>       <af:column >         <f:facet name="header">           <af:outputLabel value="Email"/>         </f:facet>         ...       </af:column>       <af:column >         <f:facet name="header">           <af:outputLabel value="PhoneNumber"/>         </f:facet>         ...       </af:column>     </af:column>     ... 

The overall nested column structure presented in this page – stripped of the actual column contents – now looks like this:

 <af:table id="AllocationsTable"    <af:column ...>     <f:facet name="header">       <af:outputLabel value="Id" />     </f:facet>     ...   </af:column>   <af:column>     <f:facet name="header">         <af:outputText value="Employee"/>     </f:facet>     <af:column ... >       <f:facet name="header">         <af:outputLabel value="EmpId"/>       </f:facet>     </af:column>     <af:column ...>       <f:facet name="header">         <af:outputLabel value="FirstName"/>       </f:facet>       ...     </af:column>     <af:column >       <f:facet name="header">         <af:outputLabel value="LastName"/>       </f:facet>       ...     </af:column>     <af:column >       <f:facet name="header">         <af:outputText value="Contact"/>       </f:facet>       <af:column >         <f:facet name="header">           <af:outputLabel value="Email"/>         </f:facet>         ...       </af:column>       <af:column >         <f:facet name="header">           <af:outputLabel value="PhoneNumber"/>         </f:facet>         ...       </af:column>     </af:column>     <af:column ... >         <f:facet name="header">           <af:outputLabel value="HireDate"/>         </f:facet>         ...     </af:column>     <af:column id="EmployeeCurrent">       <f:facet name="header">         <af:outputText value="Current Position"/>       </f:facet>       <af:column ...><f:facet name="header"><af:outputLabel value="JobId"/></f:facet>...</af:column>       <af:column ...><f:facet name="header"><af:outputLabel value="Salary" /></f:facet>...</af:column>       <af:column ...><f:facet name="header"><af:outputLabel value="DepartmentId"/></f:facet>...</af:column>     </af:column>   </af:column>   <af:column id="Allocation">     <f:facet name="header">       <af:outputText value="Allocation"/>     </f:facet>     ...   </af:column>   ... </af:table> 

As you can see, creating clustered, nested columns – down to several levels – is an easy thing to do.

Note that when rendering, ADF Faces does not produce COLGROUP or COL elements, as I had expected and hoped for, but instead creates regular TR, TH and TD elements. Every additional level of column nesting results in an additional TR element – with the non-nested columns getting an increase in their ROWSPAN attribute.