Book Image

JSF 1.2 Components

By : IAN HLAVATS
Book Image

JSF 1.2 Components

By: IAN HLAVATS

Overview of this book

Today's web developers need powerful tools to deliver richer, faster, and smoother web experiences. JavaServer Faces includes powerful, feature-rich, Ajax-enabled UI components that provide all the functionality needed to build web applications in a Web 2.0 world. It's the perfect way to build rich, interactive, and "Web 2.0-style" Java web apps. This book provides a comprehensive introduction to the most popular JSF components available today and demonstrate step-by-step how to build increasingly sophisticated JSF user interfaces with standard JSF, Facelets, Apache Tomahawk/Trinidad, ICEfaces, JBoss Seam, JBoss RichFaces/Ajax4jsf, and JSF 2.0 components. JSF 1.2 Components is both an excellent starting point for new JSF developers, and a great reference and “how to” guide for experienced JSF professionals. This book progresses logically from an introduction to standard JSF HTML, and JSF Core components to advanced JSF UI development. As you move through the book, you will learn how to build composite views using Facelets tags, implement common web development tasks using Tomahawk components, and add Ajax capabilities to your JSF user interface with ICEfaces components. You will also learn how to solve the complex web application development challenges with the JBoss Seam framework. At the end of the book, you will be introduced to the new and up-coming JSF component libraries that will provide a road map of the future JSF technologies.
Table of Contents (14 chapters)
JSF 1.2 Components
Credits
Foreword
About the Author
About the Reviewers
Preface

Rendering text


Another common task for web applications is to render text in the browser. The HTML markup language includes a number of elements that can be used to render text. JSF includes standard components that represent these HTML elements and extend their capabilities to include support for internationalization, conditional rendering, formatted text, validation messages, and more.

Many elements in HTML, such as<p>, <div>, <span>, and<label> for example, can be used to render text. The JSF<h:outputText> tag renders the HtmlOutputText component as an arbitrary text value or as a<span> element that contains text if CSS attributes on the tag are set. The<h:outputText> can be used to render plain text or HTML that originates from the backing bean.

The value attribute of the tag specifies the text to be rendered. If we are rendering HTML, we should make sure to set the escape attribute to false so that the HTML is rendered properly in the browser. The<h:outputText> tag can also be used to render arbitrary Java objects, such as Date, Integer, Float, and other types. When the value attribute contains an EL expression that evaluates to a Java type other than String, the component attempts to render the value as a string. If a converter is registered on the component, the converter is responsible for converting the object to a string.

One of the uses of the HtmlOutputText component is to display localized messages. Let's look at a few examples of how to use this component to internationalize our JSF pages. In the process, we will have the opportunity to look at the JSF framework's internationalization support in more detail.

Rendering localized text

One of the many benefits of the JSF framework is the ability to easily internationalize our applications. As the format of date and time, numbers, and currency values can change significantly from one locale to another, JSF conveniently extends Java's internationalization (I18N) support to our user interface.

For demonstration, our JSF application will support three locales: English (our default locale), French, and Spanish. Localized messages will be stored in three message bundles named "messages_en.properties", "messages_fr.properties", and "messages_es.properties".

Since JSF 1.2, there are two ways to make message bundles available to web pages in our JSF applications.

Registering a message bundle (JSF 1.1)

Registering a message bundle in JSF 1.1 requires adding the following XML to the faces-config.xml file:

<application>
<message-bundle>messages</message-bundle>
<locale-config>
<default-locale>en</default-locale>
<supported-locale>fr</supported-locale>
<supported-locale>es</supported-locale>
</locale-config>
</application>

Notice that we specify the name of the message bundle properties file (without the locale information and without the .properties file extension) for the<message-bundle> element. Next, we specify the locales supported by our JSF application in the<locale-config> element, indicating that English (en) is our default locale. To use our message bundles, we need to declare the<f:loadBundle> tag in our JSF pages:

<f:view>
<f:loadBundle var="bundle" basename="messages" />
<h:outputText value="#{bundle.welcomeMessage}" />
</f:view>

Registering a message bundle (JSF 1.2)

