Showing posts with label Wait Screen. Show all posts
Showing posts with label Wait Screen. Show all posts

Tuesday, December 3, 2013


Well I have been working on VF pages for a long time now and I use a lot of AJAX / Rerender. Generally user has to wait for a AJAX action to complete to get results. So how to show the user something is working in background ? a wait screen ?

Yes indeed a wait screen with "Please Wait..." is required. I have already done some demos about the same here Loading/Wait Screen Using Jquery.

But that requires a bit of coding.
  • Add JS functions and ActionStatus
  • You may have to change your existing code to accommodate actionStatus
  • Add the new code and upload everything in static resource
Well to summarize if you need to show a generic message for all the AJAX calls that is talking place from the page you have to make changes to all the Action component to include a action status. So that raises a question can we built a listener that can track a AJAX call. The answer is yes we can build one. VFUIBlock does uses a generic listener to track the AJAX calls. 

Whats special about "VFUIBlock" ?

Its a generic componet that hooks up to all the AJAX calls and listens to them. You just have to install the component and drop the component in a Visualforce Page. It will automatically attaches itself to all the AJAX request originating from the page and will show a wait screen while the request is in Progress. No need to make any changes in your existing code, No need to use any actionstatus, It does it all by itself!

VFUIBlock in Action

How it works ?
In Visualforce AJAX request are sent to server using XMLHttpRequest, So what VFUIBlock does is, it overrides the default XMLHttpRequest and plugs in its own onSend method and OnReadyStateChange method while preserving the old Send and OnReadyStateChange method. Now with this override VFUIBlock adds in its on method with some extra fancy stuff to Show a block screen.

/*THIS IS A JUST A PORTION OF CODE, PLEASE VISIT PROJECT DETAIL FOR FULL SOURCE CODE*/
function addXMLRequestCallback($) {  
   var oldSend, i, oldonreadystatechange;  
   /*hold the old send method*/  
   oldSend = XMLHttpRequest.prototype.send;  
   /*override with a new function*/  
   XMLHttpRequest.prototype.send = function () {  
     /*call the blockui function or any other custom function to show your message*/  
     onStart($);  
     /*call the old send method*/  
     oldSend.apply(this, arguments);  
     /*cache the old onreadystate change method*/  
     oldonreadystatechange = this.onreadystatechange;  
     this.onreadystatechange = function (progress) {  
       oldonreadystatechange(progress);  
       /*call the blockui function or any other custom function to hide the message*/  
       onStop($);  
     };  
   }  
 }  



VFUIBlock uses the good old jQueryUIBlock to create the wait screen. Its a jQuery plugin which is used to create a overlay and to show a message to the user.


Features
  • Lets you customise the HTML that is being displayed to user
  • Automatically attaches itself to AJAX events events originated from CommandButton,CommandLink etc.
  • No coding and changes in existing code required.
  • Works with CommandButton , ActionFunciton, ActionPoller, ActionSupport.
Sample Code / Syntax

Just drop the below code somewhere in your page

<c:VFBlockUI>  
   <img src="/img/loading32.gif" />  
   <div style="font-size:150%;padding:5px">Please Wait....</div>  
</c:VFBlockUI>

You can always customise your message. So anything wrapped inside this VF component is displayed to User. In this example we are displaying a standard "Loading" image a long with a text "Please Wait..."


Wednesday, June 13, 2012


[Update : Added Live Demo Links]

In the first part I already described you how to create your own wait/loading screen by blocking the full page.(In case you have missed the first part, you can quickly catch up by reading this blog )

Well what if you want to block specific part of the page ?? Like a pageblock or certain set of fields?? Well jQuery is again here to rescue! The good part of jQuery is it mixes with visualforce very readily to give out awesome results!

So lets see how to make this work using the good old jQuery UI Block Plugin.


 How to block a certain portion of page?

 For demo let us assume that we want to block a pageblock while a ajax request is in progress. To achieve this just give page block a unique id say "pb2Block" and use the same from the jquery ui block. Pass in the id of the pageblock which you want to block to the function, probably from a <apex:actionStatus> like this

Action Status
<apex:actionStatus onstart="blockElement('pb2Block')" onstop="unblockElement('pb2Block')" id="blockElement"/>

Command Button

<apex:commandButton value="Send Request" action="{!processAjaxRequest}" reRender="pb" status="blockElement"/>  

