Geek Lair

Archive for the ‘Web’ 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.

Advertisements

Written by anonir

February 13, 2010 at 14:57

Posted in JEE, Web

Tagged with , ,

Productive Firefox

leave a comment »

Firefox has redefined the web experience. It dragged the web out from the clutches of the mundane and boring IE6. Apart from the features which are immediately obvious, Firefox has hidden treasures which can further improve the browsing experience

Ctrl + K

I’ve seen people who wanted to do a Google search open a new tab, type in google.com in the address bar and then enter their search term or drag their mouse pointer all the way the search box next to the address bar. There is a much faster way to accomplish the same. Just open a new tab (Ctrl + T), then press Ctrl + K and you are in the search bar!

Bonus tip: Press Ctrl + Down/Up arrow to switch between different search engines.

I’m Feeling Lucky

Google search has this feature where it will show the most popular website for a given search expression. Using Firefox you can do it right from your address bar. Say you remember a popular website for lolcats but cannot remember its address. You can type in lol cat in the address bar and voila! Firefox shows you the page that started the silly phenomenon:

Screenshot-Shiretoko

lol cat

Of course you could as well load google.com and do a search there. But that is too way too slow compared to:  go to the address bar (Ctrl + L), and just type in the search term. Time is precious. We can’t waste it can we? But a caveat here. This works fast only for search terms which involve at least two words. If you type in a single word, Firefox will attempt to do a DNS lookup for it and when there is no match for that word, only then will Firefox route the word to Google’s I’m Feeling Lucky search.

My preciouss mouse!

Here’s something for you mouse lovers. To open a link in a new background tab, you can hover over it and press the middle click of your mouse (now a days that is mostly the scroll wheel ). This way is faster than doing a right click on the link and selecting “Open Link in New Tab” option. Another way to accomplish the same is to hold the Ctrl key and do a left click with the mouse.

Skating through tabs

To cycle through tabs from left to right use Ctrl+Tab. To do it in the opposite direction, use Ctrl+Shift+Tab. To switch to the tab right of the current tab use Ctrl+Page Down and for the tab to the left, use Ctrl+Page Up.

A cleaner web

Ever since the web came out of a “fancy geek fad” status to a “essential communication medium”, website owners smelled money. A lot of it. As result we see web pages are ad soups with a bit of content thrown in and in some cases even the teeny bit of content is spread across multiple pages. Not only do ads add clutter to a web page, they also waste bandwidth. Enter Adblock Plus, an add on which blocks ads. Install it and enjoy a better web.

Written by anonir

September 10, 2009 at 13:21

Posted in 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 ,