Tuesday, January 31, 2012

PrimeFaces 3 Tutorial : Introduction & Form Validation

PrimeFaces is a component library for JSF and has huge component support.
Working with PrimeFaces is very much easy because there is a single jar, no mandatory other dependencies, no mandatory configuration is required.

Ok, in this tutorial I am going to explain how to create a Maven based PrimeFaces project and create a simple registration for and validate the form.
I am using JDK1.6.26 and Tomcat 7.0.32.


Step#1
Create Maven Project and add the following repositories, dependencies in pom.xml

<dependencies>  
  <dependency>
   <groupId>com.sun.faces</groupId>
   <artifactId>jsf-api</artifactId>
   <version>2.1.6</version>
   <scope>runtime</scope>
  </dependency>
  <dependency>
   <groupId>com.sun.faces</groupId>
   <artifactId>jsf-impl</artifactId>
   <version>2.1.6</version>
   <scope>runtime</scope>
  </dependency>
  <dependency>
   <groupId>org.primefaces</groupId>
   <artifactId>primefaces</artifactId>
   <version>3.0</version>
  </dependency>
  <dependency>
   <groupId>org.primefaces.themes</groupId>
   <artifactId>bluesky</artifactId>
   <version>1.0.2</version>
  </dependency>
 </dependencies>

 <repositories>
  <repository>
   <id>maven2-repository.dev.java.net</id>
   <name>Java.net Repository for Maven</name>
   <url>http://download.java.net/maven/2</url>
  </repository>
  <repository>
   <id>prime-repo</id>
   <name>Prime Repo</name>
   <url>http://repository.primefaces.org</url>
  </repository>
 </repositories>
 <build>
  <finalName>primefaces-demo</finalName>
 </build>

Step#2

Configure JSF2's FacesServlet configurtion in web.xml
<servlet>
    <servlet-name>FacesServlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>FacesServlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>FacesServlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
  </servlet-mapping>
  <context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
  </context-param>
  <!--Blusky theme for PrimeFaces -->
  <context-param>
 <param-name>primefaces.THEME</param-name>
 <param-value>bluesky</param-value>
  </context-param>

Step#3

Create RegistrationForm bean.

package com.sivalabs.pfdemo.mb.ui;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class RegistrationForm
{
 private Integer userId;
 private String userName;
 private String password;
 private String firstName;
 private String lastName;
 private String email;
 private String phone;
 private Date dob;
 private String gender;
 private List<String> interests = new ArrayList<String>();
 private boolean subscribeToNewsLetter;
 
 //setters/getters
 
}

Create RegistrationBean which is a Managed Bean.

package com.sivalabs.pfdemo.mb;

import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

import com.sivalabs.pfdemo.mb.ui.RegistrationForm;

@ManagedBean
@RequestScoped
public class RegistrationBean
{
 private RegistrationForm registrationForm = null;
 private List<String> interests = null;
 private List<String> genders = null;
 
 public RegistrationBean()
 {
  this.interests = new ArrayList<String>();
  this.interests.add("Sports");
  this.interests.add("Gadgets");
  this.interests.add("Politics");
  this.interests.add("Technology");
  
  this.genders = new ArrayList<String>();
  this.genders.add("Male");
  this.genders.add("Female");
 
 }
 
 public String register()
 {
  System.out.println("register.....");
  //store data in DB
  System.out.println(this.registrationForm);
  return "welcome";//go to welcome.xhtml
 }
 
 public RegistrationForm getRegistrationForm()
 {
  if(this.registrationForm == null){
   this.registrationForm = new RegistrationForm();
  }
  return registrationForm;
 }

 public void setRegistrationForm(RegistrationForm registrationForm)
 {
  this.registrationForm = registrationForm;
 }

 public List<String> getInterests()
 {
  return interests;
 }

 public void setInterests(List<String> interests)
 {
  this.interests = interests;
 }

 public List<String> getGenders()
 {
  return genders;
 }

 public void setGenders(List<String> genders)
 {
  this.genders = genders;
 }
 
}

Step#4: Create registration.xhtml JSF page.

<!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"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui"> 

<h:head>