so whenever a ajax request is invoked by a command button the onstart event of the actionStatus is fired which blocks the the pageblock with id "pb2Block" and when the ajax request ends the ontstop event is fired which unblocks the pageblock.


 The JavaScript Functions : The demo visualforce page includes two Javascript function to block and unblock the element

              a) blockElement - takes the Salesforce id of the component to block.
              b)unblockElement - takes the Salesforce id of the component to unblock.



How the Page will look like?


Where is the Code?

Visualforce Page
 <apex:page controller="jQueryUIElementBlockDemo_Con">  
   <!-- Import Necessary Jquery js File and StyleSheets-->  
   <apex:includeScript value="{!URLFOR($Resource.jQuery, 'js/jquery-1.6.2.min.js')}"/>  
   <apex:includeScript value="{!URLFOR($Resource.jQuery, 'js/jquery-ui-1.8.16.custom.min.js')}"/>  
   <apex:includeScript value="{!URLFOR($Resource.jqPlugin, '/jquery.blockUI.js')}"/>  
   <apex:stylesheet value="{!URLFOR($Resource.jQuery, 'css/ui-lightness/jquery-ui-1.8.16.custom.css')}"/>  
   <script>  
     $j = jQuery.noConflict();  
     /*  
     *Pass the Id of the element to block   
     **/  
     function blockElement(sfId){   
       $j('[id$='+sfId+']').block({ message: '<img src="/img/loading32.gif" /><h1> Loading...</h1>',   
         css: {   
            border: 'none',   
            padding: '15px',   
            '-webkit-border-radius': '10px',   
            '-moz-border-radius': '10px',   
            opacity: .9  
         }   
       });   
       return false;  
     }  
     /*  
     *Pass the Id of the element to unblock   
     **/  
     function unblockElement(sfId){  
       $j('[id$='+sfId+']').unblock();  
     }  
   </script>  
   <apex:form >  
     <!--In the on start event of action status just call the blockPage method and onstop call the unblockPage js method-->  
     <!--Calling the blockElement js function blocks the page until unblockElement method is called-->  
     <!--Please note that the "Id" of element to black is passed to the js functions--->  
     <apex:actionStatus onstart="blockElement('pb2Block')" onstop="unblockElement('pb2Block')" id="blockElement"/>  
     <apex:sectionHeader title="jQuery UI Element Block Demo" subtitle="This is a demo of jQuery UI block for Blocking Certain portion of a page."/>  
     <apex:pageBlock title="Block This Section" id="pb2Block">  
       <apex:pageBlockSection title="Press the send request button to send a ajax request to the controller/server." collapsible="false">  
         <apex:pageBlockSectionItem >      
           <apex:outputLabel >Name</apex:outputLabel>  
           <apex:inputText />   
         </apex:pageBlockSectionItem>  
         <apex:pageBlockSectionItem >      
           <apex:outputLabel >Phone</apex:outputLabel>  
           <apex:inputText />   
         </apex:pageBlockSectionItem>   
         <apex:pageBlockSectionItem >      
           <apex:outputLabel >Mobile</apex:outputLabel>  
           <apex:inputText />   
         </apex:pageBlockSectionItem>  
         <apex:pageBlockSectionItem >      
           <apex:outputLabel >Zipcode</apex:outputLabel>  
           <apex:inputText />   
         </apex:pageBlockSectionItem>     
       </apex:pageBlockSection>  
       <apex:pageBlockButtons id="pb">  
         <!--Note here in the status attribute of command button the id of action status is provided-->  
         <apex:commandButton value="Send Request" action="{!processAjaxRequest}" reRender="pb" status="blockElement"/>  
       </apex:pageBlockButtons>  
     </apex:pageBlock>  
     <apex:pageBlock title="Unblocked Section">  
       <apex:pageBlockSection title="This Page block will remain unblocked" collapsible="false">  
         <apex:pageBlockSectionItem >      
           <apex:outputLabel >Name</apex:outputLabel>  
           <apex:inputText />   
         </apex:pageBlockSectionItem>  
         <apex:pageBlockSectionItem >      
           <apex:outputLabel >Phone</apex:outputLabel>  
           <apex:inputText />   
         </apex:pageBlockSectionItem>   
         <apex:pageBlockSectionItem >      
           <apex:outputLabel >Mobile</apex:outputLabel>  
           <apex:inputText />   
         </apex:pageBlockSectionItem>  
         <apex:pageBlockSectionItem >      
           <apex:outputLabel >Zipcode</apex:outputLabel>  
           <apex:inputText />   
         </apex:pageBlockSectionItem>     
       </apex:pageBlockSection>  
     </apex:pageBlock>  
   </apex:form>  
 </apex:page>  


