HTML5-Friendly Markup
Java Platform, Enterprise Edition (Java EE) 8
The Java EE Tutorial

Previous Next Contents

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 JavaServer 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 Chapter 15, "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. JavaServer 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 JavaServer Faces attributes within HTML5 elements. JavaServer 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 JavaServer 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 JavaServer Faces components associated with a server-side UIComponent instance.

To make an element that is not a JavaServer Faces element a pass-through element, specify at least one of its attributes using the http://xmlns.jcp.org/jsf namespace. For example, the following code declares the namespace with the short name jsf:

<html ... xmlns:jsf="http://xmlns.jcp.org/jsf"
...
    <input type="email" jsf:id="email" name="email"
           value="#{reservationBean.email}" required="required"/>

Here, the jsf 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.

Table 8-4 shows how pass-through elements are rendered as Facelets tags. The JSF 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.

Table 8-4 How Facelets Renders HTML5 Elements

HTML5 Element Name

Identifying Attribute

Facelets Tag

a

jsf:action

h:commandLink

a

jsf:actionListener

h:commandLink

a

jsf:value

h:outputLink

a

jsf:outcome

h:link

body

+

h:body

button

+

h:commandButton

button

jsf:outcome

h:button

form

+

h:form

head

+

h:head

img

+

h:graphicImage

input

type="button"

h:commandButton

input

type="checkbox"

h:selectBooleanCheckbox

input

type="color"

h:inputText

input

type="date"

h:inputText

input

type="datetime"

h:inputText

input

type="datetime-local"

h:inputText

input

type="email"

h:inputText

input

type="month"

h:inputText

input

type="number"

h:inputText

input

type="range"

h:inputText

input

type="search"

h:inputText

input

type="time"

h:inputText

input

type="url"

h:inputText

input

type="week"

h:inputText

input

type="file"

h:inputFile

input

type="hidden"

h:inputHidden

input

type="password"

h:inputSecret

input

type="reset"

h:commandButton

input

type="submit"

h:commandButton

input

type="*"

h:inputText

label

+

h:outputLabel

link

+

h:outputStylesheet

script

+

h:outputScript

select

multiple="*"

h:selectManyListbox

select

+

h:selectOneListbox

textarea

+

h:inputTextArea

Using Pass-Through Attributes

Pass-through attributes are the converse of pass-through elements. They allow you to pass attributes that are not JavaServer Faces attributes through to the browser without interpretation. If you specify a pass-through attribute in a JavaServer Faces UIComponent, the attribute name and value are passed straight through to the browser without being interpreted by JavaServer Faces components or renderers. There are several ways to specify pass-through attributes.

  • Use the JavaServer Faces namespace for pass-through attributes to prefix the attribute names within a JavaServer Faces component. For example, the following code declares the namespace with the short name p, then passes the type, min, max, required, and title attributes through to the HTML5 input component:

    <html ... xmlns:p="http://xmlns.jcp.org/jsf/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 a Map<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 tut-install`/examples/web/jsf/reservation/` directory.

The following topics are addressed here:

The Facelets Pages for the reservation Application

The first important feature of the Facelets pages for the reservation application is the DOCTYPE header. Most Facelets pages in JavaServer Faces applications refer to the XHTML DTD. The facelets pages for this application begin simply with the following DOCTYPE header, which indicates an HTML5 page:

<!DOCTYPE html>

The namespace declarations in the html element of the reservation.xhtml page specify both the jsf and the passthrough namespaces:

<html lang="en"
      xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:p="http://xmlns.jcp.org/jsf/passthrough"
      xmlns:jsf="http://xmlns.jcp.org/jsf">

Next, an empty 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>
</h:head>
<h:body>
    <h:outputStylesheet name="css/stylesheet.css" target="head"/>

The reservation.xhtml page uses pass-through elements for most of the form fields on the page. This allows it to use some HTML5-specific input element types, such as date and email. For example, the following element renders both a date format and a calendar from which you can choose a date. The jsf prefix on the id attribute makes the element a pass-through one:

    <input type="date" jsf:id="date" name="date"
           value="#{reservationBean.date}" required="required"
           title="Enter or choose a date."/>

The field for the number of tickets, however, uses the h: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 event="change" render="total"
                listener="#{reservationBean.calculateTotal}"/>
    </h:inputText>

The field for the price specifies the number type 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 JavaServer Faces input component:

    <h:inputText id="price" p:type="number"
                 value="#{reservationBean.price}"
                 p:min="80" p:max="120"
                 p:step="20" p:required="required"
                 p:title="Enter a price: 80, 100, 120, or 140.">
        <f:ajax event="change" render="total"
                listener="#{reservationBean.calculateTotal}"/>
    </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 Chapter 13, "Using Ajax with JavaServer 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

  1. Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).

  2. From the File menu, choose Open Project.

  3. In the Open Project dialog box, navigate to:

    tut-install/examples/web/jsf
  4. Select the reservation folder.

  5. Click Open Project.

  6. 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

  1. Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).

  2. In a terminal window, go to:

    tut-install/examples/web/jsf/reservation/
  3. Enter the following command:

    mvn install

    This command builds and packages the application into a WAR file, reservation.war, that is located in the target 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.

  1. Enter the following URL in your web browser:

    http://localhost:8080/reservation
  2. 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).

  3. Click Make Reservation to complete the reservation or Clear to restore the fields to their default values.

  4. If you click Make Reservation, the confirmation.xhtml page appears, displaying the submitted values.

    Click Back to return to the reservation.xhtml page.


Previous Next Contents
Oracle Logo  Copyright © 2017, Oracle and/or its affiliates. All rights reserved.