JSF Workflows in a Single Page

Wizards, Conversations, Workflows in web development. Whatever you call it, it’s not trivial to deal with these properly. PrimeFaces wizard component features an AJAX powered UI and built-in partial validation to implement a conversation in a single JSF page. In the following example there’re 3 tabs corresponding to each steps of the flow and last tab is for confirmation.

wiz

This is the userWizard bean, which is simply at viewScope to span multiple requests. Session scope will work as well but optimal scope for this is the viewScope.

package org.primefaces.examples.view;

import org.primefaces.examples.domain.User;
import org.primefaces.optimus.config.Scope;
import org.primefaces.optimus.config.annotations.Controller;

@Controller(name="userWizard", scope = Scope.VIEW)
public class UserWizard {

	private User user = new User();

	public User getUser() {
		return user;
	}
	public void setUser(User user) {
		this.user = user;
	}

	public void save(ActionEvent actionEvent) {
		//Persist user
		FacesMessage msg = new FacesMessage("Successful", "Welcome :" + user.getFirstname());
		FacesContext.getCurrentInstance().addMessage(null, msg);
	}
}

And the single page that contains all steps;

<p:wizard height="200" width="600">
<p:tab>
<p:panel header="Personal Details">

	<h:messages errorClass="error"/>

	<h:panelGrid columns="2">
		<h:outputText value="Firstname: *" />
		<h:inputText value="#{userWizard.user.firstname}" required="true"/>

		<h:outputText value="Lastname: *" />
		<h:inputText value="#{userWizard.user.lastname}" required="true"/>

		<h:outputText value="Age: " />
		<h:inputText value="#{userWizard.user.age}" />
	 </h:panelGrid>
	  	</p:panel>
    </p:tab>
<p:tab>
<p:panel header="Adress Details">

	  	<h:messages errorClass="error"/>

	   		<h:panelGrid columns="2" columnClasses="label, value">
				<h:outputText value="Street: " />
				<h:inputText value="#{userWizard.user.street}" />

				<h:outputText value="Postal Code: " />
				<h:inputText value="#{userWizard.user.postalCode}" />

				<h:outputText value="City: " />
				<h:inputText value="#{userWizard.user.city}" />
	   		</h:panelGrid>
	 	</p:panel>
    </p:tab>
<p:tab>
<p:panel header="Contact Information">

	   		<h:messages errorClass="error"/>

	   		<h:panelGrid columns="2">
				<h:outputText value="Email: *" />
				<h:inputText value="#{userWizard.user.email}" required="true"/>

				<h:outputText value="Phone: " />
				<h:inputText value="#{userWizard.user.phone}"/>

				<h:outputText value="Additional Info: " />
				<h:inputText value="#{userWizard.user.info}"/>
	   		</h:panelGrid>

		</p:panel>
    </p:tab>
<p:tab>
<p:panel header="Confirmation">

	    	<h:panelGrid id="confirmation" columns="6">
				<h:outputText value="Firstname: " />
				<h:outputText value="#{userWizard.user.firstname}"/>

				<h:outputText value="Lastname: " />
				<h:outputText value="#{userWizard.user.lastname}"/>

				<h:outputText value="Age: " />
				<h:outputText value="#{userWizard.user.age}" />

				<h:outputText value="Street: " />
				<h:outputText value="#{userWizard.user.street}" />

				<h:outputText value="Postal Code: " />
				<h:outputText value="#{userWizard.user.postalCode}"/>

				<h:outputText value="City: " />
				<h:outputText value="#{userWizard.user.city}"/>

				<h:outputText value="Email: " />
				<h:outputText value="#{userWizard.user.email}" />

				<h:outputText value="Phone " />
				<h:outputText value="#{userWizard.user.phone}"/>

				<h:outputText value="Info: " />
				<h:outputText value="#{userWizard.user.info}"/>

				<h:outputText />
				<h:outputText />
			</h:panelGrid>
<p:commandButton value="Submit" actionListener="#{userWizard.save}" />

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

</p:wizard>

Ajax and Partial Validation

When you click next or previous, first the current tab is validated and if it’s valid next tab contents are loaded and update with ajax. If step is not valid, current tab is redisplayed with validation errors. Validation is done partially meaning only the current tab will be validated although wizard is enclosed in a single form.

Online Demos

There’re two examples of wizard deployed online;

Wizard with slide effect
Wizard with toggle effect

Comments are closed.

%d bloggers like this: