Tab/window close management: aBPM (accelerates Business Process Management) gives you a powerful framework to generate sophisticated Fiori-like UIs, but sometimes you need to break its chains to leverage your UI with more functionality.

One example is the need for JavaScript code when using the Link UI Control. aBPM gives you the possibility to set the URL in a static or a dynamic way, but sometimes you don’t want the “simple” navigation to the URL, but add some logic before, after or meanwhile executing the navigation. Here comes JavaScript in place, but where should it be placed, when aBPM lacks the possibility to freely define the HTML tag or the onclick-Event?

AS-IS Situation:

There are two out-of-the-box ways to place a URL on a UI created with aBPM:

    1. Type it statically in the technical Excel’s column X “default value” or
    2. Set it dynamically in a callback method. In the technical Excel’s column S “DataTypeExtension” the value “DYNAMIC” needs to be maintained. The callback’s coding could look like this:
ctx.getBusinessObject().getAttribute(DemoFieldsEnum.MYLINK).setStringCurrentValue("https://www.sap.com");

The Need:

Sometimes a (hyper-) link should have more functionality than just navigating to a URL, so it would be nice to somehow listen for the click event to be able to execute some more coding. HTML elements use the JavaScript event handler onclick to realize the call of additional coding/functionality. aBPM UI elements are generated, so you don’t have access to the HTML attributes directly.

So here is a way to achieve the execution of additional coding by adding your own event listener:

In the technical excel everything should be maintained like if you create a dynamic link, but define your own value for the technical Excel’s column S “DataTypeExtension”, for example “DYNAMIC_JS”.

The aBPM class that builds up the link HTML tag is called “UI5TabletLinkRenderer” and can be found in the DC abpm.ui.services of the  ABPM_UI5 SC. The way how to overwrite and enrich it with your coding to place the event listener is similar to the second and third paragraph of the blog Extend aBPM with PDF.js, so I will only describe it very briefly. You need two more classes in your project: CustomRendererFactory and UI5TabletLinkRenderer.

Let’s start with the CustomRendererFactory, which does nothing more than to decide when to execute your custom HTML link renderer if ever a HTML link UI element shall be displayed and rendered. The coding could look like this:

package <vendor>.custom.renderer; import com.sap.consulting.abpm.core.bl.entities.UIElement; import com.sap.consulting.abpm.ui.services.renderer.DefaultRendererFactory; import com.sap.consulting.abpm.ui.services.renderer.IRenderer; import com.sap.consulting.abpm.ui.services.renderer.RenderContext; public class CustomRendererFactory extends DefaultRendererFactory { @Override public IRenderer getRenderer(UIElement uiElement, RenderContext ctx, Object data) { if (uiElement.equals(UIElement.VIEW)) { return new UI5TabletLinkRenderer(); } else { return super.getDefaultRenderer(uiElement, ctx, data); } } } 

So now let’s have a look at the UI5TabletLinkRenderer. All you need to place your event listener is adding another if branch catching the DataTypeExtension “DYNAMIC_JS” of the attribute meta data. What is added to the HTML link is the UI5 method attachPress, which adds exactly the event listener that you need. That branch can look like this:

else if (StringUtils.equalsIgnoreCase(amd.getDataTypeExtension(), "DYNAMIC_JS")) { String prefix = params.getBindingRenderer().getPrefix(params); writer.append("var dispatchCall = function( event ) { event.preventDefault(); openLink(event);};"); writer.append("var ").append(fieldName).append("=new sap.m.Link('").append(fieldName).append("',{").append( "enabled:true,target:'_blank',").append(this.getLayoutData(ctx, amd, param)).append("});").append(fieldName + ".addStyleClass('").append( styleClass).append("')"); writer.append(".attachPress(dispatchCall);"); writer.append(";"); writer.append(UI5RenderUtils.generateAttributeBinding(fieldName, prefix, "setText", "bindProperty('text',", "secondValue")); } 

What is done here is that a new JavaScript function called dispatchCall is linked to the press event of the UI element. It passes the event itself and calls another function called openLink, but it also prevents the default behavior of a link: the navigation to URL. Here the navigation is implemented in an arbitrary JavaScript class or library that is included in you coding in some utility package.

The function openLink could look like this:

openLink = function openLink(event) { var linkId = event.oSource.sId; var linkUrl = sap.ui.getCore().byId(linkId).mBindingInfos.href.binding.oValue; // do stuff  window.open(linkUrl); }; 

The URL, which is maintained in a callback method, is delivered in the event object and can be executed wherever and whenever you want.

That’s it!

Now this solution could be used to realize further scenario implementation like described in this blog:

https://blogs.sap.com/2017/12/07/tabwindow-close-management-part-2-abpm-scenario-implementation/

Thanks & Regards,

Jan-Henrik