How to use a jquery dialog in jsf 2.0

Combining JSF 2.0 and jQuery / jQuery-UI is in my opinion the best choice to build modern web applications. Your JSF web application becomes much smaller as using one of the JSF component libraries. Also with jQuery you got a lot of flexibility designing your pages.

But things become interesting when you try to integrate a jQuery Dialog box with JSF 2.0. I am talking here about a Dialog Box which contains a JSF form with input elements to be submitted – independent from the current page flow. For example: you have a normal jsf form with input components and a link to open another form (in my case a user-profile dialog) also with data which can be submitted. It takes me some time to figure out the best way to manage this. But with JSF 2.0 and ajax support things are not so difficult.

So here is my Solution:

THE DIALOG FORM

I put my Dialog into a JSF faclet to separate all the dialog stuff in one xhtml element which can be included in the main pages. The interesting thing is here the JSF validation which is also supported. The dialog will not close if a validation error occurs. There for I check the #{facesContext.validationFailed} and save the state in a JavaScript variable. The ajax method ‘processCompleteEvent’ checks if a validation exception was thrown. In that case the dialog stays open, otherwise it will be closed after submit. The command button triggers a JSF 2.0 ajax request to avoid any changes on the main page behind the dialog.

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

	<script type="text/javascript">
		/*<![CDATA[*/
		$(document).ready(function() {
			// setup dialog
			$("#dialog-myprofile").dialog({
				resizable : false,
				width : 530,
				modal : true,
				autoOpen : false
			});
		});

		// auto close dialog and check validation... 
		var validationError=false;
		function processCompleteEvent(e) {
	          if (e.status == 'success') {
	        	if (!validationError) {
	        	 	$("#dialog-myprofile").dialog("close");
	       	 	}
	          }
	        }
		// open dialog
	 	function openMyProfile() {
			$("#dialog-myprofile").show();
			$("#dialog-myprofile").dialog("open");			
	    	}
		/*]]>*/
	</script>

	<div id="myprofile_view">
		<!-- Dialog Box -->
		<div id="dialog-myprofile" title="#{message['profile.title']}">
			<h:form id="dialog-myprofile-form">
				<ui:include src="/pages/error_message.xhtml" />
				<script>validationError=#{facesContext.validationFailed};</script>
				<h:inputText
					value="#{userController.workitem.item['txtusername']}"
					style="width: 260px;" />

				<!-- Save Action -->
				<h:commandButton actionListener="#{userController.doProcess}"
					 value="#{message.save}">					
					<f:ajax execute="@form" render="@form"
						onevent="processCompleteEvent">
					</f:ajax>
				</h:commandButton>
				<input type="button"
					onclick="$('#dialog-myprofile').dialog('close');"
					value="#{message.close}" />
			</h:form>
		</div>
	</div>
</ui:composition>

 

HOW TO OPEN THE DIALOG FROM THE MAIN PAGE

To open the Dialog from my main template I use a h:commandLink with an onclick event to open the jQuery dialog. See the following code snippet:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:c="http://java.sun.com/jsp/jstl/core"
	xmlns:f="http://java.sun.com/jsf/core"
<h:head>
.....
	<script type="text/javascript" src="../jquery-ui-1.10.0.custom.min.js"></script>
	<script type="text/javascript" src="../jquery-1.9.0.js"></script>
.....
</h:head>
<h:body>
   <f:view id="main_view">
.....
	<h:form id="main_form">
...
		<h:commandLink onclick="openMyProfile();">
			<h:outputText id="profile_userlink"
				value="#{message.open_profile}" />
			<f:ajax render=":dialog-myprofile-form" />
		</h:commandLink> 
	</h:form>
...
	<ui:include src="/pages/profile/myprofile_dialog.xhtml" />
   </f:view>
</h:body>
</html>

The trick here is again the ajax integration of the commandLink.

<f:ajax render=":dialog-myprofile-form" />

The f:ajax tag will rerender the dialog form. This is an important part of this solution, because you need to reset the old data of the dialog when the dialog is reopened. For example when the user opens the dialog, types in some data and close the dialog without submitting the data. In this scenario it is necessary to reload the dialog form data. This is done by the ajax render command.

So that’s it. I hope this will help someone.

Leave a Reply

Your email address will not be published. Required fields are marked *