Primefaces Wizard Component Example

Filed Under: PrimeFaces

Primefaces Wizard Component provides an ajax enhanced UI to implement a workflow easily in a single page. Wizard consists of several child tab components where each tab represents a step in the process.

Primefaces Wizard

Tag Wizard
Component Class org.primefaces.component.wizard.Wizard
Component Type org.primefaces.component.Wizard
Component Family org.primefaces.component
Renderer Type org.primefaces.component.WizardRenderer
Renderer Class org.primefaces.component.wizard.WizardRenderer

Primefaces Wizard Attributes

Name Default Type Description
id null String Unique identifier of the component.
rendered true Boolean Boolean value to specify the rendering of the component, when set to false component won’t be rendered
binding null Object An el expression that maps to a server side UIComponent instance in a backing bean
step 0 String Id of the current step in flow
style null String Style of the main wizard container element.
styleClass null String Style class of the main wizard container element.
flowListener null MethodExpr Server side listener to invoke when wizard attempts to go forward or back
showNavBar true Boolean Specifies visibility of default navigator arrows.
showStepStatus true Boolean Specifies visibility of default step title bar.
onback null String Javascript event handler to be invoked when flow goes back
onnext null String Javascript event handler to be invoked when flow goes forward
nextLabel null String Label of next navigation button.
backLabel null String Label of back navigation button.
widgetVar null String

Getting Started With Primefaces Wizard

Following below simple example that provides you the using of Wizard component for initiating a tutorial registration wizard.

tutorialRegistration.xhtml


<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:p="http://primefaces.org/ui">
	<h:head>
		<title>Wizard</title>
		<script name="jquery/jquery.js" library="primefaces"></script>
	</h:head>
	<h:form>
		<div style="width:500px">
			<p:wizard>
				<p:tab id="tutorialBasicInformation">
					<p:panelGrid columns="2">
						<p:outputLabel value="Tutorial Name:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialName}"></h:inputText>
						<p:outputLabel value="Tutorial Instructor:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialInstructor}"></h:inputText>
						<p:outputLabel value="Tutorial Period:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialPeriod}"></h:inputText>
					</p:panelGrid>
				</p:tab>
				<p:tab id="tutorialRegistration">
					<p:panelGrid columns="2">
						<p:outputLabel value="Tutorial Price:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialPrice}"></h:inputText>
						<p:outputLabel value="Tutorial Start Date:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialStartDate}"></h:inputText>
						<p:outputLabel value="Tutorial End Date:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialEndDate}"></h:inputText>
					</p:panelGrid>
					<h:commandButton value="Register" action="#{tutorialRegistrationBean.register}"></h:commandButton>
				</p:tab>
			</p:wizard>
			<p:dataTable value="#{tutorialRegistrationBean.tutorials}" var="tutorial">
				<f:facet name="header">
					<p:outputLabel value="Tutorials List"/>
				</f:facet>
				<p:column>
					<h:outputText value="#{tutorial.tutorialName}"/>
				</p:column>
				<p:column>
					<h:outputText value="#{tutorial.tutorialInstructor}"/>
				</p:column>
				<p:column>
					<h:outputText value="#{tutorial.tutorialStartDate}"/>
				</p:column>
				<p:column>
					<h:outputText value="#{tutorial.tutorialEndDate}"/>
				</p:column>
			</p:dataTable>
		</div>
	</h:form>
</html>

package com.journaldev.prime.faces.beans;

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

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

import com.journaldev.data.Tutorial;

@ManagedBean
@SessionScoped
public class TutorialRegistrationBean {

	private List<Tutorial> tutorials = new ArrayList<Tutorial>();
	private Tutorial tutorial = new Tutorial();

	public Tutorial getTutorial() {
		return tutorial;
	}

	public void setTutorial(Tutorial tutorial) {
		this.tutorial = tutorial;
	}

	public List<Tutorial> getTutorials() {
		return tutorials;
	}

	public void setTutorials(List<Tutorial> tutorials) {
		this.tutorials = tutorials;
	}

	public String register(){
		this.tutorials.add(tutorial);
		this.tutorial = new Tutorial();
		return "";
	}
}

package com.journaldev.data;

public class Tutorial {

	private String tutorialName;
	private String tutorialInstructor;
	private String tutorialPeriod;
	private String tutorialPrice;
	private String tutorialStartDate;
	private String tutorialEndDate;