Apex Controller
public class jQueryUIElementBlockDemo_Con {  
   public void processAjaxRequest(){  
     //Do some processing here  
     for(Integer i =0 ; i < 150000; i++){  
     }  
   }  
   //test method  
   static testMethod void test_ProcessAjaxRequest(){  
     new jQueryUIElementBlockDemo_Con().processAjaxRequest();  
   }  
 }  

Demo

Need more help to implement?

Don't worry packaged a demo visualforce page and all the necessary static resources like jQuery files, jQuery UI Block Plugin. Install the demo page from the here http://blogforce9dev-developer-edition.ap1.force.com/ProjectDetail?id=a0290000007rfwN




Saturday, June 9, 2012



[Update : Added Live Demo Links]

Ever wondered how to show user a wait or loading message while a ajax call from a visualforce page is in progress?
Well the answer is yes! You can always show a message to user using action status.
What if you want to block the page or some predefined area? Well the solution is jQuery UI block. Using this plugin you can actually block portions of visualforce page while the ajax action is processing.Well the part 1 I am demonstrating how to block the full page while a ajax request is in progress.

How it works?

Very simple from <apex:commandButton/> or <apex:actionFunction/> simply relate a <apex:actionstatus/> component which has a "onstart" and "onstop" event. Call the "blockPage" js function from the "onstart" and call "unblockPage" function from "onstop" attribute.

How the Page will look like?




Visualforce Page


<apex:page controller="jQueryUIBlockDemo_Con">  
   <!-- Import Necessary Jquery js File and StyleSheets-->  
   <apex:includeScript value="{!URLFOR($Resource.jQuery, 'js/jquery-1.6.2.min.js')}"/>  
   <apex:includeScript value="{!URLFOR($Resource.jQuery, 'js/jquery-ui-1.8.16.custom.min.js')}"/>  
   <apex:includeScript value="{!URLFOR($Resource.jqPlugin, '/jquery.blockUI.js')}"/>  
   <apex:stylesheet value="{!URLFOR($Resource.jQuery, 'css/ui-lightness/jquery-ui-1.8.16.custom.css')}"/>  
   <script>  
     $j = jQuery.noConflict();  
     //function to block the whole page  
     function blockPage(){   
       $j.blockUI({ message: '<img src="/img/loading32.gif" /><h1> Loading...</h1>',   
         css: {   
          border: 'none',   
          padding: '15px',   
          '-webkit-border-radius': '10px',   
          '-moz-border-radius': '10px',   
          opacity: .9  
         }   
       });   
       return false;  
     }  
     //function to unblock the page  
     function unblockPage(){  
       $j.unblockUI();  
     }  
   </script>  
   <apex:form >  
     <apex:sectionHeader title="Jquery UI Block Demo" subtitle="This is a demo of jQuery UI block for Blocking the whole page when a ajax request is in progress!"/>  
     <!--In the on start event of action status just call the blockPage method and onstop call the unblockPage js method-->  
     <!--Calling the blockPage js function blocks the page until unblockPage method is called-->  
     <apex:actionStatus onstart="blockPage()" onstop="unblockPage()" id="blockUI"/>  
     <apex:pageBlock title="Jquery UI Block Demo">  
       <p>Press the send request button to send a ajax request to the controller/server.</p>  
       <apex:pageBlockButtons id="pb">  
         <!--Note here in the status attribute of command button the id of action status is provided-->  
         <apex:commandButton value="Send Request" action="{!processAjaxRequest}" reRender="pb" status="blockUI"/>  
       </apex:pageBlockButtons>  
     </apex:pageBlock>  
   </apex:form>  
 </apex:page>  


Apex Controller


 public class jQueryUIBlockDemo_Con{  
   public void processAjaxRequest(){  
     //Do some processing here  
     for(Integer i =0 ; i < 10000; i++){  
     }  
   }  
   //test method  
   static testMethod void test_ProcessAjaxRequest(){  
     new jQueryUIBlockDemo_Con().processAjaxRequest();  
   }  
 }  

Demo
You can check the live demo from http://blogforce9dev-developer-edition.ap1.force.com/jQueryUIBlockDemo

Need more help to implement?

Don't worry packaged a demo visualforce page and all the necessary static resources like jQuery files, jQuery UI Block Plugin. Install the demo page from the the Project Detail Page http://blogforce9dev-developer-edition.ap1.force.com/ProjectDetail?id=a0290000007rfwI and go to "jQueryUIBlockDemo". The code is well commented and ready to use.