Tag Archives: jsf

How to use JSF 2.0 as an Action-Based-Framework

JSF is a common used and widely spread Web-Framework with a lot of powerful features and a great community. But JSF also follows a concept which is not comparable to Action-Based or Request-Based Frameworks like MVC 1.0 or Spring MVC. The concept behind JSF is a so called Event- or Component-Based Framework (alternative therm is MVC-Pull). This approach gives you a lot of flexibility in developing web applications, but it also includes some problems. What you often see in JSF  applications is, that URLs are not bookmarkable and you can not use the browsers History-Back button. This makes the behavior of JSF a little bit clumsy to the end-users.  I will explain  in this post how to solve this ‘problem’ in an elegant way without abusing JSF.

The Problem

The problem with the non bookmarkable URLs and the ugly situation that we can not use the Browser History-Back Button in a JSF application is founded in the so called Postback mechanism.  Each time you use a JSF Command-Action like a <h:commandButton> or a <h:commandLink>, JSF generates a Form Post, computes the resulting web site internally and posts back the markup to the browser. This is the natural behavior of the HTTP POST method and very efficient because the browser is not forced to load a new page. But if you want to change the page content/url the user is faced with a usability problem. The following two pages illustrating the problem:

page1.xhtml:

...
<h:body>
 <h:form>
 <h1>Page1</h1>
 <h:commandLink action="/page2">Go to Page2</h:commandLink>
 </h:form>
</h:body>

page2.xhtml:

...
<h:body>
 <h:form>
 <h1>Page2</h1>
 <h:commandLink action="/page1">Go to Page1</h:commandLink>
 </h:form>
</h:body>

If you test this page example you will see that the browser URL did not correspond with the page you see. Command-Actions are very powerful and we need them in situations where we want to submit the user input. But for simple navigation there is another tag introduced in JSF 2.0 which should be used instead of a command action. The <h:link> and <h:button>. In the next example you can see how the two pages work when we use this new JSF component:

page1.xhtml:

...
<h:body>
 <h1>Page1</h1>
 <h:link outcome="/page2">Link to Page2</h:link>
</h:body>

page2.xhtml:

...
<h:body>
 <h1>Page2</h1>
 <h:link outcome="/page1">Link to Page1</h:link>
</h:body>

Now when the user clicks on one of the page links the browser url is updated correctly because a HTTP GET request is initiated. This is the correct way to implement a page navigation in JSF.

Rule No. 1: Never use a command-action to navigate between pages

 

The Action Controller

In most situations it is not sufficient to simply navigate between to pages. What we need is business logic to be called when the user clicks on the navigation link to open a new page. Command Actions providing a lot of functionality to solve this problem. And this is also the reason why command actions are often used in JSF.  To control the outcome of a page after the user clicks on a action link is called an Action Controller. A Action Controller is in most cases a request-scoped CDI bean. So what we can do here is to bind the outcome attribute of the <h:link> component to a CDI Bean method like seen in the following example:

page1.xhtml:

...
<h:body>
 <h1>Page1</h1>
 <h:link outcome="#{myActionController.action1()">Link to Page2</h:link>
</h:body>

MyActionController.java:

@Named
@RequestScoped
public class MyActionController implements Serializable {
 private static final long serialVersionUID = 1L;
 public String action1() {
 // your code goes here.....
 return "/page2";
 }
}

The ugly part of this solution is that the action controller have to know the page name. So the action controller is tightly coupled to our JSF pages. (By the way, we see exactly the same coupling in MVC 1.0 examples.) In addition in this solution we need to make sure hat every link navigating to page2 is calling our action method. But a more complicating problem is that the action controller is not called if the user opens the page2 form a bookmarked URL!

So lets look on a better solution: We can place the ActionController directly into the page view. This  can be done by the new JSF 2.0 component <f:event> inside a the JSF component <h:view>. With the f:event type we can specify the jsf life-cycle phase where the action controller should be called.  See the next example:

page1.xhtml:

...
<h:body>
 <f:view>
  <f:event type="preRenderView" listener="#{myActionController.init()}" />
   <h1>Page1</h1>
   <h:link outcome="/page2">Link to Page2</h:link>
 </f:view>