	public String getTutorialName() {
		return tutorialName;
	}
	public void setTutorialName(String tutorialName) {
		this.tutorialName = tutorialName;
	}
	public String getTutorialInstructor() {
		return tutorialInstructor;
	}
	public void setTutorialInstructor(String tutorialInstructor) {
		this.tutorialInstructor = tutorialInstructor;
	}
	public String getTutorialPeriod() {
		return tutorialPeriod;
	}
	public void setTutorialPeriod(String tutorialPeriod) {
		this.tutorialPeriod = tutorialPeriod;
	}
	public String getTutorialPrice() {
		return tutorialPrice;
	}
	public void setTutorialPrice(String tutorialPrice) {
		this.tutorialPrice = tutorialPrice;
	}
	public String getTutorialStartDate() {
		return tutorialStartDate;
	}
	public void setTutorialStartDate(String tutorialStartDate) {
		this.tutorialStartDate = tutorialStartDate;
	}
	public String getTutorialEndDate() {
		return tutorialEndDate;
	}
	public void setTutorialEndDate(String tutorialEndDate) {
		this.tutorialEndDate = tutorialEndDate;
	}
}

Here’s a detailed explanation for the code above:

  • A tutorial plain old java object is requested for holding the tutorial information that user will provide.
  • A TutorialRegistrationBean bean is developed for handle the registration process.
  • Wizard component used two tabs for defining the required steps; first tab for gathering the basic information of tutorial while the second tab for remaining information in addition to register action that will get defined tutorial retained temporarily inside a list of tutorial.
  • DataTable component will be used for displaying the tutorials registered.
  • Switching between steps is based on ajax, meaning each step is loaded dynamically with ajax. Partial validation is also happened partially; the only current steps is validated, if the current step is valid, next tab’s content are loaded with ajax.
  • Validations aren’t executed when flow goes back.

Primefaces Wizard - Step-APrimefaces Wizard - Step-B Fill DataPrimefaces Wizard - Step-A Fill DataPrimefaces Wizard - Register Tutroial

  • You can navigate between Wizard’s defined steps by interacting with Next and Back built-in actions.

FlowListener

Wizard component provides a listener mechanism that associated with a defined method for listening wizard attempts to go back or forward. Following the same sample discussed previously with FlowListener added functionality.

tutorialRegistration.xhtml


<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:p="http://primefaces.org/ui">
	<h:head>
		<title>Wizard</title>
		<script name="jquery/jquery.js" library="primefaces"></script>
	</h:head>
	<h:form>
		<div style="width:500px">
			<p:wizard flowListener="#{tutorialRegistrationBean.flowListener}">
				<p:tab id="tutorialBasicInformation">
					<p:panelGrid columns="2">
						<p:outputLabel value="Tutorial Name:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialName}"></h:inputText>
						<p:outputLabel value="Tutorial Instructor:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialInstructor}"></h:inputText>
						<p:outputLabel value="Tutorial Period:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialPeriod}"></h:inputText>
					</p:panelGrid>
				</p:tab>
				<p:tab id="tutorialRegistration">
					<p:panelGrid columns="2">
						<p:outputLabel value="Tutorial Price:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialPrice}"></h:inputText>
						<p:outputLabel value="Tutorial Start Date:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialStartDate}"></h:inputText>
						<p:outputLabel value="Tutorial End Date:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialEndDate}"></h:inputText>
					</p:panelGrid>
					<h:commandButton value="Register" action="#{tutorialRegistrationBean.register}"></h:commandButton>
				</p:tab>
			</p:wizard>
			<p:dataTable value="#{tutorialRegistrationBean.tutorials}" var="tutorial">
				<f:facet name="header">
					<p:outputLabel value="Tutorials List"/>
				</f:facet>
				<p:column>
					<h:outputText value="#{tutorial.tutorialName}"/>
				</p:column>
				<p:column>
					<h:outputText value="#{tutorial.tutorialInstructor}"/>
				</p:column>
				<p:column>
					<h:outputText value="#{tutorial.tutorialStartDate}"/>
				</p:column>
				<p:column>
					<h:outputText value="#{tutorial.tutorialEndDate}"/>
				</p:column>
			</p:dataTable>
		</div>
	</h:form>
</html>

package com.journaldev.prime.faces.beans;

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

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

import org.primefaces.event.FlowEvent;

