DynamicColumns

Here is a forum post discussing issues regarding dynamic columns: http://www.jboss.com/index.html?module=bb&op=viewtopic&t=118257

 

using the rendered attribute on rich:column

 

Below there is a simple example of how you can use the rendered attribute of the rich:column.

 

Example xhtml file:

<ui:composition  template="/WEB-INF/layout/template.xhtml">     
 <ui:define name="body">
   <h2>Table</h2>
     <h:form>
     <rich:dataTable id="aTable"
          onRowMouseOver="this.style.backgroundColor='#F1F1F1'"
          onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'"
          value="#{trb.tableData}" var="row">
               <f:facet name="header">
                    <rich:columnGroup>
                         <rich:column colspan="6">
                              Testing
                         </rich:column>
                    </rich:columnGroup>
               </f:facet>
               
               <f:facet name="footer">
                    <rich:columnGroup>
                         <rich:column colspan="6">
                              Footer
                         </rich:column>
                    </rich:columnGroup>
               </f:facet>
               
               <rich:column rendered="#{trb.cellRendered['value1']}">
                    <f:facet name="header">
     
                         <s:div>
                              value1 <h:commandLink value="x" action="#{trb.hideColumn('value1')}"></h:commandLink>
                         </s:div>                                                  
                    </f:facet>
                    #{row.value1}
               </rich:column>
               <rich:column rendered="#{trb.cellRendered['value2']}">
                    <f:facet name="header">
                         <s:div>
                              value2 <h:commandLink value="x" action="#{trb.hideColumn('value2')}"></h:commandLink>
                         </s:div>          
                    </f:facet>
                    #{row.value2}
               </rich:column>
               <rich:column rendered="#{trb.cellRendered['value3']}">
                    <f:facet name="header">
                         <s:div>
                              value3 <h:commandLink value="x" action="#{trb.hideColumn('value3')}"></h:commandLink>     
                         </s:div>     
                    </f:facet>
                    <h:outputText value="#{row.value3}"></h:outputText>
               </rich:column>
               <rich:column rendered="#{trb.cellRendered['value4']}">
                    <f:facet name="header">
                         <s:div>
                         value4 <h:commandLink value="x" action="#{trb.hideColumn('value4')}"></h:commandLink>
                         </s:div>          
                    </f:facet>
                    #{row.value4}
               </rich:column>
               <rich:column rendered="#{trb.cellRendered['value5']}">
                    <f:facet name="header">
                         <s:div>
                              value5 <h:commandLink value="x" action="#{trb.hideColumn('value5')}"></h:commandLink>
                         </s:div>          
                    </f:facet>
                    #{row.value5}
               </rich:column>
               <rich:column onmouseover="this.style.backgroundColor='#880000'" 
                               onmouseout="this.style.backgroundColor=''" 
                               onclick="SomeFunc();" rendered="#{trb.cellRendered['value6']}">
                    <f:facet name="header">
                         <s:div>
                              value6 <h:commandLink title="Remove column" value="x" action="#{trb.hideColumn('value6')}"></h:commandLink>
                         </s:div>          
                    </f:facet>
                    #{row.value6}
               </rich:column>          
          </rich:dataTable>
          
               Generate new table values:
          <h:commandButton value="generate" action="#{trb.createData}"></h:commandButton>
     </h:form>
          
     <h:form>
          Select which columns are rendered.
          <br/>
          <h:selectBooleanCheckbox title="value1" value="#{trb.cellRendered['value1']}"></h:selectBooleanCheckbox>
          <h:selectBooleanCheckbox title="value2" value="#{trb.cellRendered['value2']}"></h:selectBooleanCheckbox>
          <h:selectBooleanCheckbox title="value3" value="#{trb.cellRendered['value3']}"></h:selectBooleanCheckbox>
          <h:selectBooleanCheckbox title="value4" value="#{trb.cellRendered['value4']}"></h:selectBooleanCheckbox>
          <h:selectBooleanCheckbox title="value5" value="#{trb.cellRendered['value5']}"></h:selectBooleanCheckbox>
          <h:selectBooleanCheckbox title="value6" value="#{trb.cellRendered['value6']}"></h:selectBooleanCheckbox>
          <br/>
          <h:commandButton value="Apply" action="rerender"></h:commandButton>
     </h:form>
          
     </ui:define>
</ui:composition>

Example bean (trb above):

public class TableBackingRendered implements Serializable{

     /**
      * 
      */
     private static final long serialVersionUID = 1L;
     
     private Random rand = new Random(System.currentTimeMillis());
     private List<TableItem> tableData;
     private Map<String,Boolean> cellRendered = new HashMap<String,Boolean>();

     public TableBackingRendered(){
          
          createData();
          allCellsRendered();
     }

     
     public String createData(){
          
          int count = rand.nextInt(25)+1;
          tableData = new ArrayList<TableItem>(count);
          
          for(int i=0; i<count; i++){
               tableData.add( new TableItem(
                         "value1_" +i,
                         "value2_" +i,
                         "value3_" +i,
                         "value4_" +i,
                         "value5_" +i,
                         "value6_" +i
                         ));
          }
          
          return null;
     }
     
     public String allCellsRendered(){
          cellRendered.put("value1", Boolean.TRUE);
          cellRendered.put("value2", Boolean.TRUE);
          cellRendered.put("value3", Boolean.TRUE);
          cellRendered.put("value4", Boolean.TRUE);
          cellRendered.put("value5", Boolean.TRUE);
          cellRendered.put("value6", Boolean.TRUE);
          
          return null;
     }
     
     public String hideColumn(final String columnToHide){
          cellRendered.put(columnToHide, Boolean.FALSE);
          
          return null;
     }
     
     public List<TableItem> getTableData() {
          return tableData;
     }

     public Map<String, Boolean> getCellRendered() {
          return cellRendered;
     }


     public void setCellRendered(Map<String, Boolean> cellRendered) {
          this.cellRendered = cellRendered;
     }


     public void setTableData(List<TableItem> tableData) {
          this.tableData = tableData;
     }
}

 

Another solution when you are dealing with a significant amount of rows, if you are using facelets you can use c:forEach (jslt)

 

 

<rich:dataTable value="report.rows" var="row">

 

   <f:facet name="header">

 

      <rich:columnGroup>

 

         <c:forEach var="col" items="{report.columns}/>

 

            <h:outputText value="{col.label}"/>

 

         </c:forEach>

 

      </rich:columnGroup>

 

   </f:facet>

 

 

   <c:forEach var="cell" items="{report.columns}" varStatus="col">

 

      <h:outputText value="{row[Col.index|col.index].cells.value}"/>

 

   </c:forEach>

 

</rich:dataTable>