Section 5.6. Building Tables


5.6. Building Tables

JSF provides two mechanisms for generating tables. Panel grids allow you to organize multiple JSF components into an HTML table and are useful for laying out data entry forms and other pages for which you know the number of components but want to leave the mechanics of HTML formatting to the JSF engine. Data grids allow you to build tables based on variable numbers of objectslist objects, ResultSets and RowSets, and JSF DataModel objects.

5.6.1. Panel Grids

The Book Details form uses the <h:panelGroup> and <h:panelGrid> tags to group and display multiple JSF tags. The <h:panelGroup> tag is very simpleit groups a set of JSF components into a single unit. Decisions about which components to display can then be handled at the group level rather than component by component. Back in Example 5-6, we grouped an <h:panelGrid> (for book information) and an <h:panelGroup> (containing two additional panel groups for control buttons) into a parent <h:panelGroup>. The top-level group controls rendering of all book information based on whether a book is selected.

The <h:panelGrid> component allows you to apply table formatting to a set of components. The tag allows the designer to specify a number of columns and then builds a table with the specified number of columns and as many rows as are required to accommodate the set of components provided by the page designer. In our example, we have two columns and eight components, so the JSF engine renders a table with two columns and four rows:

   <h:panelGrid columnClasses="rowLabel,rowContent" columns="2">      <h:outputText value="Title:"/>      <h:outputText value="#{bookdisplayform.book.title}"/>      <h:outputText value="Author:"/>      <h:outputText value="#{bookdisplayform.book.author}"/>      <h:outputText value="ISBN:"/>      <h:outputText value="#{bookdisplayform.book.ISBN}"/>      <h:outputText value="Status:"/>      <h:outputText value=       "#{bookdisplayform.book.checkedOut ? 'Checked Out' : 'Checked In'}"/>    </h:panelGrid>

To specify Cascading Style Sheets (CSS) styles, the <h:panelGrid> tag includes four CSS-related attributes: columnClasses, rowClasses, headerClass, and footerClass, each of which specifies a CSS style. The columnClasses and rowClasses attributes accept comma-separated lists of values that repeat if more columns or rows exist than there are CSS styles specified. This allows you to do things like alternate the color of each row by specifying something like:

   <h:panelGrid rowClasses="oddRows,evenRows" columns="4">        <!-- components would go here -->   </h:panelGrid>

The <h:panelGrid> tag works only with a known number of components. To display grids with unknown numbers of components, use the <h:dataGrid> tag, which we discuss next.

Remember that neither <h:panelGroup> nor <h:panelGrid> affects non-UIComponent page content. So if you want to use a group to control whether some text is displayed, you need to display the text via <h:outputText> rather than just entering it into the JSP file.

5.6.2. Data Grids

Panel grids aren't helpful when we don't know how many rows we need to display. For the Library Administration screen, shown in Figure 5-3, we want to list all the books available and whether they're checked in and give librarians an easy way to check books in and out. Data grids allow us to iterate through a set of objects (such as a java.util.List) or the results of a SQL query and display the results in a table.

Figure 5-3. Library Administration table


Example 5-7 shows the JSP file for the Library Administration page. The important tag is the <h:dataTable> tag, which contains a set of <h:column> tags that define the contents of each column. In this example, we're using the list of books from the shared library bean, so we don't even need a special backing bean for this form.

Example 5-7. /view/adminbooks.jsp
 <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>   <html>  <f:view>  <head>     <title>Library Administration</title>     <link rel="stylesheet" type="text/css"       href='<%= request.getContextPath(  ) + "/css/app.css" %>'>  </head>  <body>     <h1>Library Administration</h1>     <hr>  <h:form>     <h:commandButton value="Return Home" action="home"/>       <h:dataTable value="#{library.bookList}"        header var="book">         <h:column>             <f:facet name="header">                 <h:outputText value="Title"/>             </f:facet>             <h:outputText value="#{book.title}"/>         </h:column>         <h:column>             <f:facet name="header">                 <h:outputText value="Author"/>             </f:facet>             <h:outputText value="#{book.author}"/>         </h:column>         <h:column>             <f:facet name="header">                 <h:outputText value="Checked Out"/>             </f:facet>             <h:selectBooleanCheckbox onclick="submit(  )"                value="#{book.checkedOut}"/>         </h:column>    </h:dataTable>  </h:form>  </body>  </f:view> </html>

The value attribute of the <h:dataTable> tag lets us specify the list of objects for the table, which are displayed one per row. As the table is rendered, the JSF engine iterates through each object on the list and creates a "temporary" variable using the name specified in the var attribute.

The <h:column> tags define the columns for the table. The body of the tag contains the components that will be included for that column in each row of the table. By including an <h:outputText> tag in the column definition, we can display a value for each object in the list.

Data tables also support facets via the <f:facet> tag. A facet allows you to define specific additional behavior for use under certain conditions. Data table columns support a header facet and a footer facet for each column. The renderer uses this information to generate header and footer rows where appropriate. In this case, we use header facets (in conjunction with the headerClass attribute) to display a set of header rows.

5.6.2.1. Editing data tables

We've also made this table editable by the extremely simple expedient of using an <h:selectBooleanCheckbox> tag to display the checkedOut property of each book. We use an onclick JavaScript handler to submit the form whenever the box is checked or unchecked. This is all we have to do to update the underlying modelJSF will take care of the rest, including associating the individual checkboxes with the appropriate Java beans. Of course, if this doesn't sound like good separation of the real data model and the application, you're right, and we'll look at that next.

If we want to make the administration view available to any user, but limit check in and check out capabilities to librarians, we can include two components in the column and use the rendered attribute to control which one is displayed:

 <h:column>     <f:facet name="header">          <h:outputText value="Checked Out"/>     </f:facet>     <h:selectBooleanCheckbox                onclick="submit(  )"                value="#{book.checkedOut}"                rendered="#{usersession.currentUser.librarian}"> />     <h:outputText value="#{book.checkedOut}"                rendered="#{not usersession.currentUser.librarian}" /> </h:column>

5.6.2.2. Data model objects

Data tables don't actually access the underlying objects directly. Instead, the underlying objects (lists, JDBC result sets, and so forth) are wrapped inside an object that extends the javax.faces.model.DataModel class. The <h:dataTable> component interacts with the DataModel implementation, which handles interaction with the model itself.

Why is this important? In our example, we're accessing the library's book list directly. That makes it easy for us to support editing by clicking and unclicking checkboxes and keeps the code to a minimum. But what if we want to support sorting by title or by author? We can't simply sort the main list every time the user sorts since that list is shared by every user in the system. By writing a custom data model (or a wrapper for one of the standard data model implementations), we can maintain a separate "view" into the underlying data for each session.



Java Enterprise in a Nutshell
Java Enterprise in a Nutshell (In a Nutshell (OReilly))
ISBN: 0596101422
EAN: 2147483647
Year: 2004
Pages: 269

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net