The most convenient way to provide dynamic data is in the form of data tables. Data tables are a way of displaying data when we do not know the exact number of elements in a list. For example, if we want to display employee details, we cannot know in advance how many employees will be available in the database. We cannot use the standard panelGrid tag because it creates a table with a fixed number of rows. Instead, we can use a data table ( dataTable ).
To create a data table, you must supply a "collective" bean property, that is a property of one of the following types:
Array
An instance of java.util.List
An instance of java.sql.ResultSet
An instance of javax.servlet.jsp.jstl.sql.Result
An instance of javax.faces.model.DataModel
This collective property is the property over which the data table will iterate. The contents of the data table usually visualize the properties of each single instance in the collective property.
The format of a data table is as follows:
<h:dataTable value="#{myBean.myCollectiveProp}" var="mySingleProp"> <h:column> <f:facet name="header"> <h:outputText value="Property One"/> </f:facet> <h:outputText value="#{mySingleProp.prop1}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Property Two"/> </f:facet> <h:outputText value="#{mySingleProp.prop2}"/> </h:column> </h:dataTable>
In the above data table, the table iterates over the collective property myCollectiveProp , which consists of single instances named mySingleProp . Accordingly, the two columns of the table display the two properties of each individual instance.
In data tables, elements are described according to the column they belong to, unlike with HTML tables, where components are described according to the row they belong to.
For the creation of the following page, we use a data table:
The JSP source code for this table is:
<h:dataTable value="#{departmentList.allDepartments}" var="dept" styleClass="ftable" columnClasses="tabletxt" headerClass="ftabletxt" width="100%"> <h:column> <f:facet name="header"> <h:panelGroup> <f:verbatim> <link href="../styles/ejb3demo_styles.css" rel="stylesheet" type="text/css"/> </f:verbatim> <h:outputText value="Department ID"/> </h:panelGroup> </f:facet> <h:outputText value="#{dept.department.departmentId}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Department Name"/> </f:facet> <h:outputText value="#{dept.department.name}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Number of Employees"/> </f:facet> <h:outputText value="#{dept.numberOfEmployees}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Department Manager"/> </f:facet> <h:outputText value="#{dept.nameOfManager}"></h:outputText> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Select"/> </f:facet> <h:selectBooleanCheckbox value="#{dept.selected}"/> </h:column> </h:dataTable>
In some cases, it is necessary to use data tables inside other data tables. This is the case with the Department Details page (see the graphic below): All selected departments were listed in a root data table, and the details for each department were listed in an internal data table.
Here is the more sophisticated data table source code:
<h:form id="department"> <h:dataTable value="#{departmentList.selectedDepartments}" var="dept" cellspacing="3" width="100%"> <h:column> <h:panelGrid width="100%" columns="1" cellspacing="2"> <h:panelGrid columns="2" width="100%" styleClass="ftable" cellspacing="1" headerClass="ftabletxt"> <f:facet name="header"> <h:panelGroup> <f:verbatim>Department Details</f:verbatim> </h:panelGroup> </f:facet> <h:column> <h:outputText value="Department Name" styleClass="tabletxt"/> </h:column> <h:column> <h:outputText value="#{dept.department.name}" styleClass="tabletxt"/> </h:column> <h:column> <h:outputText value="Department Manager" styleClass="tabletxt"/> </h:column> <h:column> <h:outputText value="#{dept.nameOfManager}" styleClass="tabletxt"/> </h:column> </h:panelGrid> <h:dataTable value="#{dept.department.employees}" var="emp" styleClass="ftable" rowClasses="sht1, tabletxt" width="100%" border="0" headerClass="ftabletxt"> <f:facet name="header"> <h:panelGroup> <f:verbatim>Employees</f:verbatim> </h:panelGroup> </f:facet> <h:column> <f:facet name="header"><h:outputText value="ID"/></f:facet> <h:outputText value="#{emp.employeeId}"/> </h:column> <h:column> <f:facet name="header"><h:outputText value="First Name"/></f:facet> <h:outputText value="#{emp.firstName}"/> </h:column> <h:column> <f:facet name="header"><h:outputText value="Last Name"/></f:facet> <h:inputText id="LastName" value="#{emp.lastName}" styleClass="inputt" required="true"> <f:validateLength maximum="30"/> </h:inputText> </h:column> <h:column> <f:facet name="header"><h:outputText value="Email"/></f:facet> <h:inputText id="Email" value="#{emp.EMail}" styleClass="inputt" required="true"> <f:validateLength maximum="50"/> </h:inputText> </h:column> <h:column> <f:facet name="header"><h:outputText value="Salary"/></f:facet> <h:inputText id="Salary" value="#{emp.salary}" styleClass="inputt" required="true"> <f:validateDoubleRange minimum="0" maximum="10000000"/> </h:inputText> </h:column> <h:column> <f:facet name="header"><h:outputText value="Currency"/></f:facet> <h:outputText value="#{emp.currency}"/> </h:column> </h:dataTable> </h:panelGrid> </h:column> </h:dataTable> <h:commandButton styleClass="fbc" value="Set Employee Data" action="#{departmentList.updateDepartments}"/> <h:messages styleClass="error_msg"/> </h:form>
There are two data tables in this example. The first one iterates over the selected departments from the previous view and contains the second table, which iterates over the employees available in the selected department.