RichFaces modal dialog support
I just want to share my experience of RichFaces modal dialog support without using Spring JS. Steps to introduce such support into your program (with facelets):
1) Request for popup from server:
RichFacesDialogAjaxHandler.java:
Code:
public class RichFacesDialogAjaxHandler extends RichFacesAjaxHandler
{
private static final Logger log = Logger.getLogger(RichFacesDialogAjaxHandler.class);
@Override
public void sendAjaxRedirect
(String targetUrl, HttpServletRequest request, HttpServletResponse response, boolean popup)
throws IOException
{
if( popup && isRichFacesAjaxRequest(request, response) )
{
log.debug("Sending dialog request: " + targetUrl);
response.setHeader("RichFaces-Modal-View", "true");
response.setHeader("RichFaces-Redirect-URL", response.encodeRedirectURL(targetUrl));
return;
}
super.sendAjaxRedirect(targetUrl, request, response, popup);
}
}
2) Processing request on client:
dialog.js:
Code:
var ModalDialogSupport = {};
ModalDialogSupport.originalProcessResponse = A4J.AJAX.processResponse;
A4J.AJAX.processResponse = function(req)
{
try
{
if( req.getResponseHeader("RichFaces-Modal-View") == "true" )
{
var url = req.getResponseHeader("RichFaces-Redirect-URL");
LOG.debug("Request for modal dialog: " + url);
var oncomplete = function(request, domEvt, data)
{
LOG.debug("Request for modal dialog is completed");
for( var i = 0; i < ModalPanel.panels.length; i++ )
{
var pnl = ModalPanel.panels[i];
if( pnl && pnl.markerId )
{
LOG.debug("Dialog id: " + pnl.markerId.id);
}
}
LOG.debug("Last dialog id: " + ModalDialogSupport.lastDialogId);
Richfaces.showModalPanel( ModalDialogSupport.lastDialogId );
};
A4J.AJAX.Submit
("_viewRoot", "modalPanel_region_form", null,
{
"actionUrl": url,
"oncomplete": oncomplete
}
);
return;
}
ModalDialogSupport.originalProcessResponse(req);
}
catch( e )
{
LOG.error("Error in processResponse: " + e.message);
}
};
ModalDialogSupport.lastDialogId = undefined;
ModalDialogSupport.registerDialog = function(dialogId)
{
ModalDialogSupport.lastDialogId = dialogId;
};
3) Support for dialogs on pages:
modalDialogSupport.xhtml:
HTML Code:
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j">
<!--@elvariable id="modalLevel" type="java.lang.Integer"-->
<c:set var="modalPanelRegionId" value="modalPanel#{modalLevel}_region"/>
<c:if test="#{modalLevel==null}">
<a4j:loadScript src="/scripts/dialog.js"/>
<h:form id="modalPanel_region_form"/>
</c:if>
<a4j:outputPanel id="#{modalPanelRegionId}"/>
</ui:composition>
modalDialogTemplate.xhtml:
HTML Code:
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<!--@elvariable id="modalPanelTitle" type="java.lang.String"-->
<!--@elvariable id="modalLevel" type="java.lang.Integer"-->
<c:set var="modalPanelId" value="modalPanel#{modalLevel}"/>
<a4j:outputPanel id="#{modalPanelId}_region" ajaxRendered="true">
<script type="text/javascript">
ModalDialogSupport.registerDialog('#{modalPanelId}');
</script>
<rich:modalPanel id="#{modalPanelId}" autosized="true" showWhenRendered="false">
<f:facet name="header">
<h:outputText value="#{modalPanelTitle}"/>
</f:facet>
<f:facet name="controls">
<h:graphicImage
value="/images/closePanel.png"
style="cursor:pointer"
alt="Close"
onclick="#{modalPanelId}_cancelDialog();"/>
</f:facet>
<rich:hotKey
key="esc"
handler="#{modalPanelId}_cancelDialog();"/>
<h:form id="#{modalPanelId}_form">
<a4j:jsFunction
name="#{modalPanelId}_cancelDialog"
immediate="true"
action="cancel"
onbeforedomupdate="Richfaces.hideModalPanel('#{modalPanelId}');"
/>
</h:form>
<ui:insert name="modalPanelContent"/>
</rich:modalPanel>
<!-- Nesting dialog support -->
<ui:include src="/WEB-INF/dialogs/modalDialogSupport.xhtml">
<ui:param name="modalLevel" value="#{modalLevel+1}"/>
</ui:include>
</a4j:outputPanel>
</ui:composition>
4) Usage:
confirmDialog.xhtml:
HTML Code:
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
template="/WEB-INF/dialogs/modalDialogTemplate.xhtml">
<ui:define name="modalPanelContent">
<table>
<tr>
<td align="center">
<h:outputText value="Are you sure?"/>
</td>
</tr>
<tr>
<td align="center">
<h:form id="toolbarForm">
<table cellspacing="10">
<tr>
<td>
<a4j:commandButton id="okButton" styleClass="rich-button"
value="OK" immediate="true" action="ok"/>
</td>
<td>
<a4j:commandButton id="cancelButton" styleClass="rich-button"
value="Cancel" immediate="true" action="cancel"/>
</td>
</tr>
</table>
</h:form>
</td>
</tr>
</table>
</ui:define>
</ui:composition>
main_template.xhtml (somewhere in the page):
HTML Code:
<ui:include src="/WEB-INF/dialogs/modalDialogSupport.xhtml"/>
flow.xml:
HTML Code:
<view-state id="confirmState" view="confirmDialog.xhtml" popup="true">
<transition on="ok" to="confirmState2"/>
<transition on="cancel" to="processCancelled" />
</view-state>
<view-state id="confirmState2" view="confirmDialog.xhtml" popup="true">
<on-entry>
<set name="viewScope.modalLevel" value="1" type="int"/>
</on-entry>
<transition on="ok" to="nextStage"/>
<transition on="cancel" to="confirmState" />
</view-state>