Custom container with SPARK UI toolkit

Salientprocess acquisition by IBM will make SPARK toolkit core part of IBM BPM in future release. SPARK introduces some nice new concepts, one of it is addressing that keeps SPARK containers invisible. Its public API promises to make your own coach view a container and I needed it on my code. So I tried and it did not work. Few hours of experiments with debugging SPARK code led me to workaround and defect report.

SPARK UI toolkit is built on top of IBM BPM coach framework and tries to hide some of its quirks. One of it is addressing: in coach framework navigation thru hierarchy of objects requires walking thru each level using context.getSubview() multiple times. Such boilerplate code breaks easily on layout reogranization. SPARK addressing copes with both problems allowing path-like navigation and by distinguishing views from containers (like layouts) making the latter non-addressable.

Let see it by example. Imagine we have own widget identified by “Block” that has content box filled by vertical layout “Vertical”, and inside layout there is text field with “Text” view id.

// classic navigation
var block = this.context.getSubview("Block")[0];
var vert = block.context.getSubview("Vertical")[0];
var text = vert.context.getSubview("Text")[0];
 
// spark navigation (note layout skipped in address!)
var text = bpmext.ui.getView("/Block/Text");

Now, what happen if we add extra horizontal layout between vertical and text?

// classic navigation - must be modified
var block = this.context.getSubview("Block")[0];
var vert = block.context.getSubview("Vertical")[0];
var horiz = vert.context.getSubview("Horizontal")[0];
var text = vert.context.getSubview("Text")[0];
 
// spark navigation - simply left intact!
var text = bpmext.ui.getView("/Block/Text");

What is even more attracting is that “Block” could be also invisble in addressing if its plays container role. This way with or without block we could simply address text by getView("Text")! And SPARK UI documentation clearly says that bpmext.ui.loadContainer() called on load handler of coach view serves this purpose.

Testing containers

Test layout

Test layout

Let start with regular coach view called “Custom Container CV” that has content box inside to place other coach views. To test behavior I made up a human service with coach holding four levels deep hierarchy mixing layouts (marked by red border) and my contaiers (blue borders). On the bottom there is text area that reports its own path plus collects path reports on all four containers.

Initially paths were reported as follows:

bpmext.ui.getCoachNGViewPath(textarea):	Horizontal/Custom1/Vertical/Custom2
bpmext.ui.getViewPath(textarea):	/Custom1/Custom2/Text
 
Container: Custom2
bpmext.ui.getContainerPath():		null
bpmext.ui.getViewPath():		/Custom1/Custom2
 
Container: Custom1
bpmext.ui.getContainerPath():		/Custom1  /* null expected, a SPARK bug? */
bpmext.ui.getViewPath():		/Custom1
 
Container: Vertical
bpmext.ui.getContainerPath():		/Custom1/Vertical
bpmext.ui.getViewPath():		null
 
Container: Horizontal
bpmext.ui.getContainerPath():		/Horizontal
bpmext.ui.getViewPath():		null

What you can read from it is that we have four coach views (getCoachNGViewPath), first horizontal layer then our custom view, then vertical layout, another custom view, and text area at the end.
Note that regular view path (getViewPath) run on text area widget does not “see” SPARK layouts. Also note that view path for containers is null. For container path it is
a bit more irregular as only leaf (deepest) container is always available e.g. for “Vertical” container the path is /Custom1/Vertical missing "Horizontal" at the beginning.

When "Custom container CV" is turned into SPARK container paths are reported this way:

bpmext.ui.getCoachNGViewPath(textarea):	Horizontal/Custom1/Vertical/Custom2
bpmext.ui.getViewPath(textarea):	/Text
 
Container: Custom2
bpmext.ui.getContainerPath():		/Custom2
bpmext.ui.getViewPath():		null
 
Container: Custom1
bpmext.ui.getContainerPath():		/Custom1
bpmext.ui.getViewPath():		null
 
Container: Vertical
bpmext.ui.getContainerPath():		/Vertical
bpmext.ui.getViewPath():		null
 
Container: Horizontal
bpmext.ui.getContainerPath():		/Horizontal
bpmext.ui.getViewPath():		null

Now it is clear that all wrappers around text area are transparent. Address path is direct, just a /Text and all cointainers have null view paths. Interestingly container paths are dangling at root (because parent containers are still invisible even for container path?) even though "Vertical" /Horizontal/Vertical path would be more natural then just /Vertical. Fortunately container paths are less relevant in business logic.

Setting coach view SPARK container

SPARK 4.4.4 documentation only mentions container creation through bpmext.ui.loadContainer(). Placed this method in coach load lifecycle handler made coach view addressable as container (bpmext.ui.getContainer() and bpmext.ui.getContainerPath() methods).
My coach view was still wronlgy available as regular view (view bpmext.ui.getView() and bpmext.ui.getViewPath() methods). It took me long time inspecting SPARK layouts code to understand SPARK public API shortcomings and make my coach view working as container -- I shared my concerns on product forum and SPARK support team confirmed my findings.

As of today the only way to make coach view true SPARK container is twofolds:

  1. set coach views property IS_ADDRESS_INVISIBLE to true before content box is managed (i.e. in inline javascript); this way coach view is not registered as regular view
  2. register coach view as container calling bpmext.ui.loadContainer() during load phase.
Cointaner in view-level handlers

Cointaner in view-level handlers

Choosing prototype-level handlers

Choosing prototype-level handlers

Container in prototype-level handlers

Container in prototype-level handlers

 

If coach view uses prototype-level handlers (see documentation why), then the whole container initialization code can be placed in inline JavaScript. For better debugging support code can be placed in separate JavaScript file same as SPARK and IBM stock controls are organized.

I hope that SPARK team will fix its API in one of next releases, I will keep you posted.

2016-12-21 update: as of SPARK toolkit version 4.4.5 and 4.4.6 this issue still remains not fixed.

This entry was posted in Software and tagged . Bookmark the permalink.

Leave a Reply

Your email address will not be published.