</h:head> 
<h:body> 
 <h2>Registration Form</h2>
 <h:form>
  <p:fieldset legend="Registration Form" widgetVar="regWidget" style="width: 600px;">
   <h:panelGrid columns="3" width="550" border="0">
    <h:outputLabel value="UserName" />
    <p:inputText value="#{registrationBean.registrationForm.userName}" 
       id="userName"
        required="true" 
        requiredMessage="UserName is required"
        validatorMessage="UsesrName should be of length from 5 to 15 chars"
        >
     <f:validateLength minimum="5" maximum="15" for="userName"></f:validateLength>
    </p:inputText>
    <p:message for="userName"/>
    
    
    <h:outputLabel value="Password" />
    <p:password value="#{registrationBean.registrationForm.password}"
       id="password"
       required="true" 
       requiredMessage="Password is required"
       validatorMessage="Password should be of length from 5 to 15 chars"
       >
      <f:validateLength minimum="5" maximum="15" for="password"></f:validateLength>
    </p:password>
    <p:message for="password" />
    
    <h:outputLabel value="FirstName" />
    <p:inputText value="#{registrationBean.registrationForm.firstName}"
       id="firstName"
       required="true" 
       requiredMessage="FirstName is required"
       validatorMessage="FirstName should be of length from 5 to 15 chars"
       >
      <f:validateLength minimum="5" maximum="15" for="firstName"></f:validateLength>
    </p:inputText>
    <p:message for="firstName" />
    
    
    <h:outputLabel value="LastName" />
    <p:inputText value="#{registrationBean.registrationForm.lastName}"
       id="lastName"></p:inputText>
    <p:message for="lastName" />
    
    <h:outputLabel value="Email" />
    <p:inputText value="#{registrationBean.registrationForm.email}"
       id="email"
       validatorMessage="Invalid Email">
     <f:validateRegex pattern="[a-zA-Z0-9]+@[a-zA-Z]+.[a-zA-Z]{2,3}"></f:validateRegex>   
    </p:inputText>
    <p:message for="email" />
    
    <h:outputLabel value="Phone" />
    <p:inputText value="#{registrationBean.registrationForm.phone}"
       id="phone"></p:inputText>
    <p:message for="phone" />
    
    <h:outputLabel value="DOB" />
    <p:calendar value="#{registrationBean.registrationForm.dob}"
       id="dob"
       converterMessage="Invalid Date"
       pattern="dd-MM-yyyy">
     
    </p:calendar>
    <p:message for="dob" />
    
    <h:outputLabel value="Gender" />
    <h:selectOneRadio id="gender" 
          value="#{registrationBean.registrationForm.gender}" >
     <f:selectItems value="#{registrationBean.genders}" 
         var="gOp"
         itemLabel="#{gOp}"
         itemValue="#{gOp}"/>
    </h:selectOneRadio>
    <p:message for="gender" />
    
    
    <h:outputLabel value="Interests" />
    <p:selectManyCheckbox id="interests"
           value="#{registrationBean.registrationForm.interests}"
           layout="pageDirection">
     <f:selectItems value="#{registrationBean.interests}" var="intrOp"></f:selectItems>
    </p:selectManyCheckbox>
    <p:message for="interests" />
    
    <p:commandButton value="Register" action="#{registrationBean.register}" ajax="false"></p:commandButton>
   </h:panelGrid>
  </p:fieldset>
 
 </h:form>
</h:body> 
</html>

Step#5:
Now go to http://localhost:8080/primfaces-demo/registration.xhtml

Here key things to note are:
1. We need to add primefaces taglib using xmlns:p="http://primefaces.org/ui"
2. PrimeFaces Command Button/Links bydefault use Ajax submit. So to do non-ajax submit we should use ajax="false".
3. To enable autocompletion for <p:> tags, right click on project --> Properties --> ProjectFacests --> Select Java Server Faces 2.0 checkbox and Apply.


In the next article PrimeFaces3 Tutorial : Form Validation Using BeanValidation API(JSR-303)I have explained how to validate the forms using JSR-303 Bean Validation API.

8 comments:

  1. Thanks for yours well written tutorial

    ReplyDelete
  2. Thanks a good thing, if you add welcome.xhtml it will be absolutely usefull for beginners

    ReplyDelete
  3. Hi, I'm quite new for primefaces , looks very nice. I would like to know how can I use primefaces and JSF 2.x to handle several pages, not just a registration page. Suppose after registering in a form and validated , then need to go to a second page (e,g. details.xhtml and then again from that page go to another page: itemscounts.xhtml, and then eventually g back to index page and jump again to another page. This will be a more real project and test if primefaces do the jobs well.
    yours
    jj

    ReplyDelete
  4. Diğer yazılarınızda beğenerek okudum. Bu yazınız çok güzel, bu yazınızda yorum yaparak belirtmek istedim. Paylaşımlarınız için teşekkür ederim. Başarılar dilerim.

    ReplyDelete
  5. Thank you for this tutorial. Quite simple to follow. I made adjustments to the calendar control to allow more than 10 years back and display the month and year navigation control. I also changed the phone to an inputMask instead of an inputText to force a proper phone number entry for USA just for my own testing and learning.

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. I get this error every time I use f tag (nomatter what is after : )

    Error Parsing /new-user.xhtml: Error Traced[line: 56] The prefix "f" for element "f:selectItems" is not bound.

    Anyone knows whats the problem?

    ReplyDelete