• Andrzej Michalec
    November 2, 2016 at 4:33 am #2982

    SPARK containers like layout coach views (CVs) are not directly addressable as regular views and they appear either on bpmext.ui.getViewPath() or on bpmext.ui.getContainerPath(). I have a CV that works as decorator wrapping around functionality of other CVs (like “confirmation dialog” decorator around “button” CV). Since this decorator CV is statically configured it is good candidate for container – otherwise addressing of wrapped element must be changed along with changes to wrappers around it. I tried to mark decorator CV as container by calling bpmext.ui.loadContainer(this) in “load” handler (as well as inline javascript section) without success and without any hints/errors on console — it still appears on getViewPath() as regular view.

    I see that built-in widgets like layouts are following always “custom control” concept delegating all work to external JS file, overriding NG handlers on prototype level etc. This is good when content is managed fully in programmatic way. Is it possible however to set CV as container using regular CV programming model (with “behavior” handlers, not external JS files for whole behavior)? Is is possible to have CV working as container while having extra SPARK CVs drawn on layout (like hidden modal dialog etc)?


    Andrzej Michalec
    November 7, 2016 at 5:22 am #2998

    I tried again to solve my issue in spare time. Results were puzzling so let me share my experience.

    First I tried creating custom container based on “creating you own control” just to discover it misses crucial step of setting coach view (CV) “prototype-level event handlers” property that allow properly use handlers defined by initialisation script. Making my code with prototype-level handler did not work either. What I noticed though was that my CV became both view and container, so that bpmext.ui.getView(“myContainer”) and bpmext.ui.getContainer(“myContainer”) were returning the same object. Also DOM inspection showed that private structures were redundantly created (there were _bpmextViewNode and _bpmextContainerNode in myContainer).
    Then I blamed content-box automatic initialization for wrongdoing because HorizontalLayout and VerticalLayout were containers and they were managing their content views themselves. With view-managed code for content-box I tried to revert initialisation order – first loadContainer() then create child CVs, that was not working either.
    Debugging view-managed creation of children showed that first call to context.createView() creates _bpmextViewNode so that bpmext.ui.loadContainer() is somehow separate step. Further daunting inspection ultimately got me discovery of IS_ADDRESS_INVISBLE property of CV necessary to remove CV from views chain!!!
    It looks that setting this property before child views creation prevents framework from _bpmextViewNode injection (and makes this CV completely non-addressable by SPARK) and later calling bpmext.ui.loadContainer() creates _bpmextContainerNode on target CV and makes it addressable via bpmext.ui.getContainer().

    In my opinion SPARK UI container part API is incomplete. Documentation of bpmext.ui.loadContainer() leads to impression that this method call is sufficient to register CV as container and remove from regular view path, which is obviously not true. Also magical-spell IS_ADDRESS_INVISIBLE is not part of protocol and barely looks like prepared to become part of public API.

    Despite custom container issue I was also confused by addressing scheme of containers. Having physical path of containers and views like this: “/HorizontalLayout/OneControl/VerticalLayout/AnotherControl” getViewPath() for AnotherControl returns “/OneControl/AnotherControl” which is right for “invisible” containers.
    I would expect however that containers path is similar, hiding on path what is regular view, so that getContainerPath() for VerticalLayout
    could give “/HorizontalLayout/VerticalLayout”. But it is not! All containers’ addresses are laid flat under the root view i.e. “/VerticalLayout” next to “/HorizontalLayout”… really? why?

    To be fair, I really like SPARK compared to bare coach UI, and I keep my fingers crossed. I just wish for better support and more precise and tested public parts of API to not waste developers’ time.

    SPARK Support
    November 7, 2016 at 7:53 am #3004

    Hello Andrzej,

    Thank you for your appreciation of the SPARK product and your enthusiasm to delve more deeply in the underlying design aspects.

    You have brought up several interesting questions here.  I have reached out to our Development Team to consider these questions and ensure that we provide a thorough response that will address your concerns.  We appreciate your patience.


    Stephen P.

    November 7, 2016 at 1:58 pm #3007


    I have defined simple containers by using the UNDOCUMENTED (this will be fixed in an upcoming release)

    this[“IS_ADDRESS_INVISIBLE”] = true;

    The key thing here, is that this must be put in the Inline Java Script.  Simply putting this prior to the loadContainer does not seem to work (not sure why).

    Can you try this and see if it works for you




    Andrzej Michalec
    November 9, 2016 at 7:04 am #3025

    Actually I have already made my code working as a container. My rant was just about disclosing finding on my way to solution. Once again, the problem was that method to make it working is, as you said, undocumented. It is not even mentioned that is part of internal API, it is just there in the code meaning can be replaced without notice and relaying on it not good idea.

    Note that both the IS_ADDRESS_INVISIBLE flag and loadContainer() method are disconnected in their work. The flag makes container “not registered” in view chain, while loadContainer() makes it registered in containers set. This two-step process has integrity consequences. You can easily mess up thing — when setting this flag to true and not calling loadContainer your coach view will be completely hidden (neither view nor container addressable) or in opposite, you may not set flag (or set it too late) and call loadContainer to make your coach view both view AND container addressable.

    You said that “Simply putting this prior to the loadContainer does not seem to work (not sure why)“. I already explained how your code works 🙂 when content box is created IBM coach framework calls context.createView() that takes into account IS_ADDRESS_INVISIBLE flag; if flag is not set then current view is being registered as SPARK regular view, with flag set to true current view is not having SPARK view structures initialised. Now look when coach view code is called: first (1) your inline script is called, then (2) framework manages content box creating children and (3) lifecycle load/view handlers are called. It means that “invisibility” flag must be placed in (1) before child views are made in (2), and later you register container in load (3).

    To summarise, with normal even handlers I put these snippets:
    * inline javascript: this.IS_ADDRESS_INVISIBLE=true;
    * load handler: bpmext.ui.loadContainer(this);

    For prototype-level handlers (checkbox on coach view “overview” tab) all can be done in inline javascript like this:

    this.constructor.prototype.load = function() {
    SPARK Support
    November 16, 2016 at 12:08 pm #3091

    Hi Andy,

    Thank you for your feedback.


    Stephen P.

    Andrzej Michalec
    January 18, 2017 at 2:19 am #3505

    Dear Team,
    I am still confused about approach to solving reported issues. I already pointed out that API is incomplete mixing public and private properties (hidden or undocumented if you will). So you added a paragraph to “creating your own control” article and… this is it? I had high hopes you will rework API so that loadContainer() will do the magic on hiding address etc. without some semi-documented tricks.

    However if you decided IS_ADDRESS_INVISIBLE is indeed part of formal contract to make custom CV a container, please make it clear. Otherwise my suspicion is the code will remain non-public and let you freely and silently change from release to release breaking client code. Also please make this property part of JS API documentation as unaware reader of loadContainer() function will get same impressions as I had.


    Saroj Panda
    January 20, 2017 at 3:45 am #3524

    Hi Andy,

    Great finding and nice explanation on creating the custom containers using SPARK UI. This will surely be helpful and I agree atleast this should be updated properly in JS API documentation if Salient is not planning to take care of this internally.



    SPARK Support
    January 20, 2017 at 12:43 pm #3533

    Hi Andy and Saroj,

    I do have an article planned in the backlog to provide documentation on how to handle addressing as a SPARK container.


    Stephen P.

Viewing 9 posts - 1 through 9 (of 9 total)

You must be logged in to reply to this topic.

Start typing and press Enter to search