cap5 primefaces

21
Elegant Web Applications with PrimeFaces One of the advantages of JSF is that it is very easy to develop custom components. As such, several open source component libraries have been developed. One of these component libraries is PrimeFaces. PrimeFaces allows us to develop elegant web applications with little effort. As of version 7.0, PrimeFaces is bundled with NetBeans. Our first PrimeFaces project To use PrimeFaces in our project, we simply need to create a Java Web application project as usual. When we pick the JavaServer Faces Framework, we need to click on the Components tab and select PrimeFaces 2.2.1 as our component suite.

Upload: manuel-miranda

Post on 06-May-2015

251 views

Category:

Engineering


1 download

DESCRIPTION

PRIMEFACES

TRANSCRIPT

Page 1: Cap5 primefaces

Elegant Web Applications with PrimeFaces

One of the advantages of JSF is that it is very easy to develop custom components.As such, several open source component libraries have been developed. One ofthese component libraries is PrimeFaces. PrimeFaces allows us to develop elegantweb applications with little effort. As of version 7.0, PrimeFaces is bundled withNetBeans.

Our first PrimeFaces projectTo use PrimeFaces in our project, we simply need to create a Java Web applicationproject as usual. When we pick the JavaServer Faces Framework, we need to click onthe Components tab and select PrimeFaces 2.2.1 as our component suite.

Page 2: Cap5 primefaces

Elegant Web Applications with PrimeFaces

[ 174 ]

When our project is created, NetBeans will add the required libraries to our project,PrimeFaces tags will autocomplete in our project's JSF pages.

When selecting PrimeFaces as our JSF component suite, NetBeans creates a samplepage using PrimeFaces components when our project is created. The markup for thefile looks like this:

<?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:p="http://primefaces.prime.com.tr/ui"xmlns:h="http://java.sun.com/jsf/html">

<h:head><title>Facelet Title</title>

</h:head><h:body>

<h:form><p:commandButton value="Hello from PrimeFaces"

onclick="dlg1.show();" type="button" />

<p:dialog header="PrimeFaces Dialog" widgetVar="dlg1"width="500">For more information visit <a href="http://primefaces. org">

http://primefaces.org</a>.</p:dialog>

</h:form></h:body>

</html>

Except for a few PrimeFaces-specific components, the page looks like a regular Facelets page.

Notice the PrimeFaces namespace, xmlns:p="http://primefaces.prime.com.tr/ui" isautomatically added to the <html> tag. This namespace is necessary in order to usePrimeFaces components in our pages. By convention, PrimeFaces tags use a prefix of p.

The first PrimeFaces component we see in our page is <p:commandButton>, thiscomponent is similar to the standard JSF command button component, but providescertain advantages over the standard command button, such as rendering nicelywithout us having to manually apply CSS stylesheets.

Page 3: Cap5 primefaces

Chapter 5

[ 175 ]

The other PrimeFaces component we see in our page is <p:dialog>, this componentrenders as a popup that can overlay other components on the page. The value of itswidgetVar attribute can be used to access the component from other components onthe page. The Dialog component provides a client-side JavaScript API for this purpose. The most commonly used functions of this client API are show() and hide(), used todisplay or hide the dialog on the page. We can see the client API in action as the valueof the onclick attribute of the commandButton we discussed earlier.

When we run our application, we can see the automatically generated page in action.

When we click on the button, the dialog is displayed.

Page 4: Cap5 primefaces

Elegant Web Applications with PrimeFaces

[ 176 ]

Clicking on the link inside the dialog takes us to the PrimeFaces web site.

As we can see, PrimeFaces allows us to create elegant web applications withvery little effort on our part. Next, we will see how to take advantage of severalPrimeFaces components to greatly ease and simplify the work we need to do tocreate our web applications.

Using PrimeFaces components in our JSF applicationsIn this section, we will discuss how to use some simple PrimeFaces components tosave us work when developing our JSF applications. The following page is a simplecustomer data entry page:

<?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">

Page 5: Cap5 primefaces

Chapter 5

[ 177 ]

<html xmlns="http://www.w3.org/1999/xhtml"xmlns:p="http://primefaces.prime.com.tr/ui"xmlns:h="http://java.sun.com/jsf/html"xmlns:ui="http://java.sun.com/jsf/facelets">

