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="https://www.w3.org/1999/xhtml"
xmlns:ui="https://java.sun.com/jsf/facelets"
xmlns:h="https://java.sun.com/jsf/html"
xmlns:f="https://java.sun.com/jsf/core"
xmlns:p="https://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.
- 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="https://www.w3.org/1999/xhtml"
xmlns:ui="https://java.sun.com/jsf/facelets"
xmlns:h="https://java.sun.com/jsf/html"
xmlns:f="https://java.sun.com/jsf/core"
xmlns:p="https://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.
- 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="https://www.w3.org/1999/xhtml"
xmlns:ui="https://java.sun.com/jsf/facelets"
xmlns:h="https://java.sun.com/jsf/html"
xmlns:f="https://java.sun.com/jsf/core"
xmlns:p="https://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 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="https://www.w3.org/1999/xhtml"
xmlns:ui="https://java.sun.com/jsf/facelets"
xmlns:h="https://java.sun.com/jsf/html"
xmlns:f="https://java.sun.com/jsf/core"
xmlns:p="https://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 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.
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.
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?
Excellent work It helped me,
thanks
sentil
Thanks senthil kumar,
Your feedback is highly appreciated.
Regards,