Richfaces - Modal Panel As A Wizard

Posted on June 25, 2009


Richfaces 'Modal Panel' component can be used to create a 'Dialog Box' or a 'Wizard' (or Wizard like behaviour), which is useful, when some part of the website/application has to ask for the input from the user, in steps. It can be customized, as per the requirements of that particular application, although everything that you implement doesn't sound like a standard mechanism, from the 'Richfaces' AJAX framework. Below is an example of creating a 'Wizard' out of a 'Richfaces Modal Panel' component:

1) Lets suppose that this 'Wizard' is opened, when a user clicks on some link (or any other AJAX/Javascript event)...and 2 steps, for that Wizard. So, the modal panel is on one page and there would be 2 other pages that are to be included, in the modal panel, to get that 'Wizard' like behavior. In my case, I'm using JSF and Facelets (Xhtml files). Below is a code snippet for the main page (where the modal panel is included):

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j">

<ui:composition>
...........
...........
............

<rich:modalPanel id="panel1">
<f:facet name="header">
<h:outputText value="Test" />
</f:facet>

<f:facet name="controls">
<h:commandLink value="Close"
style="cursor:pointer"
onclick="Richfaces.hideModalPanel('panel1')" />
</f:facet>

<a4j:include binding="#{someBean.include}" viewId="/view/include1.xhtml"/>
</rich:modalPanel>
</ui:composition>
</html>


2) And below is the code snippet, for the first included page, on the modal panel:

<!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"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j">

<ui:composition>
...........
...........
............

<h:form>
<h:panelGrid columns="2">
<h:outputText value="#{msg.input}"
<h:inputText value="#{someBean.someText}"/>

<rich:spacer width="20"/>
<a4j:commandButton value="#{msg.submit}" action="include2" reRender="wizard"/>
</h:panelGrid>
</h:form>
</ui:composition>
</html>


Note that the above included page, doesn't need to have f:view tags. Also, there are a couple of important points to consider from the Richfaces documentation:

RichFaces allows to organize a page flow inside the component. This is a typical scenario for Wizard like behavior. The new content is rendered inside the area. The content is taken from the navigation rule of the faces configuration file (usually, the faces-config.xml). Note, that the content of the "wizard" is not isolated from the rest of the page. The included page should not have own (it does not matter if you use facelets). You need to have an Ajax component inside the to navigate between the wizard pages. Otherwize, the whole page update will be performed.

If you want to involve the server side validators and navigate to the next page only if the Validation phase is passed successfully, you can replace with and point to the action method that navigates to the next page. If Validation process fails, the partial page update will occur and you will see an error message. Otherwize, the application proceeds to the next page. Make sure, you define option for the navigation rule to avoid memory leaks.


3) And below is the "include2.xhtml", which is shown as a second step, for that wizard. This wizard appears only if the validation succeeds on the previously included page (in case, if you have any input validations).

<!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"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j">

<ui:composition>
...........
...........
............

<h:form>
<a4j:commandButton value="#{msg.confirm}" action="#{someBean.doSomeBusinessShit}" reRender="someId,wizard"/>
<a4j:commandButton value="#{msg.cancel}" action="#{someBean.reset}" onclick="javascript:Richfaces.hideModalPanel('panel1')" reRender="wizard"/>
</h:form>
</ui:composition>
</html>


4) And the faces-config.xml configuration, is as follows:

<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
............
............
............

<navigation-rule>
<from-view-id>/view/include1.xhtml</from-view-id>
<navigation-case>
<from-outcome>include2</from-outcome>
<to-view-id>/view/include2.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>



...And hey, its not yet over. If you happened to implement the above stuff and if you navigated to the second step, clicked 'Cancel' and tried to open the 'Wizard' again, the second included page, opens up directly, without the first step (included page). To remedy this, I've to reset the "viewId" in the "a4j:include" component. The "a4j:include" tag, already includes a binding. The only thing that has to be done is to implement the "reset" method, as below:

package echo;

import org.ajax4jsf.component.html.Include;

public class SomeBean {
.........
.........
private Include include;

.......
.......
.......

public void reset() {
include.setViewId("/view/include1.xhtml");
}
}


Blog Categories
Disclaimer
The views expressed on this blog are my personal views and do not reflect the views of my employer or campaigns I am supporting.

All sample code is provided for illustrative purposes only. These examples have not been thoroughly tested under all conditions. The writer therefore, cannot guarantee or imply reliability, serviceability, or function of these programs.

All programs contained herein are provided to you "AS IS" without any warranties of any kind. The implied warranties of non-infringement, merchantability and fitness for a particular purpose are expressly disclaimed.