<ui:composition template="./template.xhtml"><ui:define name="top">

<h2>Customer Information Data Entry</h2></ui:define>

<ui:define name="content"><h:form>

<p:messages/><p:panel header="Enter Customer Information">

<h:panelGrid columns="2"><h:outputLabel for="firstName" value="First Name"

styleClass="requiredLbl"/><h:inputText id="firstName" label="First Name"

value="#{customer.firstName}"required="true"/>

<h:outputLabel for="middleName" value="Middle Name"

styleClass="optionalLbl"/><h:inputText id="middleName" label="Middle Name"

value="#{customer.middleName}"/><h:outputLabel for="lastName" value="Last Name"

styleClass="requiredLbl"/><h:inputText id="lastName" label="Last Name"

value="#{customer.lastName}"required="true"/>

<h:outputLabel for="birthDate" value="Date of Birth"

styleClass="optionalLbl"/><p:calendar id="birthDate"

value="#{customer.birthDate}"showOn="button" inputStyle="width:100px;"navigator="true"/>

<h:panelGroup/><p:commandButton

value="Submit"action="#{customerController. saveCustomer}"

Page 6: Cap5 primefaces

Elegant Web Applications with PrimeFaces

[ 178 ]

ajax="false"/></h:panelGrid></p:panel></h:form></ui:define></ui:composition> </html>

In our example, we took advantage of NetBean's Facelet Template generation, that way we can get some very nice CSS styles for "free", refer to the previous chapter for details on NetBeans' Facelets Tem-plate capabilities.

When we run our project, the above markup is rendered on the browser as shown inthe following screenshot:

The first new PrimeFaces component we used on our page was the <p:messages>component. This component can be used as a drop-in replacement for the standardJSF <h:messages> component. The advantage of <p:messages> over <h:messages>is that with <p:messages>, error messages are nicely formatted by default.

Page 7: Cap5 primefaces

Chapter 5

[ 179 ]

Similar to <p:messages>, PrimeFaces has a <p:message> component that can beused as a drop-in replacement for the standard JSF <h:message> component (notshown in the example). Just like <h:message>, <p:message> should be used whenwe wish to show validation errors next to the field whose value did not validate, as opposed to showing the message at the top of the page.

Page 8: Cap5 primefaces

Elegant Web Applications with PrimeFaces

[ 180 ]

The other new PrimeFaces component we see in this example is <p:calendar>. Thiscalendar can be used for date input fields. When the user clicks on the icon generated by this component, a nice calendar widget pops up, where the user can select thedate to enter by pointing and clicking.

The PrimeFaces calendar component is very customizable. By default, it renders as atext field, and when the user clicks on this text field, the calendar widget pops up. In our example, we set the showOn attribute to button, this has the effect of rendering a calendar icon next to the text field, which gives a visual indication that this is a special field, and also allows users to enter dates manually if they prefer to do so.

By default, the month and year dropdowns are not rendered, this makes itcumbersome to enter dates that are far in the future or in the past (default day isalways the present date). To get around this, we can set the navigator property totrue like we did in our example.

Additionally, we can control the appearance of the text input field generated by using the inputStyle or inputStyleClass attributes of <p:calendar>. TheinputStyle attribute value must be a valid inline CSS, where the value of theinputStyleClass attribute must be the name of a CSS class defined in one of our CSS stylesheets.

Page 9: Cap5 primefaces

Chapter 5

[ 181 ]

The last new PrimeFaces component we used in our page is <p:commandButton>,by default, this component renders a button that triggers AJAX requests to updateparts of our page without doing a full page request. This component can also beused as a drop-in replacement for the standard JSF <h:commandButton> component.To do this, we need to set its ajax property to false, which is what we did in ourexample. The advantage of using <p:commandButton> as a drop-in replacement for <h:commandButton> is that <p:commandButton> is nicely rendered by default,without the need for us to create custom CSS styles for our buttons.

When clicking on the button in our example, the user is directed to a confirmation page.

We didn't use any new PrimeFaces components in the confirmation page, therefore we won't be discussing it. Its markup can be found in this chapter's download (confirmation.xhtml).

