- Java EE 8 Application Development
- David R. Heffelfinger
- 1194字
- 2021-07-02 22:04:59
Facelets
As we mentioned in this chapter's introduction, the default view technology for JSF 2.0 and newer versions is Facelets. Facelets need to be written using standard XML. The most popular way to develop Facelet pages is to use XHTML in conjunction with JSF-specific XML namespaces. The following example shows how a typical Facelet page looks:
<?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"
xmlns:f="http://java.sun.com/jsf/core">
<h:head> <title>Enter Customer Data</title> </h:head>
<h:body>
<h:outputStylesheet library="css" name="styles.css"/>
<h:form id="customerForm">
<h:messages></h:messages>
<h:panelGrid columns="2"
columnClasses="rightAlign,leftAlign">
<h:outputLabel for="firstName" value="First Name:">
</h:outputLabel>
<h:inputText id="firstName"
label="First Name"
value="#{customer.firstName}"
required="true">
<f:validateLength minimum="2" maximum="30">
</f:validateLength>
</h:inputText>
<h:outputLabel for="lastName" value="Last Name:">
</h:outputLabel>
<h:inputText id="lastName"
label="Last Name"
value="#{customer.lastName}"
required="true">
<f:validateLength minimum="2" maximum="30">
</f:validateLength>
</h:inputText>
<h:outputLabel for="email" value="Email:">
</h:outputLabel>
<h:inputText id="email"
label="Email"
value="#{customer.email}">
<f:validateLength minimum="3" maximum="30">
</f:validateLength>
</h:inputText>
<h:panelGroup></h:panelGroup>
<h:commandButton action="confirmation" value="Save">
</h:commandButton>
</h:panelGrid>
</h:form>
</h:body> </html>
The following screenshot illustrates how the previous page renders in the browser:
The preceding screenshot, of course, was taken after entering some data in every text field; originally each text field was blank.
Pretty much any Facelet JSF page will include the two namespaces illustrated in the example. The first namespace (xmlns:h="http://xmlns.jcp.org/jsf/html") is for tags that render HTML components; by convention, the prefix h (for HTML) is used when using this tag library.
The second namespace (xmlns:f="http://xmlns.jcp.org/jsf/core") is the core JSF tag library, by convention, the prefix f (for faces) is used when using this tag library.
The first JSF-specific tags we see in the preceding example are the <h:head> and <h:body> tags. These tags are analogous to the standard HTML <head> and <body> tags, and are rendered as such when the page is displayed in the browser.
The <h:outputStylesheet> tag is used to load a CSS stylesheet from a well-known location (JSF standardizes the locations of resources, such as CSS stylesheets and JavaScript files; this will be discussed in detail later in the chapter). The value of the library attribute must correspond to the directory where the CSS file resides (this directory must be under a resources directory). The name attribute must correspond to the name of the CSS stylesheet we want to load.
The next tag we see is the <h:form> tag. This tag generates an HTML form when the page is rendered. As can be seen in the example, there is no need to specify an action or a method attribute for this tag; as a matter of fact, there is no action or method attribute for this tag. The action attribute for the rendered HTML form will be generated automatically, and the method attribute will always be post. The id attribute of <h:form> is optional; however, it is a good idea to always add it, since it makes debugging JSF applications easier.
The next tag we see is the <h:messages> tag. As its name implies, this tag is used to display any messages. As we will see shortly, JSF can automatically generate validation messages, displayed inside this tag. Additionally, arbitrary messages can be added programmatically via the addMessage() method defined in javax.faces.context.FacesContext.
The next JSF tag we see is <h:panelGrid>. This tag is roughly equivalent to an HTML table, but it works a bit differently. Instead of declaring rows (<tr>) and cells (<td>), the <h:panelGrid> tag has a columns attribute; the value of this attribute indicates the number of columns in the table rendered by this tag. As we place components inside this tag, they will be placed in a row until the number of columns defined in the columns attribute is reached, when the next component will be placed in the next row. In the example, the value of the columns attribute is 2, therefore the first two tags will be placed in the first row, the next two will be placed in the second row, and so forth.
Another interesting attribute of <h:panelGrid> is the columnClasses attribute. This attribute assigns a CSS class to each column in the rendered table. In the example, two CSS classes (separated by a comma) are used as the value for this attribute. This has the effect of assigning the first CSS class to the first column, and the second one to the second column. Had there been three or more columns, the third one would have gotten the first CSS class, the fourth one the second one, and so on, alternating between the first one and the second one. To clarify how this works, the next code snippet illustrates a portion of the source of the HTML markup generated by the preceding page:
<table> <tbody> <tr> <td class="rightAlign">
<label for="customerForm:firstName">
First Name:
</label>
</td>
<td class="leftAlign">
<input id="customerForm:firstName" type="text"
name="customerForm:firstName" />
</td> </tr> <tr> <td class="rightAlign">
<label for="customerForm:lastName">
Last Name:
</label>
</td>
<td class="leftAlign">
<input id="customerForm:lastName" type="text"
name="customerForm:lastName" />
</td> </tr> <tr> <td class="rightAlign">
<label for="customerForm:lastName">
Email:
</label>
</td>
<td class="leftAlign">
<input id="customerForm:email" type="text"
name="customerForm:email" />
</td> </tr> <tr> <td class="rightAlign"></td>
<td class="leftAlign">
<input type="submit" name="customerForm:j_idt12"
value="Save" />
</td> </tr> </tbody> </table>
Notice how each <td> tag has an alternating CSS tag—"rightAlign" or "leftAlign"; we achieved this by assigning the value "rightAlign,leftAlign" to the columnClasses attribute of <h:panelGrid>. We should note that the CSS classes we are using in our example are defined in the CSS stylesheet we loaded via the <h:outputStylesheet> we discussed earlier. The ID's of the generated markup are a combination of the ID we gave to the <h:form> component, plus the ID of each inpidual component. Notice that we didn't assign an ID to the <h:commandButton> component near the end of the page, so the JSF runtime assigned one automatically.
At this point in the example, we start adding components inside <h:panelGrid>. These components will be rendered inside the table rendered by <h:panelGrid>. As we mentioned before, the number of columns in the rendered table is defined by the columns attribute of <h:panelGrid>. Therefore, we don't need to worry about columns (or rows), we can just start adding components and they will be placed in the right place.
The next tag we see is the <h:outputLabel> tag. This tag renders as an HTML label element. Labels are associated with other components via the for attribute, whose value must match the ID of the component that the label is for.
Next, we see the <h:inputText> tag. This tag generates a text field in the rendered page. Its label attribute is used for any validation messages; it lets the user know what field the message refers to.
Although it is not mandatory for the value of the label attribute of <h:inputText> to match the label displayed on the page, it is highly recommended to use this value. In case of an error, this will let the user know exactly what field the message is referring to.
Of particular interest is the tag's value attribute. What we see as the value for this attribute is a value binding expression. What this means is that this value is tied to a property of one of the application's named beans. In the example, this particular text field is tied to a property called firstName in a named bean called customer. When a user enters a value for this text field and submits the form, the corresponding property in the named bean is updated with this value. The tag's required attribute is optional; valid values for it are true and false. If this attribute is set to true, the container will not let the user submit the form until the user enters some data for the text field. If the user attempts to submit the form without entering a required value, the page will be reloaded and an error message will be displayed inside the <h:messages> tag:
The preceding screenshot illustrates the default error message shown when the user attempts to save the form in the example without entering a value for the customer's first name. The first part of the message (First Name) is taken from the value of the label attribute of the corresponding <h:inputTextField> tag. The text of the message can be customized, as well as its style (font, color, and more.). We will cover how to do this later in the chapter.
- 自己動手寫搜索引擎
- Ext JS Data-driven Application Design
- Mastering LibGDX Game Development
- Advanced Oracle PL/SQL Developer's Guide(Second Edition)
- Scala編程實戰(原書第2版)
- Python時間序列預測
- Java高并發核心編程(卷1):NIO、Netty、Redis、ZooKeeper
- 移動增值應用開發技術導論
- Getting Started with Python
- Arduino電子設計實戰指南:零基礎篇
- Microsoft HoloLens By Example
- 虛擬現實建模與編程(SketchUp+OSG開發技術)
- Visual Basic語言程序設計上機指導與練習(第3版)
- Raspberry Pi Robotic Projects
- Learning Predictive Analytics with R