2018-01-27 04:56:26

if you have worked with coach framework of IBM BPM you must have noticed that visibility for a coach view in a coach can be set in three main ways

  • choosing from drop down
  • binding to a string variable
  • using rule
  • using script

but when placing controls inside a coach view you will find only two methods

  • choosing from drop down
  • binding to some string variable

. other two methods namely rules and script are not available inside coach views.
So the big question now is how to set visibility of controls inside a coach view dynamically ???
the solution is quite easy
here are the steps involved and then i’ll give the code to make it work.

  1. watch for the variable’s value change which will control the visibility
  2. capture and calculate the target visibility
  3. set visibility of target control

and this is how it can be achieved
Step 1: watch for change of value on a variable
if the variable(property) under consideration is a part of any Business Object, we can use bind or bindAll apis for example lets say our coach view is bound to a Variable of type name value pair and we want to take some action whenever the name property changed, in real world example it can be something like firing ajax to get account details whenever account number changes.
the syntax of bind and bindAll is very simple
bind takes three parameters while bindAll takes only two. this difference is because bind watches for change of the specified property’s value while bindAll does it for all the properties of the BO on which it is called

this.context.binding.get("value").bind("name",functionName, functionContext)
//here name is the property in bo which you want to monitor for a change

this.context.binding.get("value").bindAll(functionName, functionContext)
                

While what bind does is, it attaches function given as second parameters to the change event of property given as first parameter which is then called back in case of change of value with the context passed as third parameter. binAll calls back the function passed as first parameter with context of parameter passed as second parameter whenever any of the properties in bound variable changes.
what I normally prefer for function is a function defined in inline script section of the coach view.

//inline javascript

this.handleVisibility = function(){
	//here write your rules to get bo proprty value and process acordingly
}.bind(this);
//function defination .bind(this) allows me to use this.context inside the function body
                

more about .bind()

//load
this.context.binding.get("value").bind("name",handleVisibility, this)
                

Step 2: capture and calculate the target visibility
now inside your handleVisibility function get the bo proprty variable value and use it to calculate the visibilty
something like this

//inline javascript
this.handleVisibility = function(){
	//here write your rules to get bo proprty value and process acordingly
	var proprtyValue = null;
	if(this.context.binding){	//this check is to avoid cases where we miss to binding the bo on coach
		proprtyValue = this.context.binding.get("value").get("propertyName")
	}
	if(proprtyValue == xyz){		// write your logic here
		//set visibility default
	}else{
		//set visibility else
	}
}.bind(this);
                

Step 3: set visibility of target control
In order to set target visibility we need it div id.
so after doing all this the big question here is how to find div id ????
the method which I use is to use viewId to capture element via querryselector and then find the element id.
for this method to work we have to set a view id for the control which should be unique on the rendered page.
how I achieve this ??
I use a view id which is combination of cv name and the proprty name which the control is bound to
so lets say we have a cv named userDetails which has a control bound to property xyz for which the visibilty need to be set
in this case I will keep viewid of this control as userDetailsXyz
here is how it works

	var control = document.querySelector('div[data-viewid="userDetailsXyz"]');
                

once I have the control all we need to doo is to find out its id and use that with bpm apis to set visibility
and so the complete set visibility function would look something like this

//inline javascript
// calculate visibility
this.handleVisibility = function() {
    //here write your rules to get bo proprty value and process acordingly
    var proprtyValue = null;
    if (this.context.binding) { //this check is to avoid cases where we miss to binding the bo on coach
        proprtyValue = this.context.binding.get("value").get("propertyName")
    }
    if (proprtyValue == xyz) { // write your logic here
        //set visibility default
        this.setVisibility("userDetailsXyz","DEFAULT")
    } else {
        //set visibility else
        this.setVisibility("userDetailsXyz","NONE")
    }
}.bind(this);
// note :- valid visibility options are DEFAULT NONE READONLY HIDDEN


//set visibility
this.setVisibility = function(viewId, visibility) {
    var control = document.querySelector('div[data-viewid="' + viewId + '"]');
    console.log(viewId, visibility, control);
    controlId = control.id;
    if (controlId) {
        var target = com_ibm_bpm_global.coachView.byDomId(controlId)
        if (target) {
            if (visibility && visibility != "") {
                target.context.options._metadata.visibility.set("value", visibility)
            } else {
                console.log("visibility was null or empty")
            }
        } else {
            console.log("BPM context for control with \"data-viewid=" + viewId + "\" not found");
        }
    }
}.bind(this)