Geek Lair

Archive for the ‘JEE’ Category

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.

Written by anonir

February 13, 2010 at 14:57

Posted in JEE, Web

Tagged with , ,

Zebra striping tables with JSTL and CSS

with 6 comments

Zebra striping is giving adjacent rows in a table different colors and alternate rows the same color:

Zebra Striped Table

Zebra Striped Table

One way to do it is using JavaScript and CSS. There are a lot of articles describing how to do so. This method has one disadvantage – if the user disables JavaScript in the browser, the table will not be striped. The only way is to hard code the style for each row. This is easily done using JSTL.

If we have a list of objects of type Person, then we can iterate over them using the JSTL <c:forEach> action and render a row for each item. Even and odd rows can be determined from the loop counter:

<table>
    <thead>
	<tr>
	    <td>Sno</td>
	    <td>First Name</td>
	    <td>Last Name</td>
	    <td>Age</td>
	    <td>Gender</td>
	</tr>
    </thead>

    <tbody>
	<c:forEach var="person" items="${persons}" varStatus="i">
	    <c:choose>
		<c:when test="${(i.count) % 2 == 0}">
		    <tr class="even">
		</c:when>
		<c:otherwise>
		    <tr class="odd">
		    </c:otherwise>
		</c:choose>
		<td>${i.count}</td>
		<td>${person.firstName}</td>
		<td>${person.lastName}</td>
		<td>${person.age}</td>
		<td>${person.gender}</td>
	    </tr>
	</c:forEach>
    </tbody>
</table>

 
Even rows will have the style “even” and odd rows “odd”. Here are the CSS styles I used:

<style type="text/css">
    table {
	border-collapse: collapse;
	text-align: center;
    }
    td {
	border: 1px solid #000;
    }
    thead {
	background-color: #000;
	color: #fff;
	font-weight: bold;
    }
    thead td {
	padding: 0 .5em;
    }
    .odd {
	background-color: #E6E6E6;
    }
    .even {
	background-color: #fff;
    }
</style>

Written by anonir

December 16, 2008 at 20:07

Posted in JEE, Web

Tagged with ,