import com.journaldev.data.Tutorial;

@ManagedBean
@SessionScoped
public class TutorialRegistrationBean {

private List tutorials = new ArrayList();
private Tutorial tutorial = new Tutorial();

public Tutorial getTutorial() {
return tutorial;
}

public void setTutorial(Tutorial tutorial) {
this.tutorial = tutorial;
}

public List getTutorials() {
return tutorials;
}

public void setTutorials(List tutorials) {
this.tutorials = tutorials;
}

public String register(){
this.tutorials.add(tutorial);
this.tutorial = new Tutorial();
return "";
}

public String flowListener(FlowEvent event){
System.out.println("Flow Event Happened :: New Step :: "+event.getNewStep()+" :: Old Step :: "+event.getOldStep());
return event.getNewStep();
}
}

Here’s the detailed explanation for the code above:

  • flowListener method has defined for handling the backward and forward events.
  • The ability to determine the old step and the next step by invoking their respective methods against FlowEvent object.
  • FlowListener associated method should return a String that specify the next step you would be moving on. Non linear manner can be achieved by returning the identifier for the referenced tab. Tabs referenced by id attribute, Tabs defined using tab component.

Primefaces Wizard - FlowListener

  • Forward event has been initiated thus an FlowEvent has been created. Old step and next step are accessed and their identifiers are displayed.
  • In case you’ve required some other components to be notified as a result of Wizard flow, RequestContext.update(clientId) api is used.

Primefaces Wizard Client Side API

As experienced with all of Primefaces components, the component can be controlled by invoking JavaScript method against the WidgetVar attribute which its value would be an instance of PrimeFaces.widget.Wizard. This section will spot lights into these methods used for this purpose.

Method Params Return Type Description
next() void Proceeds to next step
back() void Proceeds to previous step
getStepIndex() Number Returns the index of current step.
showNextNav() void Shows next button.
hideNextNav() void Hides next button.
showBackNav() void Shows back button.
hideBackNav() void Hides back button.

Following sample example that provides you a basic HTML button to achieve next and back actions.

tutorialRegistration.xhtml


<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:p="http://primefaces.org/ui">
	<h:head>
		<title>Wizard</title>
		<script name="jquery/jquery.js" library="primefaces"></script>
		<script>
			function next(){
				PF('wizard').next();
			}

			function back(){
				PF('wizard').back();
			}
		</script>
	</h:head>
	<h:form>
		<div style="width:500px">
			<input value="Next" type="button" onclick="next();"/>
			<input value="Prev" type="button" onclick="back();"/>
			<p:wizard widgetVar="wizard" flowListener="#{tutorialRegistrationBean.flowListener}" showNavBar="false">
				<p:tab id="tutorialBasicInformation">
					<p:panelGrid columns="2">
						<p:outputLabel value="Tutorial Name:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialName}"></h:inputText>
						<p:outputLabel value="Tutorial Instructor:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialInstructor}"></h:inputText>
						<p:outputLabel value="Tutorial Period:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialPeriod}"></h:inputText>
					</p:panelGrid>
				</p:tab>
				<p:tab id="tutorialRegistration">
					<p:panelGrid columns="2">
						<p:outputLabel value="Tutorial Price:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialPrice}"></h:inputText>
						<p:outputLabel value="Tutorial Start Date:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialStartDate}"></h:inputText>
						<p:outputLabel value="Tutorial End Date:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialEndDate}"></h:inputText>
					</p:panelGrid>
					<h:commandButton value="Register" action="#{tutorialRegistrationBean.register}"></h:commandButton>
				</p:tab>
			</p:wizard>
			<p:dataTable value="#{tutorialRegistrationBean.tutorials}" var="tutorial">
				<f:facet name="header">
					<p:outputLabel value="Tutorials List"/>
				</f:facet>
				<p:column>
					<h:outputText value="#{tutorial.tutorialName}"/>
				</p:column>
				<p:column>
					<h:outputText value="#{tutorial.tutorialInstructor}"/>
				</p:column>
				<p:column>
					<h:outputText value="#{tutorial.tutorialStartDate}"/>
				</p:column>
				<p:column>
					<h:outputText value="#{tutorial.tutorialEndDate}"/>
				</p:column>
			</p:dataTable>
		</div>
	</h:form>
</html>