Tabbed viewsFrequently, HTML forms have several fields that would typically result in very long forms. It is common to divide a form into two or more tabs, that way the pagelooks less overwhelming to the user. Normally, creating a page with tabs requiressome HTML and JavaScript tricks, however, PrimeFaces includes a <p:tabView>component we can use to easily generate tabs, the following example illustrates howto use this component:

<?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">

Page 10: Cap5 primefaces

Elegant Web Applications with PrimeFaces

[ 182 ]

<html xmlns="http://www.w3.org/1999/xhtml"xmlns:p="http://primefaces.prime.com.tr/ui"xmlns:h="http://java.sun.com/jsf/html"xmlns:ui="http://java.sun.com/jsf/facelets"xmlns:f="http://java.sun.com/jsf/core">

<ui:composition template="./template.xhtml"><ui:define name="top">

<h2>Customer Information Data Entry</h2></ui:define>

<ui:define name="content"><h:form>

<p:messages/><h:panelGrid columns="1" style="width: 100%">

<p:tabView><p:tab title="Personal Information">

<h:panelGrid columns="2"><h:outputLabel for="firstName" value="First Name"

styleClass="requiredLbl"/><h:inputText id="firstName" label="First Name"

value="#{customer. firstName}"required="true"/>

<h:outputLabel for="middleName" value="Middle Name"

styleClass="optionalLbl"/><h:inputText id="middleName" label="Middle Name"

value="#{customer. middleName}"/>

<h:outputLabel for="lastName" value="Last Name"

styleClass="requiredLbl"/><h:inputText id="lastName" label="Last Name"

value="#{customer. lastName}"required="true"/>

<h:outputLabel for="birthDate"value="Date of Birth"

styleClass="optionalLbl"/><p:calendar id="birthDate"

value="#{customer. birthDate}"showOn="button"

Page 11: Cap5 primefaces

Chapter 5

[ 183 ]

inputStyle="width:100px;"navigator="true"/>

</h:panelGrid></p:tab><p:tab title="Address">

<h:panelGrid columns="2"><h:outputLabel for="line1" value="Line 1"

styleClass="requiredLbl"/><h:inputText id="line1"

value="#{customer. addrLine1}"required="true"/>

<h:outputLabel for="line2" value="Line 2"

styleClass="optionalLbl"/><h:inputText id="line2"

value="#{customer. addrLine2}"/>

<h:outputLabel for="city" value="City"

styleClass="requiredLbl"/><h:inputText id="city"

value="#{customer. addrCity}"required="true"/>

<h:outputLabel for="state" value="State"

styleClass="requiredLbl"/><h:selectOneMenu id="state" required="true"

value="#{customer.addrState}"><f:selectItem itemValue="" itemLabel=""/><f:selectItem itemValue="AL"

itemLabel="Alabama"/><f:selectItem itemValue="AK"

itemLabel="Alaska"/><f:selectItem itemValue="AZ"

itemLabel="Arizona"/><f:selectItem itemValue="AR"

itemLabel="Arkansas"/><!-- other states omitted for

Page 12: Cap5 primefaces

Elegant Web Applications with PrimeFaces

[ 184 ]

brevity --></h:selectOneMenu>

<h:outputLabel for="zip" value="Zip"

styleClass="requiredLbl"/><h:inputText id="zip"

value="#{customer. addrZip}"required="true"/>

</h:panelGrid></p:tab><p:tab title="Phone Numbers">

<h:panelGrid columns="2"><h:outputLabel for="homePhone" value="Home"/><p:inputMask id="homePhone"

mask="(999)-999-9999"value="#{customer. homePhone}"size="12" styleClass="optionalLbl"/>

<h:outputLabel for="mobilePhone"value="Mobile"/>

<p:inputMask id="mobilePhone"mask="(999)-999-9999"value="#{customer. mobilePhone}"size="12" styleClass="optionalLbl"/>

<h:outputLabel for="workPhone" value="Work"/><p:inputMask id="workPhone"

mask="(999)-999-9999"value="#{customer. workPhone}"size="12" styleClass="optionalLbl"/>

</h:panelGrid></p:tab>

</p:tabView><p:commandButton

value="Submit"action="#{customerController.saveCustomer}"ajax="false"/>

