Introduction to Facelets
We are working on a fresh, updated Jakarta EE Tutorial. This section hasn’t yet been updated. |
The term Facelets refers to the view declaration language for Jakarta Faces technology. Facelets is a part of the Jakarta Faces specification and also the preferred presentation technology for building Jakarta Faces technology–based applications. Jakarta Server Pages technology, previously used as the presentation technology for Jakarta Faces, does not support all the new features available in Jakarta Faces in the Jakarta EE platform. Jakarta Server Pages technology is considered to be a deprecated presentation technology for Jakarta Faces.
What Is Facelets?
Facelets is a powerful but lightweight page declaration language that is used to build Jakarta Faces views using HTML style templates and to build component trees. Facelets features include the following:
-
Use of XHTML for creating web pages
-
Support for Facelets tag libraries in addition to Jakarta Faces and JSTL tag libraries
-
Support for the Expression Language (EL)
-
Templating for components and pages
The advantages of Facelets for large-scale development projects include the following:
-
Support for code reuse through templating and composite components
-
Functional extensibility of components and other server-side objects through customization
-
Faster compilation time
-
Compile-time EL validation
-
High-performance rendering
In short, the use of Facelets reduces the time and effort that needs to be spent on development and deployment.
Facelets views are usually created as XHTML pages.
Jakarta Faces implementations support XHTML pages created in conformance with the XHTML Transitional Document Type Definition (DTD), as listed at https://www.w3.org/TR/xhtml1/#a_dtd_XHTML-1.0-Transitional.
By convention, web pages built with XHTML have an .xhtml
extension.
Jakarta Faces technology supports various tag libraries to add components to a web page. To support the Jakarta Faces tag library mechanism, Facelets uses XML namespace declarations. Tag Libraries Supported by Facelets lists the tag libraries supported by Facelets.
Tag Library | URI | Prefix | Example | Contents |
---|---|---|---|---|
Jakarta Faces Facelets Tag Library |
jakarta.faces.facelets |
|
|
Tags for templating |
Jakarta Faces HTML Tag Library |
jakarta.faces.html |
|
|
Jakarta Faces component tags for all |
Jakarta Faces Core Tag Library |
jakarta.faces.core |
|
|
Tags for Jakarta Faces custom actions that are independent of any particular render kit |
Pass-through Elements Tag Library |
jakarta.faces |
|
|
Tags to support HTML5-friendly markup |
Pass-through Attributes Tag Library |
jakarta.faces.passthrough |
|
|
Tags to support HTML5-friendly markup |
Composite Component Tag Library |
jakarta.faces.composite |
|
|
Tags to support composite components |
JSTL Core Tag Library |
jakarta.tags.core |
|
|
JSTL 1.2 Core Tags |
JSTL Functions Tag Library |
jakarta.tags.functions |
|
|
JSTL 1.2 Functions Tags |
Facelets provides two namespaces to support HTML5-friendly markup. For details, see HTML5-Friendly Markup.
Facelets supports tags for composite components, for which you can declare custom prefixes. For more information on composite components, see Composite Components.
The namespace prefixes shown in the table are conventional, not mandatory. As is always the case when you declare an XML namespace, you can specify any prefix in your Facelets page. For example, you can declare the prefix for the composite component tag library as
xmlns:composite="jakarta.faces.composite"
instead of as
xmlns:cc="jakarta.faces.composite"
Based on the Jakarta Faces support for Expression Language (EL) syntax, Facelets uses EL expressions to reference properties and methods of managed beans. EL expressions can be used to bind component objects or values to methods or properties of managed beans that are used as backing beans. For more information on using EL expressions, see Using the EL to Reference Managed Beans.
The Lifecycle of a Facelets Application
The Jakarta Faces specification defines the lifecycle of a Jakarta Faces application. For more information on this lifecycle, see The Lifecycle of a Jakarta Faces Application. The following steps describe that process as applied to a Facelets-based application.
-
When a client, such as a browser, makes a new request to a page that is created using Facelets, a new component tree or
jakarta.faces.component.UIViewRoot
is created and placed in theFacesContext
. -
The
UIViewRoot
is applied to the Facelets, and the view is populated with components for rendering. -
The newly built view is rendered back as a response to the client.
-
On rendering, the state of this view is stored for the next request. The state of input components and form data is stored.
-
The client may interact with the view and request another view or change from the Jakarta Faces application. At this time, the saved view is restored from the stored state.
-
The restored view is once again passed through the Jakarta Faces lifecycle, which eventually will either generate a new view or re-render the current view if there were no validation problems and no action was triggered.
-
If the same view is requested, the stored view is rendered once again.
-
If a new view is requested, then the process described in Step 2 is continued.
-
The new view is then rendered back as a response to the client.
Developing a Simple Facelets Application: The guessnumber-faces Example Application
This section describes the general steps involved in developing a Jakarta Faces application. The following tasks are usually required:
-
Developing the managed beans
-
Creating the pages using the component tags
-
Defining page navigation
-
Mapping the
FacesServlet
instance -
Adding managed bean declarations
Creating a Facelets Application
The example used in this tutorial is the guessnumber-faces
application.
The application presents you with a page that asks you to guess a number from 0 to 10, validates your input against a random number, and responds with another page that informs you whether you guessed the number correctly or incorrectly.
The source code for this application is in the jakartaee-examples/tutorial/web/faces/guessnumber-faces/
directory.
Developing a Managed Bean
In a typical Jakarta Faces application, each page of the application connects to a managed bean that serves as a backing bean. The backing bean defines the methods and properties that are associated with the components. In this example, both pages use the same backing bean.
The following managed bean class, UserNumberBean.java
, generates a random number from 0 to 10 inclusive:
package ee.jakarta.tutorial.guessnumber;
import java.io.Serializable;
import java.util.Random;
import jakarta.annotation.PostConstruct;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
@Named
@ViewScoped
public class UserNumberBean implements Serializable {
private static final long serialVersionUID = 1L;
private static final int MINIMUM = 0;
private static final int MAXIMUM = 10;
private int randomInt;
private Integer userNumber;
private String response;
@PostConstruct
public void init() {
randomInt = new Random().nextInt(maximum + 1);
// Print number to server log.
System.out.println("Duke's number: " + randomInt);
}
public void guess() {
if (userNumber.compareTo(randomInt) != 0) {
response = "Sorry, " + userNumber + " is incorrect.";
}
else {
response = "Yay! You got it!";
}
}
public Integer getUserNumber() {
return userNumber;
}
public void setUserNumber(Integer userNumber) {
this.userNumber = userNumber;
}
public String getResponse() {
return response;
}
public int getMinimum() {
return MINIMUM;
}
public int getMaximum() {
return MAXIMUM;
}
}
Note the use of the @Named
annotation, which makes the managed bean accessible through the EL.
The @ViewScoped
annotation registers the bean scope as view
to enable you to reuse the same bean instance as long as you interact with the same web page without navigating away.
Creating Facelets Views
To create a page or view, you add components to the pages, wire the components to backing bean values and properties, and register converters, validators, or listeners on the components.
For the example application, XHTML web pages serve as the front end.
The page of the example application is a page called greeting.xhtml
.
A closer look at various sections of this web page provides more information.
The first section of the web page declares the document type of the generated HTML output, which is HTML5:
<!DOCTYPE html>
The next section specifies the language of the text embedded in the generated HTML output and then declares the XML namespace for the tag libraries that are used in the web page:
<html lang="en"
xmlns:h="jakarta.faces.html"
xmlns:f="jakarta.faces.core">
The next section uses various tags to insert components into the web page:
<h:head>
<title>Guess Number Facelets Application</title>
<h:outputStylesheet name="css/default.css"/>
</h:head>
<h:body>
<h:form>
<h:graphicImage name="images/wave.svg"
alt="Duke waving his hand"
width="100" height="100" />
<h1>
Hi, my name is Duke. I am thinking of a number from
#{userNumberBean.minimum} to #{userNumberBean.maximum}.
Can you guess it?
</h1>
<div class="input">
<h:outputLabel id="userNumberLabel" for="userNumber"
value="Enter a number from 0 to 10:" />
<h:inputText id="userNumber" required="true"
value="#{userNumberBean.userNumber}">
<f:validateLongRange minimum="#{userNumberBean.minimum}"
maximum="#{userNumberBean.maximum}" />
</h:inputText>
<h:message id="userNumberMessage" for="userNumber" />
</div>
<div class="actions">
<h:commandButton id="guess" value="Guess"
action="#{userNumberBean.guess}">
<f:ajax execute="@form"
render="userNumberMessage response" />
</h:commandButton>
</div>
<div class="output">
<h:outputText id="response" value="#{userNumberBean.response}" />
</div>
</h:form>
</h:body>
Note the use of the following tags:
-
Facelets HTML tags (those beginning with
h:
) to add components -
The Facelets core tag
f:validateLongRange
to validate the user input
An h:inputText
tag accepts user input and sets the value of the managed bean property userNumber
through the EL expression #{userNumberBean.userNumber}
.
The input value is validated for value range by the Jakarta Faces standard validator tag f:validateLongRange
.
The image file, wave.svg
, is added to the page as a resource, as is the style sheet.
For more details about the resources facility, see Web Resources.
An h:commandButton
tag with the ID guess
starts validation of the input data when a user clicks the button.
Using f:ajax
, the tag updates the h:message
associated with the h:inputText
so that it can display any validation error messages.
Also the h:outputText
is being updated which shows the response to your input.
Configuring the Application
Configuring a Jakarta Faces application involves mapping the Faces Servlet in the web deployment descriptor file, such as a web.xml
file, and possibly adding managed bean declarations, navigation rules, and resource bundle declarations to the application configuration resource file, faces-config.xml
.
If you are using NetBeans IDE, a web deployment descriptor file is automatically created for you.
In such an IDE-created web.xml
file, change the default greeting page, which is index.xhtml
, to greeting.xhtml
.
Here is an example web.xml
file, showing this change in bold.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
version="6.0">
<context-param>
<param-name>jakarta.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>jakarta.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>greeting.xhtml</welcome-file>
</welcome-file-list>
</web-app>
Note the use of the context parameter PROJECT_STAGE
.
This parameter identifies the status of a Jakarta Faces application in the software lifecycle.
The stage of an application can affect the behavior of the application.
For example, if the project stage is defined as Development
, debugging information is automatically generated for the user.
If not defined by the user, the default project stage is Production
.
Running the guessnumber-faces Facelets Example
You can use either NetBeans IDE or Maven to build, package, deploy, and run the guessnumber-faces
example.
To Build, Package, and Deploy the guessnumber-faces Example Using NetBeans IDE
-
Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).
-
From the File menu, choose Open Project.
-
In the Open Project dialog box, navigate to:
jakartaee-examples/tutorial/web/faces
-
Select the
guessnumber-faces
folder. -
Click Open Project.
-
In the Projects tab, right-click the
guessnumber-faces
project and select Build.This option builds the example application and deploys it to your GlassFish Server instance.
To Build, Package, and Deploy the guessnumber-faces Example Using Maven
-
Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).
-
In a terminal window, go to:
jakartaee-examples/tutorial/web/faces/guessnumber-faces/
-
Enter the following command:
mvn install
This command builds and packages the application into a WAR file,
guessnumber-faces.war
, that is located in thetarget
directory. It then deploys it to the server.
To Run the guessnumber-faces Example
-
Open a web browser.
-
Enter the following URL in your web browser:
http://localhost:8080/guessnumber-faces
-
In the field, enter a number from 0 to 10 and click Submit.
Another page appears, reporting whether your guess is correct or incorrect.
-
If you guessed incorrectly, click Back to return to the main page.
You can continue to guess until you get the correct answer, or you can look in the server log, where the
UserNumberBean
constructor displays the correct answer.
Using Facelets Templates
Jakarta Faces technology provides the tools to implement user interfaces that are easy to extend and reuse. Templating is a useful Facelets feature that allows you to create a page that will act as the base, or template, for the other pages in an application. By using templates, you can reuse code and avoid recreating similarly constructed pages. Templating also helps in maintaining a standard look and feel in an application with a large number of pages.
Facelets Templating Tags lists Facelets tags that are used for templating and their respective functionality.
Tag | Function |
---|---|
|
Defines a component that is created and added to the component tree. |
|
Defines a page composition that optionally uses a template. Content outside of this tag is ignored. |
|
Defines a debug component that is created and added to the component tree. |
|
Similar to the composition tag but does not disregard content outside this tag. |
|
Defines content that is inserted into a page by a template. |
|
Similar to the component tag but does not disregard content outside this tag. |
|
Encapsulates and reuses content for multiple pages. |
|
Inserts content into a template. |
|
Used to pass parameters to an included file. |
|
Used as an alternative for loop tags, such as |
|
Removes content from a page. |
For more information on Facelets templating tags, see the Jakarta Faces Facelets Tag Library documentation.
The Facelets tag library includes the main templating tag ui:insert
.
A template page that is created with this tag allows you to define a default structure for a page.
A template page is used as a template for other pages, usually referred to as client pages.
Here is an example of a template saved as /WEB-INF/templates/template.xhtml
:
<!DOCTYPE html>
<html xmlns:ui="jakarta.faces.facelets"
xmlns:h="jakarta.faces.html">
<h:head>
<title>Facelets Template</title>
<h:outputStylesheet name="css/default.css"/>
<h:outputStylesheet name="css/layout.css"/>
</h:head>
<h:body>
<div id="top">
<ui:insert name="top">Top Section</ui:insert>
</div>
<div>
<div id="left">
<ui:insert name="left">Left Section</ui:insert>
</div>
<div id="content">
<ui:insert name="content">Main Content</ui:insert>
</div>
</div>
</h:body>
</html>
The example page defines an XHTML page that is divided into three sections: a top section, a left section, and a main section. The sections have style sheets associated with them. The same structure can be reused for the other pages of the application.
The client page invokes the template by using the ui:composition
tag.
In the following example, a client page named templateclient.xhtml
invokes the template page named template.xhtml
from the preceding example.
A client page allows content to be inserted with the help of the ui:define
tag.
<ui:composition template="/WEB-INF/templates/template.xhtml">
xmlns:ui="jakarta.faces.facelets"
xmlns:h="jakarta.faces.html">
<ui:define name="top">
<h1>Welcome to Template Client Page</h1>
</ui:define>
<ui:define name="left">
<p>You are in the Left Section.</p>
</ui:define>
<ui:define name="content">
<header>
<h:graphicImage name="images/wave.svg"
alt="Duke waving his hand"
width="100" height="100" />
</header>
<p>You are in the Main Content Section.</p>
</ui:define>
</ui:composition>
You can use NetBeans IDE to create Facelets template and client pages. For more information on creating these pages, see https://netbeans.org/kb/docs/web/jsf20-intro.html.
Composite Components
Jakarta Faces technology offers the concept of composite components with Facelets. A composite component is a special type of template that acts as a component.
Any component is essentially a piece of reusable code that behaves in a particular way. For example, an input component accepts user input. A component can also have validators, converters, and listeners attached to it to perform certain defined actions.
A composite component consists of a collection of markup tags and other existing components. This reusable, user-created component has a customized, defined functionality and can have validators, converters, and listeners attached to it like any other component.
With Facelets, any XHTML page that contains markup tags and other components can be converted into a composite component. Using the resources facility, the composite component can be stored in a library that is available to the application from the defined resources location.
Composite Component Tags lists the most commonly used composite tags and their functions.
Tag | Function |
---|---|
|
Declares the usage contract for a composite component. The composite component can be used as a single component whose feature set is the union of the features declared in the usage contract. |
|
Defines the implementation of the composite component.
If a |
|
Declares an attribute that may be given to an instance of the composite component in which this tag is declared. |
|
Any child components or template text within the composite component tag in the using page will be reparented into the composite component at the point indicated by this tag’s placement within the |
|
Declares that the composite component whose contract is declared by the |
|
Declares that the composite component whose contract is declared by the |
|
Declares that the composite component whose contract is declared by the |
For more information and a complete list of Facelets composite tags, see the Jakarta Faces Facelets Tag Library documentation.
The following example shows a composite component that renders an form field with a label, input and message component:
<ui:component xmlns:ui="jakarta.faces.facelets"
xmlns:cc="jakarta.faces.composite"
xmlns:h="jakarta.faces.html">
<cc:interface>
<cc:attribute name="label" required="true" />
<cc:attribute name="value" required="true" />
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}" class="field">
<h:outputLabel for="input" value="#{cc.attrs.label}" />
<h:inputText id="input" value="#{cc.attrs.value}" />
<h:message for="input" />
</div>
</cc:implementation>
</ui:component>
Note the use of cc.attrs.value
when defining the value of the outputLabel
and inputText
components.
The word cc
in Jakarta Faces is a reserved word for composite components.
The #{cc.attrs.attribute-name}
expression is used to access the attributes defined for the composite component’s interface, which in this case happens to be value
.
The preceding example content is stored as a file named field.xhtml
in a folder named resources/mycomponents
, under the application web root directory.
This directory is considered a library by Jakarta Faces, and a component can be accessed from such a library.
The mycomponents
folder name is free to your choice.
For more information on resources, see Web Resources.
The web page that uses this composite component is generally called a using page.
The using page includes a reference to the composite component, in the xml
namespace declarations:
<!DOCTYPE html>
<html xmlns:h="jakarta.faces.html"
xmlns:my="jakarta.faces.composite/mycomponents">
<h:head>
<title>Using a sample composite component</title>
</h:head>
<h:body>
<h:form>
<my:field id="email"
label="Enter your email address"
value="#{bean.email}" />
</h:form>
</h:body>
</html>
The local composite component library is defined in the xmlns
namespace with the declaration xmlns:my="jakarta.faces.composite/mycomponents"
.
The my
XML namespace are free to your choice. The /mycomponents
part must represent the folder name where the composite component files are located.
The component itself is accessed through the my:field
tag.
The preceding example content can be stored as a web page named userpage.xhtml
under the web root directory.
When compiled and deployed on a server, it can be accessed with the following URL:
http://localhost:8080/application-name/userpage.xhtml
See Composite Components: Advanced Topics and an Example for more information and an example.
Web Resources
Web resources are any software artifacts that the web application requires for proper rendering, including images, script files, and any user-created component libraries. Resources must be collected in a standard location, which can be one of the following.
-
A resource packaged in the web application root must be in a subdirectory of a
resources
directory at the web application root:resources/resource-identifier
. -
A resource packaged in the web application’s classpath must be in a subdirectory of the
META-INF/resources
directory within a web application:META-INF/resources/resource-identifier
. You can use this file structure to package resources in a JAR file bundled in the web application.
The Jakarta Faces runtime will look for the resources in the preceding listed locations, in that order.
Resource identifiers are unique strings that conform to the following format (all on one line):
[locale-prefix/][library-name/][library-version/]resource-name[/resource-version]
Elements of the resource identifier in brackets ([]
) are optional, indicating that only a resource-name, which is usually a file name, is a required element.
For example, the most common way to specify a style sheet, image, or script is to use the library
and name
attributes, as in the following tag from the guessnumber-faces
example:s
<h:outputStylesheet library="css" name="default.css"/>
This tag specifies that the default.css
style sheet is in the directory web/resources/css
.
You can also specify the location of an image using the following syntax, also from the guessnumber-faces
example:
<h:graphicImage value="#{resource['images:wave.med.gif']}"/>
This tag specifies that the image named wave.med.gif
is in the directory web/resources/images
.
Resources can be considered as a library location.
Any artifact, such as a composite component or a template that is stored in the resources
directory, becomes accessible to the other application components, which can use it to create a resource instance.
Relocatable Resources
You can place a resource tag in one part of a page and specify that it be rendered in another part of the page.
To do this, you use the target
attribute of a tag that specifies a resource.
Acceptable values for this attribute are as follows.
-
“head” renders the resource in the
head
element. -
“body” renders the resource in the
body
element. -
“form” renders the resource in the
form
element.
For example, the following h:outputScript
tag is placed within an h:form
element, but it renders the JavaScript in the head
element:
<h:form>
<h:outputScript name="myscript.js" library="mylibrary" target="head"/>
</h:form>
The h:outputStylesheet
tag also supports resource relocation, in a similar way.
Relocatable resources are essential for composite components that use stylesheets and can also be useful for composite components that use JavaScript. See The compositecomponentexample Example Application for an example.
Resource Library Contracts
Resource library contracts allow you to define a different look and feel for different parts of one or more applications, instead of either having to use the same look and feel for all or having to specify a different look on a page-by-page basis.
To do this, you create a contracts
section of your web application.
Within the contracts
section, you can specify any number of named areas, each of which is called a contract.
Within each contract you can specify resources such as template files, stylesheets, JavaScript files, and images.
For example, you could specify two contracts named c1
and c2
, each of which uses a template and other files:
src/main/webapp
WEB-INF/
contracts
c1
template.xhtml
style.css
myImg.gif
myJS.js
c2
template.xhtml
style2.css
img2.gif
JS2.js
index.xhtml
...
One part of the application can use c1
, while another can use c2
.
Another way to use contracts is to specify a single contract that contains multiple templates:
src/main/webapp
contracts
myContract
template1.xhtml
template2.xhtml
style.css
img.png
img2.png
You can package a resource library contract in a JAR file for reuse in different applications.
If you do so, the contracts must be located under META-INF/contracts
.
You can then place the JAR file in the WEB-INF/lib
directory of an application.
This means that the application would be organized as follows:
src/main/webapp/
WEB-INF/lib/myContract.jar
...
You can specify the contract usage within an application’s faces-config.xml
file, under the resource-library-contracts
element.
You need to use this element only if your application uses more than one contract, however.
The hello1-rlc Example Application
The hello1-rlc
example modifies the simple hello1
example from A Web Module That Uses Jakarta Faces Technology: The hello1 Example to use two resource library contracts.
Each of the two pages in the application uses a different contract.
The managed bean for hello1-rlc
, Hello.java
, is identical to the one for hello1
(except that it replaces the @Named
and @RequestScoped
annotations with @Model
).
The source code for this application is in the jakartaee-examples/tutorial/web/faces/hello1-rlc/
directory.
Configuring the hello1-rlc Example
The faces-config.xml
file for the hello1-rlc
example contains the following elements:
<resource-library-contracts>
<contract-mapping>
<url-pattern>/reply/*</url-pattern>
<contracts>reply</contracts>
</contract-mapping>
<contract-mapping>
<url-pattern>*</url-pattern>
<contracts>hello</contracts>
</contract-mapping>
</resource-library-contracts>
The contract-mapping
elements within the resource-library-contracts
element map each contract to a different set of pages within the application.
One contract, named reply
, is used for all pages under the reply
area of the application (/reply/*
).
The other contract, hello
, is used for all other pages in the application (*
).
The application is organized as follows:
hello1-rlc
pom.xml
src/main/java/jakarta/tutorial/hello1rlc/Hello.java
src/main/webapp
WEB-INF
faces-config.xml
web.xml
contracts
hello
default.css
duke.handsOnHips.gif
template.xhtml
reply
default.css
duke.thumbsup.gif
template.xhtml
reply
response.xhtml
greeting.xhtml
The web.xml
file specifies the welcome-file
as greeting.xhtml
.
Because it is not located under src/main/webapp/reply
, this Facelets page uses the hello
contract, whereas src/main/webapp/reply/response.xhtml
uses the reply
contract.
The Facelets Pages for the hello1-rlc Example
The greeting.xhtml
and response.xhtml
pages have identical code calling in their templates:
<ui:composition template="/template.xhtml">
The template.xhtml
files in the hello
and reply
contracts differ only in two respects: the placeholder text for the title
element ("Hello Template" and "Reply Template") and the graphic that each specifies.
The default.css
stylesheets in the two contracts differ in only one respect: the background color specified for the body
element.
To Build, Package, and Deploy the hello1-rlc Example Using NetBeans IDE
-
Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).
-
From the File menu, choose Open Project.
-
In the Open Project dialog box, navigate to:
jakartaee-examples/tutorial/web/faces
-
Select the
hello1-rlc
folder. -
Click Open Project.
-
In the Projects tab, right-click the
hello1-rlc
project and select Build.This option builds the example application and deploys it to your GlassFish Server instance.
To Build, Package, and Deploy the hello1-rlc Example Using Maven
-
Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).
-
In a terminal window, go to:
jakartaee-examples/tutorial/web/faces/hello1-rlc/
-
Enter the following command:
mvn install
This command builds and packages the application into a WAR file,
hello1-rlc.war
, that is located in thetarget
directory. It then deploys it to your GlassFish Server instance.
To Run the hello1-rlc Example
-
Enter the following URL in your web browser:
http://localhost:8080/hello1-rlc
-
The
greeting.xhtml
page looks just like the one fromhello1
except for its background color and graphic. -
In the text field, enter your name and click Submit.
-
The response page also looks just like the one from
hello1
except for its background color and graphic.The page displays the name you submitted. Click Back to return to the
greeting.xhtml
page.
HTML5-Friendly Markup
When you want to produce user interface features for which HTML does not have its own elements, you can create a custom Jakarta Faces component and insert it in your Facelets page. This mechanism can cause a simple element to create complex web code. However, creating such a component is a significant task (see Creating Custom UI Components and Other Custom Objects).
HTML5 offers new elements and attributes that can make it unnecessary to write your own components. It also provides many new capabilities for existing components. Jakarta Faces technology supports HTML5 not by introducing new UI components that imitate HTML5 ones but by allowing you to use HTML5 markup directly. It also allows you to use Jakarta Faces attributes within HTML5 elements. Jakarta Faces technology support for HTML5 falls into two categories:
-
Pass-through elements
-
Pass-through attributes
The effect of the HTML5-friendly markup feature is to offer the Facelets page author almost complete control over the rendered page output, rather than having to pass this control off to component authors. You can mix and match Jakarta Faces and HTML5 components and elements as you see fit.
Using Pass-Through Elements
Pass-through elements allow you to use HTML5 tags and attributes but to treat them as equivalent to Jakarta Faces components associated with a server-side UIComponent
instance.
To make an element that is not a Jakarta Faces element a pass-through element, specify at least one of its attributes using the jakarta.faces
namespace.
For example, the following code declares the namespace with the short name faces
:
<html ... xmlns:faces="jakarta.faces"
...
<input type="email" faces:id="email" name="email"
value="#{reservationBean.email}" required="required"/>
Here, the faces
prefix is placed on the id
attribute so that the HTML5 input tag’s attributes are treated as part of the Facelets page.
This means that, for example, you can use EL expressions to retrieve managed bean properties.
How Facelets Renders HTML5 Elements shows how pass-through elements are rendered as Facelets tags. The faces implementation uses the element name and the identifying attribute to determine the corresponding Facelets tag that will be used in the server-side processing. The browser, however, interprets the markup that the page author has written.
HTML5 Element Name | Identifying Attribute | Facelets Tag |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Using Pass-Through Attributes
Pass-through attributes are the converse of pass-through elements.
They allow you to pass attributes that are not Jakarta Faces attributes through to the browser without interpretation.
If you specify a pass-through attribute in a Jakarta Faces UIComponent
, the attribute name and value are passed straight through to the browser without being interpreted by Jakarta Faces components or renderers.
There are several ways to specify pass-through attributes.
-
Use the Jakarta Faces namespace for pass-through attributes to prefix the attribute names within a Jakarta Faces component. For example, the following code declares the namespace with the short name
p
, then passes thetype
,min
,max
,required
, andtitle
attributes through to the HTML5input
component:<html ... xmlns:p="jakarta.faces.passthrough" ... <h:form prependId="false"> <h:inputText id="nights" p:type="number" value="#{bean.nights}" p:min="1" p:max="30" p:required="required" p:title="Enter a number between 1 and 30 inclusive."> ...
This will cause the following markup to be rendered (assuming that
bean.nights
has a default value set to 1):<input id="nights" type="number" value="1" min="1" max="30" required="required" title="Enter a number between 1 and 30 inclusive.">
-
To pass a single attribute, nest the
f:passThroughAttribute
tag within a component tag. For example:<h:inputText value="#{user.email}"> <f:passThroughAttribute name="type" value="email" /> </h:inputText>
This code would be rendered similarly to the following:
<input value="me@me.com" type="email" />
-
To pass a group of attributes, nest the
f:passThroughAttributes
tag within a component tag, specifying an EL value that must evaluate to aMap<String, Object>
. For example:<h:inputText value="#{bean.nights}"> <f:passThroughAttributes value="#{bean.nameValuePairs}" /> </h:inputText>
If the bean used the following
Map
declaration and initialized the map in the constructor as follows, the markup would be similar to the output of the code that uses the pass-through attribute namespace:private Map<String, Object> nameValuePairs; ... public Bean() { this.nameValuePairs = new HashMap<>(); this.nameValuePairs.put("type", "number"); this.nameValuePairs.put("min", "1"); this.nameValuePairs.put("max", "30"); this.nameValuePairs.put("required", "required"); this.nameValuePairs.put("title", "Enter a number between 1 and 4 inclusive."); }
The reservation Example Application
The reservation
example application provides a set of HTML5 input
elements of various types to simulate purchasing tickets for a theatrical event.
It consists of two Facelets pages, reservation.xhtml
and confirmation.xhtml
, and a backing bean, ReservationBean.java
.
The pages use both pass-through attributes and pass-through elements.
The source code for this application is in the jakartaee-examples/tutorial/web/faces/reservation/
directory.
The Facelets Pages for the reservation Application
The first important feature of the Facelets pages for the reservation
application is the DOCTYPE
header.
The facelets pages for this application begin simply with the following DOCTYPE
header, which indicates that the XHTML-generated result is an HTML5 page:
<!DOCTYPE html>
The namespace declarations in the html
element of the reservation.xhtml
page specify both the faces
and the passthrough
namespaces:
<html lang="en"
xmlns:faces="jakarta.faces"
xmlns:f="jakarta.faces.core"
xmlns:h="jakarta.faces.html"
xmlns:p="jakarta.faces.passthrough">
Next, an h:head
tag followed by an h:outputStylesheet
tag within the h:body
tag illustrates the use of a relocatable resource (as described in Relocatable Resources):
<h:head>
<title>Reservation Application</title>
</h:head>
<h:body>
<h:outputStylesheet name="css/stylesheet.css" target="head" />
The reservation.xhtml
page uses a HTML5-specific input
element type on h:inputText
, which is date
.
<h:inputText id="date" type="date"
value="#{reservationBean.date}" required="true"
title="Enter or choose a date." />
The field for the number of tickets uses the f:passThroughAttributes
tag to pass a Map
defined in the managed bean.
It also recalculates the total in response to a change in the field:
<h:inputText id="tickets" value="#{reservationBean.tickets}">
<f:passThroughAttributes value="#{reservationBean.ticketAttrs}"/>
<f:ajax listener="#{reservationBean.calculateTotal}"
render="total" />
</h:inputText>
The field for the price specifies the min
, max
and step
as a pass-through attribute of the h:inputText
element, offering a range of four ticket prices.
Here, the p
prefix on the HTML5 attributes passes them through to the browser uninterpreted by the Jakarta Faces input component:
<h:inputText id="price" type="number"
value="#{reservationBean.price}" required="true"
p:min="80" p:max="120" p:step="20"
title="Enter a price: 80, 100, 120, or 140.">
<f:ajax listener="#{reservationBean.calculateTotal}"
render="total" />
</h:inputText>
The output of the calculateTotal
method that is specified as the listener for the Ajax event is rendered in the output element whose id
and name
value is total
.
See Using Ajax with Jakarta Faces Technology, for more information.
The second Facelets page, confirmation.xhtml
, uses a pass-through output
element to display the values entered by the user and provides a Facelets h:commandButton
tag to allow the user to return to the reservation.xhtml
page.
The Managed Bean for the reservation Application
The session-scoped managed bean for the reservation application, ReservationBean.java
, contains properties for all the elements on the Facelets pages.
It also contains two methods, calculateTotal
and clear
, that act as listeners for Ajax events on the reservation.xhtml
page.
To Build, Package, and Deploy the reservation Example Using NetBeans IDE
-
Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).
-
From the File menu, choose Open Project.
-
In the Open Project dialog box, navigate to:
jakartaee-examples/tutorial/web/faces
-
Select the
reservation
folder. -
Click Open Project.
-
In the Projects tab, right-click the
reservation
project and select Build.This option builds the example application and deploys it to your GlassFish Server instance.
To Build, Package, and Deploy the reservation Example Using Maven
-
Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).
-
In a terminal window, go to:
jakartaee-examples/tutorial/web/faces/reservation/
-
Enter the following command:
mvn install
This command builds and packages the application into a WAR file,
reservation.war
, that is located in thetarget
directory. It then deploys the WAR file to your GlassFish Server instance.
To Run the reservation Example
At the time of the publication of this tutorial, the browser that most fully implements HTML5 is Google Chrome, and it is recommended that you use it to run this example. Other browsers are catching up, however, and may work equally well by the time you read this.
-
Enter the following URL in your web browser:
http://localhost:8080/reservation
-
Enter information in the fields of the
reservation.xhtml
page.The Performance Date field has a date field with up and down arrows that allow you to increment and decrement the month, day, and year as well as a larger down arrow that brings up a date editor in calendar form.
The Number of Tickets and Ticket Price fields also have up and down arrows that allow you to increment and decrement the values within the allowed range and steps. The Estimated Total changes when you change either of these two fields.
Email addresses and dates are checked for format, but not for validity (you can make a reservation for a past date, for instance).
-
Click Make Reservation to complete the reservation or Clear to restore the fields to their default values.
-
If you click Make Reservation, the
confirmation.xhtml
page appears, displaying the submitted values.Click Back to return to the
reservation.xhtml
page.