Tuesday, October 8, 2013

Prevent User Input while Server Side Activity In Progress

Sometimes, we may need to block the user input in ADF application while server side activity is still active. Following post will help you to achieve this.

Case1:
  • First of all add a Popup (af:popup) ADF Faces component to the page with an embedded Dialog (af:dialog) component in it as shown below.
        <af:popup id="busyPopup" clientComponent="true" contentDelivery="immediate" childCreation="deferred">
            <af:dialog id="busyDialog" type="none" closeIconVisible="false" title="Loading, please wait..." contentWidth="250">
                <af:image source="/progress_bar.gif" shortDesc="Loading..." id="i2"/>
            </af:dialog>        
        </af:popup>   

            progress_bar.gif:
  • Next, add following java script to the page with af:resource tag of type 'javascript'.
        <af:resource type="javascript">
          function showBusyPopup(evt) {
              var popup = AdfPage.PAGE.findComponentByAbsoluteId('busyPopup');
              if (popup != null) {
                  AdfPage.PAGE.addBusyStateListener(popup, busyStateListener);
                  evt.preventUserInput();
              }
          }
          function busyStateListener(evt) {
              var popup = AdfPage.PAGE.findComponentByAbsoluteId('busyPopup');
              if (popup != null) {
                  if (evt.isBusy()) {
                      popup.show();
                  }
                  else if (popup.isPopupVisible()) {
                      popup.hide();
                      AdfPage.PAGE.removeBusyStateListener(popup, busyStateListener);
                  }
              }
          }
        </af:resource>

  • Next, add af:clientlistener component of type 'action' for af component in page and refer showBusyPopup as method to be triggered.
            <af:commandButton text="Show PopUp" id="cb1" partialSubmit="true">
               <af:clientListener method="showBusyPopup" type="action"/>                 
            </af:commandButton>

If we run the application with these changes, the popup will be displayed when you click on Button displayed on page. And the popup will get disappeared automatically when server side task get finished.

Popup:

I recommend to perform above mentioned steps 1 & 2 in template page, so that you can reuse same functionality across application.

Case2:

Now let us say, we want to prevent user input for each server side activity. To achieve this, remove af:clientlistener at component level and add it at page level with type 'load'.

<af:clientListener method="showBusyPopup" type="load"/>

I faced an issue when I tried to handle each server side activity i.e. case2. Its not working properly with pages having LOV's.

Case3:

If you want to just prevent the user input till event get completed, try following simple java script. No pop up will be displayed as in Case 1 & 2.

<af:resource type="javascript">
 function showBusyPopup(evt){
    evt.preventUserInput(); 
  }
 </af:resource>

No comments:

Post a Comment

Provide your thoughts !