Since JSF 1.2, there is a more efficient way to use message bundles in our JSF pages. Instead of loading our message bundle on each page using the<f:loadBundle> tag, we can simply declare our message bundle once in faces-config.xml and use it from any page in our JSF application. The following XML must be added to faces-config.xml to enable this feature:

<application>
<resource-bundle>
<base-name>messages</base-name>
<var>bundle</var>
</resource-bundle>
</application>

The following example demonstrates how we can render our localized text in a JSF page using the<h:outputText> tag. In this example, the text is rendered from our default message bundle for the English locale.

<f:view> <f:loadBundle basename="messages" var="bundle" />
<h:outputText value="#{bundle.welcomeMessage} (#{view.locale.displayName})" />
</f:view>

Note

Developer tip: Message bundle keys and the JSF EL

Due to the syntax of the JSF expression language, if we use the "dot" notation as in the expression #{bundle.welcomeMessage}, then we must take care to choose valid key names for our message bundle. This means avoiding periods and spaces and using only letters and numbers for any message bundle keys we want to use in our JSF pages. Alternately, we can use the "map" notation as in the expression #{bundle['another.message.key']} to specify any arbitrary message bundle key containing any acceptable key characters supported by the Java properties file format.

Our message bundle contains the following key/value pair:

welcomeMessage=Welcome!

In the next example, we hardcoded the locale of our view by setting the locale attribute of the<f:view> tag to the French locale in a separate view, and the JSF framework loaded the messages from our French message bundle.

<f:view locale="fr">
<f:loadBundle basename="messages" var="bundle" />
<h:outputText value="#{bundle.welcomeMessage} (#{view.locale.displayName})" />
</f:view>

We created a third view for the Spanish locale. As we also configured a message bundle for this locale, JSF was able to render localized messages for this locale.

<f:view locale="es">
<f:loadBundle basename="messages" var="bundle" />
<h:outputText value="#{bundle.welcomeMessage} (#{view.locale.displayName})" />
</f:view>

Creating separate pages for each locale is one approach to implement internationalization in JSF. Another approach that we can use is to create a single view without specifying the locale and let the JSF framework determine the appropriate message bundle to use, based on the locale sent by the user's browser. As users can configure their browsers to specify their preferred languages, our JSF application can rely on this information to identify the user's locale.

Detecting the browser's locale in a single view can be a more efficient approach, as we no longer have to maintain a different copy of the view for each supported locale.

If the user's locale is not supported, they will see messages for our application's default locale.

Another use of the<h:outputText> tag is to render text conditionally. For example, we may want to display a message to the user only if he/she is currently logged into our web application. For this purpose, we can use the rendered attribute of the<h:outputText> tag. This attribute accepts a Boolean value, and we can use an EL expression to determine if the component should be visible or not.

Rendering date/time information

Web applications often have to display dates, currencies, numbers, and other types of information to the user in a variety of ways. For example, you may want to display the date January 1, 2009 in the short format "01/01/09", in the medium format "Jan 1, 2009", or in the long format (including time information) "Thursday, January 1, 2006 5:30:15 PM".

Conveniently, the JSF Core tag<f:convertDateTime> can be nested inside an<h:outputText> tag to control date/time formatting. The following example demonstrates date/time formatting using the<f:convertDateTime> tag. In this case, we display the date using the "full" date/time style.

<h:outputText value="You were born on " rendered="#{backingBean.date ne null}" />
<h:outputText value="#{backingBean.date}">
<f:convertDateTime type="date" dateStyle="full" />
</h:outputText>

The<h:outputText> tag is also locale aware, so it renders the date according to the formatting conventions of the current locale.

The<h:outputText> tag is a very flexible JSF component that supports a wide range of text rendering situations.

Rendering parameterized text

Sometimes we want to render formatted text that contains parameters to be specified later. JSF includes the<h:outputFormat> tag for this purpose. It is able to render messages that contain special placeholders that can be filled in at runtime. Let's look at how to render parameterized messages using the HtmlOutputFormat component.