</h:body>

MyActionController.java:

@Named
@RequestScoped
public class MyActionController implements Serializable {
 private static final long serialVersionUID = 1L;
 public void init() {
 System.out.println("...initializing action controller....");
 }
}

This solution ensures that your ActionController is always called before the page is rendered.

Rule No. 2: Avoid binding controller methods to a navigation link

If you do some tests with the ActionController example you will notice that the init() method of the ActionController is not called if the user clicks the Browser History-Back Button to enter the page. This again is not a problem of JSF but of the caching behavior of Web Browsers. See a good blog post about this topic here.

The JSF Command-Action and Postbacks

Now lets take a look on the JSF command action. As I mentioned earlier the JSF command actions are useful if you want to submit the users input from a input form.

<h:form>
 <h1>Form1</h1>
 <h:inputText value="#{myActionController.orderDate}" >
    <f:convertDateTime pattern="dd.MM.yyyy" timeZone="CET"/>
 </h:inputText>
 <h:commandButton action="#{myActionController.submitOrder}" value="submit"/>
 </h:form>

In this example the submit action button triggers our action controller method ‘submitOrder()’. Thus a method typically implements our business logic to persist or update data. JSF exepcts a public method returning a String which points to the resulting page outcome. See the following example:

 public String submitOrder() {
   // your code goes here....
   return "/page2";
 }

If you do some tests, you will see that a click on the submit button will produce a HTTP POST method call and the page content will result in the markup of page2. As this was a postback the browser URL has not updated. Another problem seen here is that we now have again the situation where our Action Controller have to now the page name.

To avoid this problems simple make use of another JSF command action attribute called ‘actionListener’. With EL 2.2 we can call any method of a CDI bean with or without parameter. The action attribute itself can now be used for the navigation part. In case we want to navigate to another page we still have the Postback problem. But JSF 2.0 allows to force a redirect by adding the query parameter ‘?faces-redirect=true’ at the end of the navigation path.

<h:commandButton actionListener="#{myActionController.submitOrderByListener()}"
 action="page2?faces-redirect=true" value="submit"/>

ActionListener method:

 public void submitOrderByListener() {
   // your code goes here....
   System.out.println("ActionListener called...");
 }

The result of the faces-redirect=true is also known as the Postback/Redirect/Get (PRG) pattern. The browser will receive a HTTP result 302 with the new URL to be redirected to.

Rule No. 3: Use faces-redirect=true to force Posteback/Redirect/Get pattern

Conclusion

As you can see, JSF 2.0 is a powerful framework which can be used also to implement web application with a request-based behavior as it is typically for modern web applications. Take care of the following rules:

Rule No. 1: Never use a command-action to navigate between pages
Rule No. 2: Avoid binding controller methods to a navigation link
Rule No. 3: Use faces-redirect=true to force Posteback/Redirect/Get pattern

I hope this blog post will help someone to get out the most of JSF. If you have any ideas or questions post your comments.

JSF and Transactioncontext

Today I want to talk about a detail in the JSF Framework, which is on the first view not obviously. In different to Spring, business logic placed in a JSF front-end controller (JSF Backing Beans) did not initializes a separate transaction context. Normally business logic which need to be transaction save should be spread out into EJBs. EJBs are the recommended place for business logic. So in JSF/EJB business logic should be put into stateless session EJBs and controlled the page flow of a web application through the so called front end controllers  – JSF Backing beans. As I mentioned before spring starts a transaction context also in front-end controllers, but jsf does not.

So what is the problem here? When you look at the following JSF example, you maybe will not recognize the problem at first:

//jsf bean...
@EJB ejb1;
...
public String process(businessobject) {
 ejb1.op1(businessobject);
 ejb1.op2(businessobject);
 ....
}

The JSF front-end controller method ‘process(businessobject)’ injects an EJB and calls two ejb methods. This will propaply work without any side effects. But it can produce errors in some cases. The problem in this pattern is that the front-end controller performed two apparently dependent business actions completely separately. If these two methods need to be transaction save but are operating on the same database entities this can result in serious problems. In a high concurrent system indeed this pattern can cause a corrupted DB state even if you thought JPA will solve all the transaction stuff for you.

