Showing posts with label Navigation Rule. Show all posts
Showing posts with label Navigation Rule. Show all posts

Wednesday, 25 September 2013

Conditional Navigation rule in JSF2.0

// siddhu vydyabhushana // 4 comments
JSF 2 comes with a very flexible conditional navigation rule to solve the complex page navigation flow, see the following conditional navigation rule example :

1. JSF Page

A simple JSF page, with a button to move from this page to the payment page.
start.xhtml
<?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:h="http://java.sun.com/jsf/html">
 
    <h:body>
    	<h2>This is start.xhtml</h2>
	<h:form>
    	   <h:commandButton action="payment" value="Payment" />
	</h:form>
    </h:body>
</html>

2. Managed Bean

A managed bean to provide sample data to perform the conditional checking in the navigation rule.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped; 
import java.io.Serializable;
 
@ManagedBean
@SessionScoped
public class PaymentController implements Serializable {
 
	private static final long serialVersionUID = 1L;
 
	public boolean registerCompleted = true;
	public int orderQty = 99;
 
	//getter and setter methods
}

3. Conditional Navigation Rule

Normally, you declared the simple navigation rule in the “faces-config.xml” like this :
<navigation-rule>
	<from-view-id>start.xhtml</from-view-id>
	<navigation-case>
		<from-outcome>payment</from-outcome>
		<to-view-id>payment.xhtml</to-view-id>
	</navigation-case>
</navigation-rule>
With JSF 2, you can add some conditional checking before it move to the payment page, see following :
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
    version="2.0">
 
	<navigation-rule>
		<from-view-id>start.xhtml</from-view-id>
		<navigation-case>
			<from-outcome>payment</from-outcome>
			<if>#{paymentController.orderQty &lt; 100}</if>
			<to-view-id>ordermore.xhtml</to-view-id>
		</navigation-case>
		<navigation-case>
			<from-outcome>payment</from-outcome>
			<if>#{paymentController.registerCompleted}</if>
			<to-view-id>payment.xhtml</to-view-id>
		</navigation-case>
		<navigation-case>
			<from-outcome>payment</from-outcome>
			<to-view-id>register.xhtml</to-view-id>
		</navigation-case>
	</navigation-rule>
 
</faces-config>
This is equal to the following Java code :
if (from-view-id == "start.xhtml"){
 
   if(from-outcome == "payment"){
 
      if(paymentController.orderQty < 100){
	  return "ordermore";
      }else if(paymentController.registerCompleted){
	  return "payment";
      }else{
	  return "register";
      }
 
   }
 
}
The code should be self explanatory enough.
Note
In the conditional navigation rule, the sequence of the navigation rule does affect the navigation flow, always put the highest checking priority in the top.

4. Testing

Different data sets for testing :
Example 1
public class PaymentController implements Serializable {
 
	public boolean registerCompleted = true;
	public int orderQty = 99;
	...
When the button is clicked, it hits the “paymentController.orderQty < 100” criteria and move to the “ordermore.xhtml” page.
Example 2
public class PaymentController implements Serializable {
 
	public boolean registerCompleted = true;
	public int orderQty = 200;
	...
When the button is clicked, it hits the “paymentController.registerCompleted” criteria and move to the “payment.xhtml” page.
Example 3
public class PaymentController implements Serializable {
 
	public boolean registerCompleted = false;
	public int orderQty = 200;
	...
When the button is clicked, it failed all the checking criteria and move to the “register.xhtml” page.

Suggestion

In JSF 2.0, there is no “else” tag in the conditional navigation rule, wish JSF team can include the “else” tag in the future release. For example,
   <navigation-rule>
	<from-view-id>start.xhtml</from-view-id>
	<navigation-case>
		<from-outcome>payment</from-outcome>
		<if>#{paymentController.orderQty &lt; 100}</if>
			<to-view-id>ordermore.xhtml</to-view-id>
		<else if>#{paymentController.registerCompleted}</else if>
			<to-view-id>payment.xhtml</to-view-id>
		<else>
			<to-view-id>register.xhtml</to-view-id>
	</navigation-case>
   </navigation-rule>
Moreover, It should include the multiple conditional checking as well, like this
   <navigation-rule>
	<from-view-id>start.xhtml</from-view-id>
	<navigation-case>
		<from-outcome>payment</from-outcome>
		<if>#{paymentController.orderQty &lt; 100} && #{paymentController.xxx}</if>
			<to-view-id>ordermore.xhtml</to-view-id>
		<else if>#{paymentController.registerCompleted}</else if>
			<to-view-id>payment.xhtml</to-view-id>
		<else>
			<to-view-id>register.xhtml</to-view-id>
	</navigation-case>
   </navigation-rule>
Thought…
JSF 2 conditional navigation rule, … quite similar with the Spring Web Flow, right? :)

Download Source Code

 
Read More