Wednesday, July 2, 2014

Visualforce and jQuery BlockUI : How to block the UI when ajaxing

Introduction


Any website or application that processes requests and data asynchronously and doesn't take precaution to prevent users from interacting with data when it is being processed and updated can lead to a lot of issues, some prominent ones being data inconsistencies and crappy user experience. In Visualforce you can use the actionStatus tag to display the status of an AJAX (Asynchronous JAvascript & Xml) request which can either be in progress or complete. A bit of googling will show you a handful of other techniques which are definitely more complex than using the actionStatus tag or an alternative that I am about to show you in this post.
This alternative is a jQuery plugin called BlockUI. It offers so many different possibilities and it is so simple to use that my mouth literally dropped with disbelief when i first used it.

Use case


Can be used when making AJAX calls to the server. A typically AJAX call to the server will use the actionFunction tag to update a record, and then perform a partial page refresh using the id of a section on the page specified in the rerender attribute of the actionFunction tag.

Your end result could look something like this:


Visualforce


First you need to download jQuery BlockUI and add it to your static resource. Then reference it on the page as follows;

  <apex:includeScript value="{!URLFOR($Resource.tutorials, '/js/jquery.blockUI.js')}" />  

If you would like to use other resources like a gif image for the spinning wheel, then also put this in the static resource. In this examply we will use a gif spinning wheel when blocking the UI. See the documentation and examples for the different possibilities you have with BlockUI.

You can then define two functions to block and unblock the UI respectively


 function showBlockUI(){  
      $.blockUI({ message: '<img src="{!URLFOR($Resource.tutorials, 'img/loading.gif')}"/><span>Please wait...</span>' });  
 }  
 function hideBlockUI() {  
      $.unblockUI();  
 }   


And that is it.

How to use


Whenever you make an AJAX call you can called the showBlockUI() function to block the user interface.


 <apex:column headerValue="Opportunities">  
      <span class="opportunityLink" onclick="showBlockUI(); fetchOpportunities('{!account.Id}', '{!account.Name}');" >opportunities</span>  
 </apex:column>  


And when ever the call to the server returns, is called to unblock the user interface


 <apex:actionFunction name="fetchOpportunities" action="{!fetchOpportunities}" oncomplete="hideBlockUI(); showOpportunityDialog('{!selectedAccountName}', '{!jsonDataOpportunitiesByAccount}')" >  
      <apex:param name="selectedAccount" assignTo="{!selectedAccountId}" value="" />  
      <apex:param name="selectedAccountName" assignTo="{!selectedAccountName}" value="" />  
 </apex:actionFunction>  


Look at the oncomplete attribute of the actionFunction tag.

Conclusion


As I said, super easy.

No comments:

Post a Comment