The reason for the unexpected behavior is the missing wrapping transaction. Each ejb method starts it own transaction with all the transaction control provided by the ejb container. But the hole business method is not transaction save.

To solve this you have two possible solutions:

1) add a UserTranaction context to the front-end controller:

//jsf bean...
@Resource UserTransaction tx;
@EJB ejb1;
...
public String process(businessobject) {
 try {
   tx.begin();
   ejb1.op1(businessobject);
   ejb1.op2(businessobject);
 finaly {
   tx.commit();
 }....
}

In this example now the jsf controller starts itself the UserTransaction. As a result both EJB methods (with default transaction mode ‘mandatory’) run in the same transaction context. Even operations on the database in a high concurrent system will be transaction save.

2) Merge the EJB Methods into one transaction save business method

The second solution merges both ejb methods into a single EJB method call:

// JSF bean calls new ejb method...
public String process(Entity entity) {
 ejb1.op1op2(entity);
 // ...
}

with the following ejb implementation:

// EJB
public void op1op2(Entity entity) {
 op1(entity);
 op2(entity);
}

Now the new ejb method is transaction save an there is no need to fiddle with UserTransaction in the jsf fornt-end controller.

The second solution is recommended because there is no more risk that the transaction context is split by the front-end. And you can reuse the new ejb method easily with now need to think about the transaction context scenarios.

Maybe this will help you solving some problems with jsf transaction context in the future.

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.

Using @multipartconfig in a servlet running on GlassFish 3.2.2

