About
How to create a dynamic JSF data table with a facelet page ?
Example made with:
- JSF 2.0
- JDK 1.6 (J2EE 6)
- on Glassfish
- with NetBeans 7.1
Articles Related
Steps
The Facelet Page
The facelet page just need a place holder to include the dynamic table generation made with the managed bean such as:
<h:panelGroup binding="#{datatableManagedBean.dynamicDataTableGroup}" />
Below a complete example made with the Style Sheet of Netbeans JSF CRUD application generator.
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>My Dynamic Data Table</title>
<h:outputStylesheet name="css/jsfcrud.css"/>
</h:head>
<h:body>
<h1>
My Dynamic Data Table
</h1>
<p>
<h:form styleClass="jsfcrud_list_form">
<h:panelGroup binding="#{datatableManagedBean.dynamicDataTableGroup}" />
</h:form>
</p>
</h:body>
</html>
The Managed Bean
package dynamic.jsf;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.html.HtmlColumn;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.component.html.HtmlPanelGroup;
import javax.faces.context.FacesContext;
/**
*
* @author gerard
*/
@ManagedBean(name = "datatableManagedBean")
@SessionScoped
public class DynamicDataTableManagedBean {
// Init --------------------------------------------------------------------------------------
private static List<List<String>> dynamicList; // Simulate fake DB.
private static String[] dynamicHeaders; // Optional.
private HtmlPanelGroup dynamicDataTableGroup; // Placeholder.
// Actions -----------------------------------------------------------------------------------
private void loadDynamicList() {
// Set headers (optional).
dynamicHeaders = new String[] {"Region Id", "Region Name"};
// Set rows
dynamicList = new ArrayList<List<String>>();
dynamicList.add(Arrays.asList(new String[] { "1", "Europe" }));
dynamicList.add(Arrays.asList(new String[] { "2", "Americas" }));
dynamicList.add(Arrays.asList(new String[] { "3", "Asia" }));
dynamicList.add(Arrays.asList(new String[] { "4", "Middle East and Africa"}));
}
private void populateDynamicDataTable() {
// Context and Expression Factory
FacesContext fCtx = FacesContext.getCurrentInstance();
ELContext elCtx = fCtx.getELContext();
ExpressionFactory ef = fCtx.getApplication().getExpressionFactory();
// Create <h:dataTable value="#{datatableManagedBean.dynamicList}" var="dynamicRow">.
HtmlDataTable dynamicDataTable = new HtmlDataTable();
ValueExpression ve = ef.createValueExpression(elCtx,"#{datatableManagedBean.dynamicList}",List.class);
dynamicDataTable.setValueExpression("value", ve);
dynamicDataTable.setVar("dynamicRow");
// Iterate over columns
for (int i = 0; i < dynamicList.get(0).size(); i++) {
// Create <h:column>.
HtmlColumn column = new HtmlColumn();
dynamicDataTable.getChildren().add(column);
// Create <h:outputText value="dynamicHeaders[i]"> for <f:facet name="header"> of column.
HtmlOutputText header = new HtmlOutputText();
header.setValue(dynamicHeaders[i]);
column.setHeader(header);
// Create <h:outputText value="#{dynamicRow[" + i + "]}"> for the body of column.
HtmlOutputText output = new HtmlOutputText();
ve = ef.createValueExpression(elCtx, "#{dynamicRow[" + i + "]}", String.class);
output.setValueExpression("value", ve);
column.getChildren().add(output);
}
// Add the datatable to <h:panelGroup binding="#{datatableManagedBean.dynamicDataTableGroup}">.
dynamicDataTableGroup = new HtmlPanelGroup();
dynamicDataTableGroup.getChildren().add(dynamicDataTable);
}
// Getters -----------------------------------------------------------------------------------
public HtmlPanelGroup getDynamicDataTableGroup() {
// This will be called once in the first RESTORE VIEW phase.
if (dynamicDataTableGroup == null) {
loadDynamicList(); // Preload dynamic list.
populateDynamicDataTable(); // Populate editable datatable.
}
return dynamicDataTableGroup;
}
public List<List<String>> getDynamicList() {
return dynamicList;
}
// Setters -----------------------------------------------------------------------------------
public void setDynamicDataTableGroup(HtmlPanelGroup dynamicDataTableGroup) {
this.dynamicDataTableGroup = dynamicDataTableGroup;
}
}