الأربعاء، 29 أبريل 2020

How to display a please wait message when the server is processing using addBusyStateListener in ADF ?


Clients often require their ADF applications to process a lot of data or upload big files when their users click on a specific button.
Those treatments can often take a couple of minutes to run and your user may lose patience or wonder why the application isn’t responding.
As a best practice, you should always aim to provide a fast responding application and run the big treatment in an asynchronous way behind the scene to avoid blocking the user interface.
But if you still have to process the long action synchronously, for example, to upload a big file, you need to display a message for the user to know his request is getting processed.
You’ll also need to prevent user interaction with the screen that could stop this treatment being processed. (navigation for example)
To implement it in ADF, you’ll need :
  • A modal ADF popup or another element to display the “processing in progress” message :
Tip 1: Be sure that this group is set on all the page where you need to warn the user. (If you need it more than once set it in a template)
Tip 2: Be sure that the popup is set as clientComponent=”true”. (if not it’ll fail to display most of the time and you’ll have a hard time understanding why)
Tip 3 (optional) : set a pure HTML div <div id=”loaderId”></div> before the popup to simplify getting it’s absolute id. (It’s hard to retrieve the absolute ADF element id in javascript)
<af:group id="pt_g3">
<div id="loaderId"></div>
<af:popup id="processingP" contentDelivery="immediate" clientComponent="true">
<af:dialog id="d2" title="Processing..." type="none" closeIconVisible="false" inlineStyle="text-align:center;" clientComponent="true"
modal="true">
<f:facet name="buttonBar"/>
<af:panelGroupLayout id="pgl2" layout="vertical" halign="center">
<af:spacer width="10" height="10" id="s11"/>
<af:outputText value="Please wait..." id="ot2669"/>
</af:panelGroupLayout>
</af:dialog>
</af:popup>
</af:group>
  • client listener to trigger the busy listener only on the buttons where you require the user to be warned :
<af:commandButton text="Do Something" immediate="true" partialSubmit="true" actionListener="DoSomething" >
<af:clientListener method="warnAndPreventUserInput" type="action"/>
</af:commandButton>
  • Define this javascript resource for your page :
Tip 1: Also ensure this javascript is set on the page where you need to warn the user.
(I usually recommend to set it in the header template so it’s available on all page using it)
Tip 2: If your popup often open itself again after being closed the first time be sure to set the listener on the clicked element (clickedElem = evt.getSource();)
Most issues are due to the removeBusyStateListener arguments being different from the previous addBusyStateListener
Tip 3: Refer to the comments describing how we use the ADF public javascript API to get notified when the server is busy and done.
(for more information: https://docs.oracle.com/html/E12046_04/oracle/adf/view/js/base/AdfPage.html#addBusyStateListener_Object__Function_)
var popup = null;
var clickedElem = null;
function triggerOnLoad(event) {
//You can either set the popup using the pure html div id (recommended)
popup = AdfPage.PAGE.findComponentByAbsoluteId(document.getElementById('loaderId').nextSibling.id);
//or set the popup knowing the full id of your popup for example :
//popup = AdfPage.PAGE.findComponentByAbsoluteId('p1:processingP');
//popup = AdfPage.PAGE.findComponent('processingP');
return true;
}
function warnAndPreventUserInput(evt) {
//To avoid most mistake where addBusyStateListener and removeBusyStateListener don't have the same arguments
//You can set the element to listen for the application busy state to be the one the user just clicked :
clickedElem = evt.getSource();
if (popup != null) {
//Adds a listener to call the handleBusyState function whenever there is a busy state event.
AdfPage.PAGE.addBusyStateListener(clickedElem, handleBusyState);
//Don't authorize the user to interact with ADF while it's busy
evt.preventUserInput();
} else {
console.error('The processing pop up isnt defined on this page ');
}
}
//JavaScript call back handler
function handleBusyState(evt) {
if (popup != null) {
if (evt.isBusy()) {
//Processing in progress so we display the popup
popup.show();
} else {
//Processing is done so we can close the popup
popup.hide();
//Important : We remove the listener from the clicked object so it will
//stop looking for a busy event to display the popup
AdfPage.PAGE.removeBusyStateListener(clickedElem, handleBusyState);
}
} else {
console.error('The processing pop up isnt defined on this page ');
}
}

ليست هناك تعليقات:

إرسال تعليق

ADF: Programmatic View Object Using Ref Cursor.

ADF: Programmatic View Object Using Ref Cursor. Posted by:  Manish Pandey   April 25, 2013   in  ADF   Leave a comment   3758 Views Sometime...