Today I run into a problem with a custom JSF component using the @MultipartConfig. Trying to use my FileUpload Bean (http://www.imixs.org/jsf/fileupload.html) results in the following error message:

[#|2013-04-26T15:37:21.769+0200|WARNING|glassfish3.1.2|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=20;_ThreadName=Thread-2;|StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
java.lang.IllegalStateException: PWC4016: Request.getParts is called without multipart configuration.  Either add a @MultipartConfig to the servlet, or a multipart-config element to web.xml

It seems that this error did not be thrown on a GlassFish 3.2.1 server.

Finally I was able to fix the problem when adding the following servlet configuration into the web.xml file for my Faces Servlet.

 ...
	<!-- Facelets -->
	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>0</load-on-startup>		
		<multipart-config>
	    	  <location>/tmp</location>
	    	  <max-file-size>20848820</max-file-size>
	    	  <max-request-size>418018841</max-request-size>
	    	  <file-size-threshold>1048576</file-size-threshold>
		</multipart-config>
        </servlet>
.....

 

 

jQuery Dialog – how to submit a form with ajax

Today I searched for a solution to submit a form embedded into a jQuery dialog with ajax.

My situation is the following: I use a jQuery UI Dialog to display a feedback-form in my web application. The feedback form should not change the state of the page the user worked before.

So my first approach was to change my form post action into a ajax post action. This can be done easily during the initialisation of the dialog. See the following code snippet:

/**
 * Method to initialize the feedback dalog.
 * @see contact_dialog.xhtml
 */
function initContactDialog() {
    // set default settings for profile dialog
    $("#dialog-contact").dialog({
        resizable : false,
        height : 530,
        width : 550,
        modal : true,
        autoOpen : false
    });

    // hide contact dialog per default
    $("#dialog-contact").hide();

    // the following method modifies the submit request into a ajax request
    // So the dialog will be closed after the submit was successfull without
    // affects to the main page.
    $('#dialog-contact-form').submit(function() {

        // show up waiting panel
        $(".ajax-wait-panel").addClass("ajax-waiting"); 

        $.ajax({
               type: "POST",
               url: "http://localhost:8080/myrestservice",
               data: $("#dialog-contact-form").serialize(), // serializes the form's elements.
               success: function(data)
               {
                   $(".ajax-wait-panel").removeClass("ajax-waiting"); 
                   $("#dialog-contact").dialog("close");
               },
               error: function(data)
               {
                   alert('An error occured. Could not send data!'); // show response from post.
                   $(".ajax-wait-panel").removeClass("ajax-waiting"); 
               }
             });

        return false; // avoid to execute the actual submit of the form.
    });

}

With the initContactDialog() method I initialize the dialog and bind a function to the submit event of my form. The function changes the submit into a ajax call and closes the dialog after the ajax request was finished.

This is quite easy and the dialog will automatically close when the Ajax submit was finished.

Here is the html part of my dialog form:

    <!-- Dialog Box -->
        <div id="dialog-contact"  title="#{global.contact_title}">
            <form id="dialog-contact-form" method="post" name="contact_form">

                <h:panelGrid columns="2">

                    <h:panelGroup>
                        <dl>
                            <dt>#{global.contact_firstname}:</dt>
                            <dd>
                                <input type="text" name="txtfirstname" value="" />
                            </dd>
                        </dl>
                    </h:panelGroup>
                    <h:panelGroup>
                        <dl style="">
                            <dt>#{global.contact_lastname}:</dt>
                            <dd>
                                <input type="text" name="txtlastname" value="" />
                            </dd>
                        </dl>
                    </h:panelGroup>
                    <h:panelGroup>
                        <dl style="">
                            <dt>#{global.contact_email}:</dt>
                            <dd>
                                <input type="text" name="txtemail" value="" />
                            </dd>
                        </dl>
                    </h:panelGroup>
                </h:panelGrid>
                <dl style="margin: 0 0 0 0px;">
                    <dt>#{global.contact_message}:</dt>
                    <dd>
                        <textarea style="width: 450px; height: 80px;" name="_description" />
                    </dd>
                </dl>
                <input type="submit" value="send" />

            </form>
            <div>
                <h2>#{global.please_wait}</h2>
            </div>
        </div>

I open the dialog with the following JavaScript function:

 /**
 * helper method to open the contact dialog. 
 * The method creates a new empty contact workitem.
 */
function openContact() {    
   $("#dialog-contact").show();
   $("#dialog-contact").dialog("open");
}

AJAX ‘WAIT-PANEL’

As you can see in my script and in the html snippet I have added a div section with the class ‘ajax-wait-panel’. This div overlays the form of my dialog when the ajax call is started. So the user will see a ‘Please wait’ message until the ajax request is finished. I simply add the class ‘ajax-waiting’ to the div section in the moment the request starts and remove the class when the submit was finished. So this is the css part of my solution:

/* Ajax-wait-panel can be useded in jquery dialogs
   for long runnign ajax request.
   Start by setting display:none to make this hidden.
   Background we set to 80% white with
   our animation centered, and no-repeating */
 .ajax-wait-panel {
    display:    none;
    position:   absolute;
    z-index:    1000;
    top:        0;
    left:       0;
    height:     100%;
    width:      100%;
    background: rgba( 255, 255, 255, .6 ) 
                url('ajax-loader.gif') 
                50% 50% 
                no-repeat;
    cursor: wait;
}

.ajax-wait-panel  h2 {
    position: absolute;
    top: 50%;
    margin-top: -80px;
    color: #666;
    text-align: center;
    width: 100%;
}
/* Class to be added when ajax wait panel should 
   be displayed */
.ajax-waiting {
     display: block;
}

JSF f:ajax – How to locate componets outside the current context

Using JSF 2.0 and Ajax simplifies the web design and provides a lot of cool tricks to extend the user experience. With the render and execute tags form the f:ajax tag it is use to update components dynamically.

But in the past I run often into problems when trying to update a component outside the current ui context. For example when you try to update a part of your form for a single row in h:datatable component you will typically see log messages like this one:

f:ajax contains an unknown id 'j_idt90:painelTabela' - cannot locate it in the context of the component j_idt75

To solve such kind of problems you need to specify the full component id to be rendered or executed. This is not always as easy at it sounds. When your component is nested in a complex component tree the component id can be prafixed with a long list of parent component ids. This happens typically in h:datatables, ui:repeats or c:forEach sections.

One solution is to navigate back in the tree to the correct ui node and get the componentID using an EL syntax like this:

<f:ajax render=":#{component.parent.parent.parent.parent.clientId}:new-minute-panel:" />

This looks not really nice and it creates new problems when you redesign or move your ui components into a new structure on your jsf page.

A simple trick to solve the problem is to bind the component which need to be rendered into a ui param. So you can reference its full clientId in the ajax context. See the following example:

<h:panelGroup layout="block" id="mylist" binding="#{myListComponent}">                
   <ui:repeat var="attachment" value="#{myController.myList}">
       ....
       <!-- some ajax functionality... -->
       <f:ajax render=":#{myListComponent.clientId}">
           <h:commandLink actionListener="#{myController.soSomething}">click me</h:commandLink>
       </f:ajax>
 ...
   </ui:repeat>
....

In this example I use the binding tag to bind the panelGroup to a param named ‘myListComponent’. Inside the ui:repeat I can now access the outer component and render the component fom my f:ajax element accessing the clientId

<f:ajax render=":#{myListComponent.clientId}"

As a result the ajax component no longer depends on the position in my page and I can reuse it in any part of my jsf page.

TRANSFER CLIENTIDS TO SUBFORMS

Another solution using the binding is to transfer a component into a subform. See the following example:

 <h:panelGroup id="my_panel" binding="#{myListComponent}">
     <h:dataTable id="mydatatable" value="#{myController.myList}" var="child">
       .....
        <ui:include src="/forms/sub_myeditor.xhtml" >
            <ui:param name="myPanel" value="#{myListComponent}" />            
        </ui:include>
       .....
     </h:dataTable>

In this example I transfer the ui:component containing my h:datatable to a subpage ‘sub_myeditor.xhtml’  which is included inside the table. Now I can access the panelGroup inside my subpage and render it after an ajax event:

<h:commandButton ....  >
       <f:ajax render=":#{myListComponent.clientId}" 
                execute=":#{myListComponent.clientId}"/>
</h:commandButton>

Also in this example the component in the ajax tag is addressed with its absolute path.

JSF 2.0 – ajax suggestion box

Since JSF 2.0 has introduced the ajax support it is quite simple to implement functional widgets like a suggestion input box. The following short tutorial shows how to build your own suggestion widget using JSF 2.0 and it’s ajax capabilities.

1. THE HTML FORM

First you need a simple input field where the user can type in a search phrase. This can be done wit the h:inputText element. After the user typed in some character a suggestion widget should start a backend search and provide the user with a list of suggestions (you can see this behaviour when searching for something on google.com). To connect your inputText element with a backend component you can use the new build-in ajax feature provided by JSF 2.0. So your input element looks something like this:

<h:panelGroup layout="block" style="margin-bottom:5px;">
     <h:inputText value="#{suggestController.input}">
        <f:ajax event="keyup"  render="suggest_box" /> 
     </h:inputText>
</h:panelGroup>

 

2. DEFINE THE SUGGEST BOX

With the ‘render’ attribute of the f:ajax tag you specify which part of your page should be rerendered after the ajax event was fired. In this case an element with the ID ‘suggest_box’ will be updated. This is the part where you can display the results of your backend search:

<h:panelGroup id="suggest_box">
	<ul>
		<ui:repeat var="entry" value="#{suggestController.result}">
			<li>#{entry}</li>
		</ui:repeat>
	</ul>
</h:panelGroup>

 

To bind you backend component (suggestController) to the event just use the listener tag:

 <f:ajax event="keyup" render="suggest_box"
	listener="#{suggestController.search}" >
</f:ajax>

Your suggest controller implementation can look like this:

....
public void search(AjaxBehaviorEvent event) {
	....
	result=new ArrayList<String>();
	....
}

public List<String> getResult() {
	return result;
}

If you are working with EL 2.2 support (GlassFish 3.1) you can also pass params as method arguments:

<f:ajax event="keyup" render="suggest_box"
	listener="#{suggestController.search('abc')}" >
</f:ajax>
public void search(String param) {
       ..
}

 

3) LAYOUT

Now you can do some layout stuff. Typically the suggestion box should only be displayed with a user typed in a search phrase. And the suggestion box should hidden if the focus is lost. This can be done with some css definition:

.suggestbox {
	position: relative;
}

.suggestbox .resultlist {
	display: block;
	position: absolute;
	z-index: 1;
	left: 2px;
	top: 22px;
	border: 1px solid #CCC;
	background-color: #EEE;
}

To hide the resultlist you can use the f:ajax event ‘blur’

 <f:ajax event="blur" render="suggest_box"
                    listener="#{suggestController.reset}" />

The listener is bound to a backend method which resets the result list. So you can display the complete box in order of the current result. This is the complete code:

JSF Code:

<h:panelGroup layout="block">
	<!-- Process references -->
	<h:panelGroup layout="block" style="margin-bottom:5px;">
		<h:inputText value="#{suggestController.input}">
			<f:ajax event="keyup" render="suggest_box"
				listener="#{suggestController.search('')}" />
			<f:ajax event="blur" render="suggest_box"
				listener="#{suggestController.reset}" />
		</h:inputText>
	</h:panelGroup>
	<h:panelGroup id="suggest_box">
		<h:panelGroup id="suggest_resultlist"
			rendered="#{! empty suggestController.result}">
			<ul>
				<ui:repeat var="entry" value="#{suggestController.result}">
					<li>#{entry}</li>
				</ui:repeat>
			</ul>
		</h:panelGroup>
	</h:panelGroup>
</h:panelGroup>

 SuggestController:

@Named("suggestController")
@RequestScoped
public class SuggestController implements Serializable {

	private static final long serialVersionUID = 1L;
	private List<String> result=null;
	private String query = null;
	private String input =null;
	
	public SuggestController() {
		super();
		result = new ArrayList<String>();
	}

	public String getQuery() {
		return query;
	}

	public void setQuery(String query) {
		this.query = query;
	}

	public String getInput() {
		return input;
	}

	public void setInput(String input) {
		this.input = input;
	}
	
	public void reset(AjaxBehaviorEvent event) {
		 result=new ArrayList<String>();
	}
	
	public void search(String query) {
    	result=new ArrayList<String>();
		result.add("Hallo "  + System.currentTimeMillis());
		result.add("World "+ + System.currentTimeMillis());

	}
	
	public List<String> getResult() {
		return result;
	}

}

4) DELAY AJAX EVENTS

