Thursday, February 20, 2014

Display Busy Mouse Cursor with PrimeFaces during Ajax Requests

Today, I want to share a solution for displaying a busy cursor while an Ajax request is active in a PrimeFaces application. The solution is strikingly simple once all the pieces click in, but it took me some good amount of research and try and error, so I decided it is worthwhile to post it here.

The journey starts with a simple CSS which defines the busy cursor:

 // <web-app-root>/resources/css/progress.css
 html.progress, html.progress * {  
  cursor: progress !important;  
 }  

The above is based on this forum post - you may want to check it out for more details or if you wish to use the original solution. The solution I went for is slightly different - it uses JavaScript with the following self-explanatory functions:

 // <web-app-root>/resources/js/progress.js
 var handle = {}  
   
 function on_start() {  
     handle = setTimeout(function() {  
         $('html').addClass('progress')  
     }, 250)  
 }  
   
 function on_complete() {  
     clearTimeout(handle)  
     $('html').removeClass('progress')  
 }  

Note that the progress class is not set immediately when the request starts. I found it very distracting when the cursor "flashes" on short Ajax requests and I decided to change the cursor after a delay of 250 ms only. Of course, you may modify the delay as you see fit (or maybe make it an argument of the on_start function). The clearTimeout call is needed to cancel the delayed cursor change when the Ajax request is completed before the delay expires.

Now to activate the solution you only need to include the following in your JSF page:

 <h:outputStylesheet library="css" name="progress.css" />  
 <h:outputScript name="js/progress.js" target="head"/>  
 <p:ajaxStatus onstart="on_start()" oncomplete="on_complete()"/>  

Final note: for the above inclusion to work you must also have an <h:head/> tag on your JSF page.

No comments:

Post a Comment