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>
Comments