Maybe you run into a problem with the onblur ajax call to hide your overlay section. If the section contains h:command links or buttons the action and actionListeners will not be called because the ajax blur event hides the overlay to early.

With a trick from BalusC you can delay the blur event a little bit. So just add the following jQuery code into your page:

$(document).ready(function() {
	$(".suggestinput").each(function(index, input) {
	    var onblur = input.onblur;
	    input.onblur = null;
	
	    $(input).on("blur", function(event) {
	        delay(function() { onblur.call(input, event); }, 300);
	    });
	    // turn autocomplete of
	    $(this).attr('autocomplete','off');
	});

});

var delay = (function() {
    var timer = 0;

    return function(callback, timeout) {
        clearTimeout(timer);
        timer = setTimeout(callback, timeout);
    };
})();

 

JSF 2.0 – The action event model

If you are working with JSF 2.0 there are different ways to interact with backend methods and passing params to action methods. A useful link for this topic can also seen here.

So for example if you have a JSF page with the following command link you use different ways to bound your backing bean:

<h:commandLink action="#{workflowController.editAction(workitem)}"
               actionListener="#{workflowController.doEdit}">
         <h:outputText value="click me" />
         <f:setPropertyActionListener
               target="#{workflowController.workitem}" value="#{workitem}" />
</h:commandLink>

The important thing here is the order which the jsf framework will trigger the differnt methods of the backingBean ‘worklfowController’

  1. The actionListener method will be called
  2. The setPropertyActionListener will trigger the setter method of the property ‘workitem’
  3. The action method with a custom param will be called

So in this case you backingBean can look something like this – note that there are two different ways to pass a param:

 

   // first the actionListener method will be called   
   public void doEdit(ActionEvent event) throws Exception {
        // do something...
       .....
    }

   // next the setter for the property will be called
   public void setWorkitem(Data aworkitem) {
        // do something    
   }

   // last the action method will be called
   public String editAction(String action) {
        // do something
        return action;      
    }