In this example, we render a parameterized string from our message bundle and replace the parameters with values obtained from the query string, the current view, and our backing bean. The process of replacing parameters with values in a parameterized string is called interpolation. This example also demonstrates the flexibility of the JSF expression language. We are literally able to plug in values from just about any source of information available to our web page.

<h:outputFormat value="#{bundle.welcomeMessage2}">
<f:param value="#{param.username}" />
<f:param value="#{view.locale}" />
<f:param value="#{backingBean.today}" />
</h:outputFormat>

The parameterized message is defined in our message bundle. We will have a similar definition for each locale.

welcomeMessage2=Welcome {0}, your locale is {1}. The current date is {2}.

First, we configure our browser to use English as our preferred language.

Next, we set French as our preferred language.

On our third try, we set Spanish as our preferred language.

Rendering labels

When marking up our JSF pages, we should take care to provide proper labels for components to give them a clear purpose in our user interface. This way, users will have an easier time learning how to use our JSF applications.

When rendering labels, it is more appropriate to use the HTML<label> element than to use a<span> element. For this purpose, we can use the JSF<h:outputLabel> tag. This tag renders an HtmlOutputLabel component as an HTML<label> element and has a special for attribute that identifies the input component represented by the label.

A nice feature about this component is that it improves the usability of forms in web browsers by providing additional information about the relationship between text labels and form controls. One enhancement in particular is that users can now click on a radio button or checkbox label to change the selection state of the control. This makes a web page more intuitive to the user and also provides accessibility information for screen readers and assistive devices.

To set the text displayed by an<h:outputLabel> tag, you can specify a string literal or a JSF EL value expression for the value attribute of the tag. You can also nest an<h:outputText> tag inside an<h:outputLabel> tag, in which case the text will be provided by the child component. The<h:outputLabel> tag has the same internationalization support as the<h:outputText> tag.

This example shows how to use the<h:outputLabel> tag in conjunction with another JSF tag. The important thing to notice is the use of the for attribute. It expects the ID of another component on the page and informs the browser that the label is intended for that particular component.

<h:outputLabel value="Remember Me" for="remember" />
<h:selectBooleanCheckbox id="remember" value="#{backingBean.rememberMe}" onclick="submit()" />

For our final example of text rendering JSF components, we can examine the<h:outputFormat> tag. This tag renders an HtmlOutputFormat component as formatted text within the JSF page. Formatted text can include a localized message from the application's message bundle for the current locale, or it can include a string pattern that is evaluated at request time. Interestingly, this string pattern can have placeholders that are substituted by any nested<f:param> tags.

So for example, if we wanted to render the message "Welcome, username", we could use an<h:outputFormat> tag that contains a parameter for the user's name. The value substituted for this parameter would be defined by a child<f:param> tag, so the actual name of the user could come from a database, an LDAP directory, or another source. The important point is that this tag simplifies a very common task for web applications, namely rendering localized, parameterized text messages conveniently and easily.

Rendering a validation message

The<h:message> tag renders an HtmlMessage component and is useful for displaying validation messages in a JSF page. It is important to include this tag on our JSF pages so that users will be informed when a JSF validation message occurs. Typically, the tag is placed immediately after a JSF component tag to display the validation messages for the associated component.

In this example, we render an HtmlInputText component and specify through the<h:inputText> tag's required attribute that the user is expected to enter a value into to the first name text field. If the user submits the form without entering a value, an error message will be rendered by the<h:message> tag beside the component. The for attribute is required and is used to associate the message with a particular UI component on the page. It expects the ID of the component that the message is for.

<h:inputText id="firstName" value="#{customerBean.customer.firstName}" required="true" />
<h:message for="firstName" errorClass="error" showSummary="true" showDetail="false" />

Rendering all validation messages

The<h:messages> tag is similar to the<h:message> tag except that it renders an HtmlMessages component that displays all validation messages for any components in the view in an unordered list. This is useful when our user interface requirements call for presenting all error messages in one place, for example, above any form fields on the page. The globalOnly attribute is false by default, but if we set it to true, then the component only displays messages generated by the application that are not associated with a particular component.

<h:messages errorClass="error" globalOnly="false" />