</h:panelGrid></h:form>

</ui:define></ui:composition>

</html>

Page 13: Cap5 primefaces

Chapter 5

[ 185 ]

As we can see in the above example, the root component for a tabbed interface is<p:tabView>; nested inside this component there must be one or more <p:tab>components. Each <p:tab> contains the input fields that will be in the corresponding tab. <p:tab> has a title attribute that will be rendered as the title for the tab.

When we execute our project we can see the tab component in action.

Page 14: Cap5 primefaces

Elegant Web Applications with PrimeFaces

[ 186 ]

By clicking on each tab we can see the corresponding components.

Alert readers may have noticed that we used a new PrimeFaces component in thethird tab. <p:inputMask> allows us to prevent users from entering badly formatteddata. In our example, we used it for every telephone number input field. The following screenshot shows <p:inputMask> in action:

Page 15: Cap5 primefaces

Chapter 5

[ 187 ]

As we can see in the screenshot, as soon as the user clicks on an inputMask component,the expected format is automatically displayed. All the user needs to do is "fill in the blanks" to have the input correctly formatted. In our case, we are expecting a phonenumber in the format (xxx)xxx-xxxx, where x is an integer value. When we define our mask, the number 9 represents any numeric value, the letter a represents anyalphabetic character, and the asterisk (*) represents an alphanumeric character.

For our formatting, we gave the mask an attribute of <p:inputMask> the value of(999)-999-9999, which resulted in the desired mask.

As we can see, using <p:inputMask> allows us to enforce correctly formatted datawithout having to rely on JSF validation.

Back to our tab discussion, when the user clicks on the submit button at the bottomof the page, data in all tabs is submitted, and is treated as a single <h:form>submission, at this point, the JSF lifecycle "kicks in" as usual.

Wizard interfacesIn addition to using tabs, another common way of dividing long forms is by usingwizards. Wizards are useful whenever we need the users to fill in input fields in a specific order. In our previous example, we had no way to force the user to enter address information before entering phone number information. This prevents usfrom validating that the phone numbers entered correspond to the geographical areain the address. To solve this problem we can use a wizard interface, which can bedone easily with the PrimeFaces' <p:wizard> component. The following exampleillustrates how to use this component:

<?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:p="http://primefaces.prime.com.tr/ui"xmlns:h="http://java.sun.com/jsf/html"xmlns:ui="http://java.sun.com/jsf/facelets"xmlns:f="http://java.sun.com/jsf/core">

<ui:composition template="./template.xhtml"><ui:define name="top">

<h2>Customer Information Data Entry</h2></ui:define>

<ui:define name="content"><h:form>

<h:panelGrid columns="1" style="width: 100%">

Page 16: Cap5 primefaces

Elegant Web Applications with PrimeFaces

[ 188 ]

<p:wizard><p:tab title="Personal Information"

id="personalInfo"><p:panel header="Personal Information">

<p:messages/><h:panelGrid columns="2">

<h:outputLabel for="firstName"value="First Name"

styleClass="requiredLbl"/><h:inputText id="firstName"

label="First Name"value="#{customer. firstName}"required="true"/>

<h:outputLabel for="middleName"value="Middle Name"

styleClass="optionalLbl"/><h:inputText id="middleName"

label="Middle Name"value="#{customer. middleName}"/>

<h:outputLabel for="lastName"value="Last Name"

styleClass="requiredLbl"/><h:inputText id="lastName"

label="Last Name"value="#{customer.

lastName}"required="true"/>

<h:outputLabel for="birthDate"value="Date of

Birth"

styleClass="optionalLbl"/><p:calendar id="birthDate"

value="#{customer. birthDate}"showOn="button"

inputStyle="width:100px;"

Page 17: Cap5 primefaces

Chapter 5

[ 189 ]

navigator="true"/></h:panelGrid>

</p:panel></p:tab>

<!-- Phone Number tab omitted forbrevity →

<p:tab title="Confirmation" id="confirmation"><p:messages/><h:panelGrid columns="2">

<h:outputText value="First Name"

styleClass="optionalLbl"/><h:outputText id="firstNameTxt"

value="#{customer. firstName}" />

<h:outputText value="Middle Name"

