Geek Lair

Posts Tagged ‘richfaces

JSF – Richfaces Ajax Modal Dialog

with 3 comments

Creating a Richfaces Modal dialog is simple enough as explained in the Richfaces reference document. But I wanted an ajax modal dialog which will be shown on click of a link. Here is how to go about it:

My requirement is, I have a user page with an “Update Profile” link. On clicking the link, a modal dialog should popup which has a form for updating the profile.

In the user page I have a form, since a4j:commandLink element should be in a form:

<h:form id="inboxForm">
	<div id="topBar">
    	<a4j:keepAlive beanName="userBean" ajaxOnly="true"/>
		<a4j:commandLink oncomplete="#{rich:component('editPanel')}.show()" 
			reRender="editPanel" value="#{msgs.updateProfile}">
			<f:setPropertyActionListener value="#{inbox.userLogin}" 
			target="#{userBean.currentUser}"/>
		</a4j:commandLink>
    	<h:commandLink action="#{login.logout}" value="#{msgs.logout}"/>
	</div>
</h:form>

userBean has a request scope and that is why I have an a4j:keepAlive element so that the bean is kept alive during the ajax call.

The a4j:commandLink has a f:setPropertyActionListener element which will set a the currentUser object on userBean. After the ajax request has been made, the editPanel, which is the modal dialog, will be re-rendered. The oncomplete attribute has a JavaScript call to show the modal dialog (by default, it will be hidden).

Here is my modal panel:

<a4j:outputPanel layout="none">
	<rich:modalPanel id="editPanel" width="530"  height="320"
		rendered="#{not empty userBean.currentUser}">
		<f:facet name="header">
            <h:outputText value="#{msgs.updateProfile}" />            
        </f:facet>
        <f:facet name="controls">
            <h:panelGroup>
                <h:graphicImage value="/css/images/close.png"
                    styleClass="hidelink" id="hidelink1" />
                <rich:componentControl for="editPanel" attachTo="hidelink1"
                    operation="hide" event="onclick"/>
            </h:panelGroup>
        </f:facet>
		
		<a4j:include viewId="/profile.jsp"/>
	</rich:modalPanel>
</a4j:outputPanel>

Since the modal panel should be rendered on an ajax call, I have it enclosed in a a4j:outputPanel tag. The layout="none" means that no html tag will be rendered. If no layout is specified, a span tag will be rendered. If layout="block", a div will be rendered.

The rich:modalPanel has a rendered="#{not empty userBean.currentUser}" attribute. It means that the modal panel will be rendered only when userBean.currentUser is not null.

The modal panel has a header facet which has a title and a close icon. The form is included with an a4j:include tag. Here is the profile.jsp:

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<%@taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
<%@taglib uri="http://richfaces.org/rich" prefix="rich"%>
<h:form id="profileForm">
<div id="profileContainer">
<a4j:outputPanel ajaxRendered="true">
	<div class="messages">
		<h:messages globalOnly="true"/>
	</div>
	<fieldset>			
	    <ul>
		<li>
		    <h:outputLabel value="#{msgs.firstName}" for="fname"/>
		    <div class="innerList">
			<ul>
			    <li>
				<h:inputText id="fname" 
				value="#{userBean.currentUser.userDetails.firstName}"
				maxlength="30">
				    <f:validateLength maximum="30"/>
				</h:inputText>
			    </li>
			    <li id="fnameErr" class="hidden">
				<h:message for="fname" errorClass="error" />
			    </li>
			</ul>
		    </div>				    
		</li>
		<li>
		    <h:outputLabel value="#{msgs.lastName}" for="lname"/>
		    <div class="innerList">
			<ul>
			    <li>
				<h:inputText id="lname" 
				value="#{userBean.currentUser.userDetails.lastName}"
				maxlength="30">
				    <f:validateLength maximum="30"/>
				</h:inputText>
			    </li>
			    <li id="lnameErr" class="hidden">
				<h:message for="lname" errorClass="error" />
			    </li>
			</ul>
		    </div>					
		</li>
		<li>
		    <h:outputLabel value="#{msgs.enterNewPassword}" for="pwd">
		    </h:outputLabel>
		    <div class="innerList">
			<ul>
			    <li>
				<h:inputSecret
				    id="pwd" value="#{userBean.password}" maxlength="15" redisplay="true"
				    requiredMessage="#{msgs.enterPasswordReq}">
				<f:validateLength minimum="6" maximum="15"/>
				</h:inputSecret>
			    </li>
			    <li><h:message for="pwd" errorClass="error" /></li>
			    <li id="pwdErr" class="hidden">
				<span class="error"><h:outputText value="#{msgs.enterPasswordReq}"/></span>
			    </li>
			    <li><h:outputText value="#{msgs.minPwdLenth}"/></li>
			</ul>				    
		    </div>
		</li>
		<li>
		    <h:outputLabel value="#{msgs.reenterNewPassword}" for="repwd">
		    </h:outputLabel>
		    <div class="innerList">
			<ul>
			    <li>
				<h:inputSecret
				    id="repwd" value="#{userBean.repassword}" maxlength="15" redisplay="true"
				    requiredMessage="#{msgs.reenterPasswordReq}">
					<f:validateLength maximum="15"/>
				</h:inputSecret>
			    </li>
			    <li><h:message for="repwd" errorClass="error" /></li>
			    <li id="repwdErr" class="hidden">
				<span class="error"><h:outputText value="#{msgs.reenterPasswordReq}"/></span>						
			    </li>
			</ul>				    
		    </div>				    
		</li>
		<li>
		    <h:outputLabel value="#{msgs.emailAddr}" for="email">
			<span class="redText">*</span>
		    </h:outputLabel>
		    <div class="innerList">
			<ul>
			    <li>
				<h:inputText 
				    id="email" value="#{userBean.currentUser.userDetails.emailId}" maxlength="40"
				    requiredMessage="#{msgs.emailAddrReq}" required="true">
				    <f:validateLength maximum="40"/>
				</h:inputText>
			    </li>
			    <li><h:message for="email" errorClass="error" /></li>
			    <li id="emailErr" class="hidden">
				<span class="error"><h:outputText value="#{msgs.emailAddrReq}"/></span>						
			    </li>
			</ul>
		    </div>				    					
		</li>				
	    </ul>
		<div class="spacerDiv"></div>
	    <ul class="hor_li">
			<li><a4j:commandButton id="profUpdate" value="#{msgs['btn.update']}" 
				action="#{userBean.updateProfile}"/></li>
			<li><a4j:commandButton id="profCancel" value="#{msgs['btn.cancel']}" 
				oncomplete="#{rich:component('editPanel')}.hide();"/></li>
		</ul>
	</fieldset>
</a4j:outputPanel>						
</div>
</h:form>

The profile form has two a4j:commandButton elements. One for submitting the form data and the other for closing the modal dialog. The form submission is through ajax and any validation errors are shown after the server responds to the ajax call.

Advertisements

Written by anonir

February 13, 2010 at 14:57

Posted in JEE, Web

Tagged with , ,