JSF 2 comes with a very flexible conditional navigation rule to solve
the complex page navigation flow, see the following conditional
navigation rule example :
start.xhtml
With JSF 2, you can add some conditional checking before it move to the payment page, see following :
faces-config.xml
This is equal to the following Java code :
The code should be self explanatory enough.
Example 1
When the button is clicked, it hits the “paymentController.orderQty < 100” criteria and move to the “ordermore.xhtml” page.
Example 2
When the button is clicked, it hits the “paymentController.registerCompleted” criteria and move to the “payment.xhtml” page.
Example 3
When the button is clicked, it failed all the checking criteria and move to the “register.xhtml” page.
Moreover, It should include the multiple conditional checking as well, like this
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>
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 < 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>
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"; } } }
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.
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; ...
Example 2
public class PaymentController implements Serializable { public boolean registerCompleted = true; public int orderQty = 200; ...
Example 3
public class PaymentController implements Serializable { public boolean registerCompleted = false; public int orderQty = 200; ...
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 < 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>
<navigation-rule> <from-view-id>start.xhtml</from-view-id> <navigation-case> <from-outcome>payment</from-outcome> <if>#{paymentController.orderQty < 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? :)
JSF 2 conditional navigation rule, … quite similar with the Spring Web Flow, right? :)
Download Source Code
Download it – JSF-2-Conditional-Navigation-Example.zip (11KB)