styleClass="optionalLbl"/><h:outputText id="middleNameTxt"

value="#{customer. middleName}"/>

<h:outputText value="Last Name"

styleClass="optionalLbl"/><h:outputText id="lastNameTxt"

value="#{customer. lastName}" />

<h:outputText value="Date of Birth"

styleClass="optionalLbl"/><h:outputText id="birthDateTxt"

value="#{customer.

formattedBirthDate}" />

<h:outputText value="Home Phone"

styleClass="optionalLbl"/><h:outputText id="homePhoneTxt"

value="#{customer. homePhone}" />

<h:outputText value="Mobile Phone"

styleClass="optionalLbl"/><h:outputText id="mobilePhoneTxt"

Page 18: Cap5 primefaces

Elegant Web Applications with PrimeFaces

[ 190 ]

value="#{customer. mobilePhone}" /><h:outputText value="Work Phone" styleClass="optionalLbl"/><h:outputText id="workPhoneTxt" value="#{customer. workPhone}" />

<h:panelGroup/><h:inputHidden value="#{customer. addrState}"/><p:commandButton id="submitButton"value="Submit" actionListener="#{customerController.saveCustomer}" ajax="false"/></h:panelGrid></p:tab></p:wizard> </h:panelGrid></h:form></ui:define></ui:composition> </html>

Some of the wizard pages or "tabs" in the above example were omittedfor brevity. Refer to the code download for this chapter for the completelisting.

As we can see, generating a wizard interface with PrimeFaces is easy. All we need todo is use the <p:wizard> component, then nest a <p:tab> component for each stepin the wizard. Markup inside each <p:tab> component is standard JSF.

In the last tab, we added a <p:commandButton> component to submit the data tothe server The value of the actionListener attribute of the commandButton is amethod in our CustomerController managed bean.

package com.ensode.primefacesdemo.managedbeans;

import java.io.Serializable;import javax.faces.bean.ManagedBean;import javax.faces.bean.SessionScoped; im-port javax.faces.event.ActionEvent; importjavax.faces.application.FacesMessage; importjavax.faces.context.FacesContext;

Page 19: Cap5 primefaces

Chapter 5

[ 191 ]

@ManagedBean@SessionScopedpublic class CustomerController implements Serializable {

/** Creates a new instance of CustomerController */public CustomerController() {}

public void saveCustomer(ActionEvent actionEvent) {//In a real application, we would save the data,//In this example we simply show a message.FacesMessage facesMessage = new FacesMessage(

"Data Saved Successfully");facesMessage.setSeverity(FacesMessage.SEVERITY_INFO);

FacesContext.getCurrentInstance().addMessage(null, facesMessage);

}}

As we can see, the saveCustomer() method simply adds a faces message that isdisplayed as a confirmation message in our page. In a real application, we of course would save the data to a database.

At this point we are ready to see the wizard component in action.

Page 20: Cap5 primefaces

Elegant Web Applications with PrimeFaces

[ 192 ]

Notice that the wizard component automatically adds a Next button at the bottomright, clicking this button takes us to the next page in the wizard.

As expected, at this point the wizard component generates both a Previous and aNext button.

As we navigate to the wizard and reach the last page, when we click on the Submitbutton we see the confirmation message generated by the saveCustomer() methodin our CustomerController managed bean. This message is rendered by the<p:messages> components, which takes care of nicely styling it without us having toexplicitly use any CSS.

Page 21: Cap5 primefaces

Chapter 5

[ 193 ]

More informationIn this chapter we only scratched the surface of the PrimeFaces' capabilities. A PrimeFaces component showcase, illustrating all PrimeFaces components can befound at http://www.primefaces.org/showcase/ui/home.jsf. For additionalinformation on PrimeFaces, visit http://www.primefaces.org.

SummaryIn this chapter we provided an introduction to the PrimeFaces JSF component librarythat has been included with NetBeans since version 7.0. We saw how PrimeFacesallows us to easily develop elegant looking, AJAX-enabled applications with littleeffort. Some of the major PrimeFaces components discussed include the Tab Viewcomponent, which allows us to easily divide our pages into tabs. We also saw how to use the PrimeFaces wizard component, which allow us to easily create wizard likeinterfaces in our web applications.