Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
0 Kudos
Inside of the aBPM Framework exists a lot of features and functionalities that helps to realize a custom scenario very quickly, but in some use cases the ordinary end user doesn't use action buttons at the bottom like a put back button for releasing the task. The typically end user close the task only via tab or window close. In such cases a task is claimed and cannot be opened, claimed or seen by substitute/s and/or other member/s (in case the task was assigned to a group). Inside of the following blog you will find a solution how the aBPM event call can be triggered in case of the tab/window close.

Use case:

An existing button/event in example a put back button in the button row at the bottom will not be used by the end user to release the task (green rectangle). The end user closes the task only via tab/window close or navigate to another URL address (red rectangles). The requirement is to trigger the exiting aBPM put back action during the tab/window close so that the task will be put back into status ready. In such cases the task is furthermore claimed and cannot be opened, claimed or seen by other people like substitutes. The requirement is to release the take via tab/window close.



Solution:

Inside JavaScript a lot of events are available that allows an interaction with the browser, windows, UI elements, browser storages and much more. Very good documentations can be found on:

https://wiki.selfhtml.org/wiki/JavaScript/DOM/Event/%C3%9Cbersicht

or

https://www.w3schools.com/js/default.asp

One of those events is very interesting for this solution, it is the "beforeunload" event of the window. This event is raised by the browser window itself if the end user tries to close the tab, to close the browser window, to use the navigation buttons (left to the address bar) or to open a new URL address.

Hint: Inside IE < Version 9 the "beforeunload" event was called "onbeforeunload".

Additionally with the event listener mechanism inside JavaScript it is possible to register a listener to the "beforeunload" window event and to execute an own function. Within the context of aBPM the own function (name: triggerPutback) contains the code lines to build the payload and to trigger the aBPM REST call like the button would do it.

Now the big question is why must this function prepare and execute the REST call/payload itself and doesn't trigger the firePress operation of the button?

The reason is that all BPM calls will be called asynchronously. The reason for this is a queue mechanism to prevent overhauling calls that based on results of a previous call, e.g. in case of events on input fields, corresponding validations and parrallel submit buttons that are clicked in unordered sequences. This approach is very good for the normal execution of aBPM actions but it is not optimal in case of the tab/window close. The reason is that the close will be executed faster before the async call will be send. Thereby the REST call/payload must be prepared and triggered synchronously through some own lines of code (attention the parameter "async" inside the ajax function must set to "false").

The following JavaScript code shows the solution in detail:
function triggerPutback() {
try {
var formView = sap.ui.getCore().byId("formView");

var payload = {
"bo" : JSON.stringify(formView.getModel("bo").getData()),
"cmd" : "Put_back.put_back",
"device" : formView.getModel("device").getProperty("/sDevice"),
"displayOption" : JSON.stringify({
"filterOption" : getFilterOption()
}),
"process" : JSON.stringify(formView.getModel("process").getData()),
"sap-ui-language" : sap.ui.getCore().getConfiguration()
.getLanguage(),
"sap-ui-number-format-language" : sap.ui.getCore().getModel(
"config").getProperty("/defaultNumberFormat/format")
};

jQuery.ajax( {
type : "POST",
url : "/abpm/actions/executeAction.do",
dataType : "json",
data : payload,
cache : false,
async : false,
success : function(data, textStatus, jqXHR) {
console.log("SUCCESS put back the task");
},
error : function(jqXHR, status) {
console.log("ERROR while put back the task");
console.log(jqXHR.responseJSON);
}
});
} catch (e) {
console.log(e);
}
}

function getFilterOption() {
if (sap.ui.getCore().byId("filterOption")) {
var iIndex = sap.ui.getCore().byId("filterOption").getSelectedIndex();
switch (iIndex) {
case 0:
return "All";
case 1:
return "Required";
case 2:
return "WithValidationError";
}
} else {
return "All";
}
}

if ('addEventListener' in window) {
window.addEventListener('beforeunload', function(event) {
console.log('putBack');
triggerPutback();
});
} else if ('attachEvent' in window) {// IE<V9
window.attachEvent('onbeforeunload', function(event) {
console.log('putBack');
triggerPutback();
});
}

Hint: This code snippet needs only to be loaded once if the UI will be initialized. A good place is the UI5TabletViewRenderer that was used in this example to insert those lines. An example for a custom UI5TabletViewRenderer can be found here (point 2):

https://blogs.sap.com/2016/12/27/extend-abpm-with-pdf.js-a-pdf-viewer-that-runs-inside-different-bro...

After deployment and a hard reload (clear brower cache, etc.) the task tab should be trigger the call in case of closing the tab or the browser window by the X. That can be checked via breakpoints inside JavaScript (please use the development tools of your browser) and/or use the Task management inside the Netweaver Administrator to check if the task status is changed from "In progress" to "Ready" after closing the tab/window.

Conclusion:

The solution of this blog can help to release BPM tasks in 95% - 99% of the end user cases. But there exists a small gap where this approach will not guarantee to put back tasks into status "Ready". One of those cases are network errors. In such cases the browser cannot send or the request cannot reach the SAP PO Java System and the task is furthermore claimed/in progress. This gap can be eliminated with an own implementation of a "task release monitoring" and a job that monitores to long claimed tasks and released those tasks automatically.