Here’s detailed explanation for the code above:

  • We’ve eliminated the built-in navigation by setting showNavBar to false.
  • We’ve provided two HTML button, one for next and second for previous.
  • We’ve controlled the Wizard by using its widgetVar JavaScript object.
  • We’ve used Client Side API to customize the Wizard component.

Primefaces Wizard - Client Side API - Step APrimefaces Wizard - Client Side API - Step BPrimefaces Wizard - Client Side API - Registration

Primefaces Wizard Client Side Callback

Wizard is equipped with onback and onnext attributes, in case you need to execute custom JavaScript after wizard goes back or forth. You just need to provide the names of JavaScript functions as the values of these attributes.

tutorialRegistration.xhtml


<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:p="http://primefaces.org/ui">
	<h:head>
		<title>Wizard</title>
		<script name="jquery/jquery.js" library="primefaces"></script>
		<script>
			function next(){
				PF('wizard').next();
			}

			function back(){
				PF('wizard').back();
			}

			function onBack(){
				alert('Back Client Side Callback');
			}

			function onnext(){
				alert('Next Client Side Callback');
			}
		</script>
	</h:head>
	<h:form>
		<div style="width:500px">
			<input value="Next" type="button" onclick="next();"/>
			<input value="Prev" type="button" onclick="back();"/>
			<p:wizard widgetVar="wizard" flowListener="#{tutorialRegistrationBean.flowListener}" showNavBar="false" onback="onBack();" onnext="onnext();">
				<p:tab id="tutorialBasicInformation">
					<p:panelGrid columns="2">
						<p:outputLabel value="Tutorial Name:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialName}"></h:inputText>
						<p:outputLabel value="Tutorial Instructor:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialInstructor}"></h:inputText>
						<p:outputLabel value="Tutorial Period:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialPeriod}"></h:inputText>
					</p:panelGrid>
				</p:tab>
				<p:tab id="tutorialRegistration">
					<p:panelGrid columns="2">
						<p:outputLabel value="Tutorial Price:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialPrice}"></h:inputText>
						<p:outputLabel value="Tutorial Start Date:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialStartDate}"></h:inputText>
						<p:outputLabel value="Tutorial End Date:"/><h:inputText value="#{tutorialRegistrationBean.tutorial.tutorialEndDate}"></h:inputText>
					</p:panelGrid>
					<h:commandButton value="Register" action="#{tutorialRegistrationBean.register}"></h:commandButton>
				</p:tab>
			</p:wizard>
			<p:dataTable value="#{tutorialRegistrationBean.tutorials}" var="tutorial">
				<f:facet name="header">
					<p:outputLabel value="Tutorials List"/>
				</f:facet>
				<p:column>
					<h:outputText value="#{tutorial.tutorialName}"/>
				</p:column>
				<p:column>
					<h:outputText value="#{tutorial.tutorialInstructor}"/>
				</p:column>
				<p:column>
					<h:outputText value="#{tutorial.tutorialStartDate}"/>
				</p:column>
				<p:column>
					<h:outputText value="#{tutorial.tutorialEndDate}"/>
				</p:column>
			</p:dataTable>
		</div>
	</h:form>
</html>

Primefaces Wizard - Client Side Callback - OnNextPrimefaces Wizard - Client Side Callback - OnBack

Primefaces Wizard Example Summary

Primefaces Wizard component help the user complete certain business scenario through moving on sequenced steps. You can download the sample project from the below link.

Comments

  1. Tibor Varga says:

    Hi! Nice introduction to Wizard widget. I’m missing only one thing.
    How can I programatically get the prev/next/actual Tab IDs in onFlowProcess method?

    public String onFlowProcess(FlowEvent event) {
    ….

    Wizard wizard = (Wizard) event.getSource();
    String prevTabId = wizard.getXXXXXPrevTabId();
    String nextTabId = wizard.getXXXXXNextTabId();
    String currentTabId = wizard.getXXXXXCurrentTabId();

    ….
    return prevTabId;
    }

    Thanks in advance.

  2. Surya teja ambati says:

    This example is so good for starters.
    I have a small doubt with wizards in primefaces.

    I would like to create a wizard which has label and values as you did, but the labels and values both has to be taken from database.

    Is it possible to retrieve label and values both from database?

  3. senthil kumar says:

    Excellent work It helped me,
    thanks
    sentil

    1. Mohammad Amr says:

      Thanks senthil kumar,

      Your feedback is highly appreciated.

      Regards,

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages