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