Académique Documents
Professionnel Documents
Culture Documents
24 June 2015
Learn approaches to customize coach controls for your organization, such as using included
files, creating third-party controls, and linking the controls with the Representational State
Transfer (REST) protocol. Also learn tips and tricks for overcoming common problems
encountered when creating coaches.
Introduction
IBM Business Process Manager (BPM) includes vibrant and configurable controls for coaches,
which you use to build to build user interfaces (UI) that your process participants use to interact
with a service. Occasionally, developers might need to create additional components to extend
functionality. This tutorial looks at the available options for beginner-to-novice level developers
for building new controls and incorporating advanced features into the controls. More advanced
topics are discussed, which require an understanding of Exposed Process Variables and the
IBM BPM cascading style sheet (CSS) styles. The same techniques apply to coaches for both
heritage human services for client-side human services. Coaches for client-side human services
also contain additional options, as described in the IBM BPM 8.5.5 Responsive Coaches video on
the IBM Business Process Manager Developer Center and in the Designing responsive coaches in
IBM Business Process Manager 8.5.5 blog entry.
The techniques in this tutorial are functional in IBM BPM V8.X environments. You should have a
basic understanding of HTML, JavaScript, IBM BPM, and the coaches framework.
Copyright IBM Corporation 2015
Branding and customizing the coach controls in IBM Business
Process Manager
Trademarks
Page 1 of 13
developerWorks
ibm.com/developerWorks/
When you create controls for an IBM BPM application, it is important to consider the time-to-output
requirement. The main purpose of the business application is to model business processes. For
this reason, control additions should be a secondary requirement to process implementation.
There are other toolkits in the Smarter Process Community on IBM Bluemix DevOps Services that
provide additional control sets, for example, bpm-CoachViewExamples. Be advised that because
they are community assets, some of the controls might act unexpectedly or not work on some
versions of IBM BPM.
IBM BPM comes with different UI components that allow developers to create coaches according
to an organization's needs. These stock components are built on the Dojo UI framework, a library
of JavaScript-driven controls. For manipulating the stock control schemes, such as colors, see
Leveraging the IBM BPM Coach Framework in Your Organization, an IBM Redbooks publication.
However, for some scenarios, the control capabilities in the IBM BPM coach framework might not
meet an organization's needs.
Organizations that require mobile-focused controls or controls that work better for users with
smaller screen sizes (for example, tablets), creating a custom control might be the answer. If
the organization requires a UI control that is not included in the existing stock controls, a custom
control might also be the answer. There are an abundance of existing libraries that can be created
in the IBM BPM product. Depending on the product version, the Dojo library itself includes many
controls that are not built into IBM BPM but that developers can create in IBM BPM.
Evaluating UI frameworks
When looking at UI libraries, it is important to understand the breadth of desired components.
Does your organization require only a single component or several components? Several
components might be easier to develop from a full library. Does the proposed library include a
multitude of control types that developers might need to use later? Importing the entire library
might make this process easier. Another important consideration for working with third-party user
interfaces outside of IBM BPM is the support you might need. Does IBM have any affiliation with
the third-party producer so that you can get support if needed from IBM? Is the library undergoing
active development, or is it no longer in use?
A major consideration, especially with the widening use of mobile devices, is the availability of the
library on a mobile device. Does the library work on mobile devices? Does it provide scaling to
screen size? A common library to consider is jQuery, which requires additional files to be loaded
on top of IBM BPM. Will this affect how your organization uses IBM BPM?
Page 2 of 13
ibm.com/developerWorks/
developerWorks
2. On the Behavior tab of the coach view, place the JavaScript for the slider (according to the
Dojo documentation) in the code window for a load event handler, as shown in Figure 2.
3. Open the palette on the coach view and place a Custom HTML block on the diagram. Copy
the HTML from the Dojo slider documentation and paste it in the HTML block, as shown in
Figure 3.
Page 3 of 13
developerWorks
ibm.com/developerWorks/
4. Open a new human service and create a coach on the palette. Drag the slider coach view
onto the coach, and then run the human service. You have now created a custom slider
control, as shown in Figure 4. The number field is included as the input tag.
Page 4 of 13
ibm.com/developerWorks/
developerWorks
2. Open the Behavior tab, and for the load, add the configurations and the bound variable
to the slider. Call the variables and use defaults. In the following example, the very
last value for each of the variables is the default value. This is important, because if a
variable is not provided to the coach view, the slider fails without the default set.var
boundValue = this.context.binding && this.context.binding.get("value") ?
this.context.binding.get("value") : 0;
3. To update the bound variable based on changes by the end user at run time, add one more
line of code like the following example. Notice the copy of the handle, which allows constant
updating of the value.
onChange: function(value){
//dom.byId("sliderValue").value = value;
boundValue = value;
console.log("change")
_this.context.binding.set("value",boundValue);
}
4. Open your human service with the slider and create a private variable of the integer type.
Bind the variable to an integer control on the diagram, and then bind it to the slider control.
Feel free to provide configuration inputs to the slider.
5. Run the human service and move the slider. The integer box should update with the correct
value. Note that the slider does not allow a number entry because the box is only an output.
See the following example for the complete code:
//console.log("1");
var boundValue = this.context.binding && this.context.binding.get("value") ?
this.context.binding.get("value") : 0;
//console.log("2");
var min = this.context.options && this.context.options.min ? this.context.options.min.get("value") : 0;
//console.log("3");
var max = this.context.options && this.context.options.max ? this.context.options.max.get("value") : 10;
var step = this.context.options && this.context.options.step ? this.context.options.step.get("value") : 1;
var style = this.context.options && this.context.options.style ? this.context.options.style.get("value") :
"width:300px;";
var id = this.context.viewid;
//console.log(id)
var slideDiv = document.getElementById("start");
slideDiv.setAttribute("id", id);
//console.log(slideDiv);
var _this = this
//console.log("2");
require([
"dojo/dom", // for inserting value in TextBox example
"dojo/parser", // parser because of TextBox decoration
"dijit/form/HorizontalSlider",
"dijit/form/TextBox" // this we only include to make an example with TextBox
], function(dom, parser, HorizontalSlider, TextBox){
//console.log(id);
parser.parse();
//console.log("inside"+_slideDiv);
//var _new = _bound
var slider = new HorizontalSlider({
name: "slider",
value: boundValue,
minimum: min,
maximum: max,
intermediateChanges: true,
style: style,
discreteValues: step,
onChange: function(value){
Page 5 of 13
developerWorks
ibm.com/developerWorks/
//dom.byId("sliderValue").value = value;
boundValue = value;
console.log("change")
_this.context.binding.set("value",boundValue);
}
}, id).startup();
});
Control ID
There is one last piece to consider: the control ID. Looking through the slider code, notice the
reference to the view ID. This reference provides the required unique widget ID. To see this issue
in action, drag an additional slider onto the human service and run the service, as shown in the
previous example.
Without the unique ID, you see a blank browser window and receive an error message about an
ID error in the browser console that is accessed either through Firebug or similar browser tools.
This error is because HTML IDs must be unique, meaning that two sliders with the implementation
cannot exist on the coach. To address this issue, IBM BPM has built-in behavior that provides the
view ID, accessible as a coach view attribute, which easily allows developers to create unique IDs
from the view ID.
Use the following code in your coach view load behavior to set the ID of the control to a unique
value:
var id = this.context.viewid;
Page 6 of 13
ibm.com/developerWorks/
developerWorks
3. Open the HTML Block on the coach view palette and use the following code to define the
button and dialog HTML.
<!-- This div was added to allow the dialog box to open >
<div data-dojo-type="dijit/Dialog" data-dojo-id="myDialog">
</div>
<button> type="button" class>="BPMButton BPMButtonBorder" ></button>
5. Put the Dialog Button coach view on a coach, and you're done. The AMD loads the needed
Dojo components more quickly than coding with dojo.require would.
6. Provide values for the configuration options, and put the coach view on a coach, as shown in
Figure 8.
7. Run the coach, and click the button. A dialog window should open.
Dojo has a number of advantages for IBM BPM developers. Most significantly, Dojo is
included with IBM BPM, meaning developers are able to use it without having to download
additional files.
See the following code example for the complete code:
var baseTextDirection = this.context.options._metadata.baseTextDirection &&
this.context.options._metadata.baseTextDirection.get("value") ?
this.context.options._metadata.baseTextDirection.get("value") : utilities.BiDi.BASE_TEXT_DIRECTION._default;
var generalPrefTextDirection = this.context.bpm.system.baseTextDirection;
Page 7 of 13
developerWorks
ibm.com/developerWorks/
//Gets the value input for the text content and labels
var innerText = this.context.options.innerText && this.context.options.innerText.get("value") ?
this.context.options.innerText.get("value") : "";
var title = this.context.options.title && this.context.options.title.get("value") ?
this.context.options.title.get("value") : "";
var confirmLabel = this.context.options.confirmLabel && this.context.options.confirmLabel.get("value") ?
this.context.options.confirmLabel.get("value") : "Submit";
var cancelLabel = this.context.options.cancelLabel && this.context.options.cancelLabel.get("value") ?
this.context.options.cancelLabel.get("value") : "Cancel";
var button = this.context.element.getElementsByTagName("button")[0];
//Adds the buttons to the dialog needs corrected spacing and labels
innerText = innerText + "<div class='dijitDialogPaneActionBar'><div style='display:inlineblock;padding:5px'><button id='ok' class='BPMButton BPMBorder' type='button'>" +confirmLabel+ "</button>"
+"</div><div style='display:inline-block;padding:5px'><button id='cancel' class='BPMButton BPMBorder'
type='button'>" +cancelLabel+ "</button></div></div>";
var visibility = utilities.handleVisibility(this.context, null, null, [button]);
if (visibility != "NONE") {
if (this.context.options._metadata.label && this.context.options._metadata.label.get("value") != "") {
button.innerHTML = this.context.htmlEscape(this.context.options._metadata.label.get("value"));
utilities.BiDi.applyTextDir(button, button.innerHTML, baseTextDirection, generalPrefTextDirection);
} else {
button.innerHTML = " ";
}
if (this.context.options._metadata.helpText && this.context.options._metadata.helpText.get("value") != "") {
button.title = this.context.options._metadata.helpText.get("value");
}
button.onmousedown = function() {
domClass.add(this, "BPMButton-down");
};
button.onmouseout = button.onmouseup = function() {
domClass.remove(this, "BPMButton-down");
};
var _this = this;
button.onclick = function() {
if (this.disabled == false) {
var context = _this.context;
if (context.binding) {
context.binding.set("value", true);
}
var _button = this;
//Sets the inner content and title
myDialog.set("content",innerText);
myDialog.set("title",title);
//Starts the dialog when the button is clicked
myDialog.show();
//Corrects the styling on the title bar
if(document.getElementsByClassName("dijitDialogTitleBar")[0]){
document.getElementsByClassName("dijitDialogTitleBar")[0].className = "BPMSectionHeader box blue"}
//Finds the submit button
var submit = document.getElementById("ok");
//Trigger for completing task is placed on the dialog button instead of the triggering button
submit.onclick = function() {
context.trigger(function() {_button.disabled = false; domClass.remove(_button, "BPMButton-disabled");});
}
//This finds the cancel button and triggers the dialog to close when clicked
var cancel = document.getElementById("cancel");
cancel.onclick = function() {
myDialog.hide();
}
}
}
this.updateStyle();
Page 8 of 13
ibm.com/developerWorks/
developerWorks
};
Importing files
One of the first considerations involves the intricate way that IBM BPM loads files attached to
coach views. Looking at the Foundation library, the coach needs to load the required JavaScript
files in a particular order to ensure that the components function. In the download of the UI library,
the files that the coach must load are included as separate JavaScript files. For more information,
see the Foundation website.
An important change that you must make is assembling a single JavaScript file with all of the
required JavaScript files in the load order dictated by Foundation. This means copying and pasting
all of the required JavaScript into one file in the correct order. If jQuery is used by the desired
library, then jQuery is included in the file also. This step is absolutely crucial. If it is not correct,
you might find inconsistent results, or the coach might not work at all. After compiling the file, you
can add the file in the Process Designer as a web file and then attach the file to the coach view as
needed. In Figure 9, all three JavaScript files are in the foundation.min.js file in the correct order.
When importing additional libraries, you might face issues with conflicting CSS classes. In some
cases, IBM BPM adds additional classes to components, or components have the same names
between libraries. The easiest way to counteract these significant issues is to remove the stock
style sheets. Use the following code:
Branding and customizing the coach controls in IBM Business
Process Manager
Page 9 of 13
developerWorks
ibm.com/developerWorks/
domAttr.remove(query("body")[0],"class","claro");
domAttr.remove(query("html")[0],"class","dj_gecko");
domAttr.remove(query("html")[0],"class","dj_contentbox");
domAttr.remove(query("html")[0],"class","dj_ff24");
In addition, you might be required to remove all references to the stock CSS files. Remove the
document elements that reference the CSS files. The main culprit is the coach_ng.css file.
Code example
function taskContain(){
require(["dojo/request/xhr"], function(xhr){
var context = _this.context;
var url = "/rest/bpm/wle/v1/search/query";
xhr(url, {
handleAs: "json",
query: {
condition:"instanceStatus|Active",
organization:"byInstance",
run:true,
shared:false,
filterByCurrentUser:true
},
headers: { 'Content-Type': 'application/json', 'Accept':'application/json' },
method:"PUT"
}).then(function(data){
taskContainer.innerHTML = "";
Page 10 of 13
ibm.com/developerWorks/
developerWorks
for(var i=0;i<data.data.data.length;i++){
if(data.data.data[i].taskStatus!="Closed"){
console.log("found one");
var subject = data.data.data[i].taskSubject;
var taskId = data.data.data[i].taskId;
};
};
}, function(err){
// Handle the error condition
}, function(evt){
// Handle a progress event from the request if the
// browser supports XHR2
});
});}
Conclusion
This tutorial examined different ways to create custom coach controls in IBM BPM. It explained the
Dojo framework included in IBM BPM and how to develop components without having to include
additional packages. This tutorial also examined how to use third-party frameworks such as
Foundation to create new mobile ready components. Finally, the tutorial showed how to leverage
REST to provide required functionality and mobile readiness.
Acknowledgements
The author would like to thank James Carr for his review and contributions to this tutorial.
Page 11 of 13
developerWorks
ibm.com/developerWorks/
Resources
Page 12 of 13
ibm.com/developerWorks/
developerWorks
Page 13 of 13