Designer 10.5 | webMethods CAF and OpenUI Development | Understanding the Client-side Model | Script Placement in the CAF Model
 
Script Placement in the CAF Model
The model wraps a DHTML control, when a page is rendered on the client. The control's HTML element must exist on page. That is, the browser must have parsed the HTML and included it in page's DOM before a model for that control is created. For example, if a script block on a page has some code which models a control as the page is being loaded, the script block must be placed after the modeled control. If the script block that models a control does so in a operation that is executed after the page is loaded such as the result of a mouse click on the control, you can have the script block placed anywhere on the page.
A common scenario for advanced scripting is to extract complicated JavaScript functions into an external script file, using the IncludeScript control. Client-side control IDs are generated by a complicated algorithm on the server and are not predictable ahead of time on the client. It is often necessary to calculate client-side control IDs using the clientIds property of the active page bean #{activePageBean.clientIds['myControlId']}, while rendering the page, and then storing the IDs in global variables.
Note:
It is a best practice to store the control ID rather than the model instance. The model instance can cache information about the control and over time become out-of-sync with the actual control state.
A good way to prevent global variables defined by one portlet instance's page from colliding with variables from another's is to define a master global object that can be shared among all instances of the portlet on a page or all instances of a set of portlets on a page. For example, all webMethods Task Engine portlets might share a global object called WMTE, conditionally defined in a script block at the top of each portlet page:
// if the WMTE object does not exist, create a new empty WMTE object
if (WMTE) var WMTE = {};
In JavaScript, you can treat all objects as a generic map that maps arbitrary string keys, the object's property names, to arbitrary object values, the object's property values. You can then use the master global object to map arbitrary global variable names to arbitrary values. For example:
WMTE['taskCount'] = 32;
You can use a key unique to the portlet instance such as the portlet's view root ID to map a global variable to a dynamic value. For example:
WMTE['#{activePageBean.clientIds['myRootId']}' + '.taskCount']
=#{activePageBean.taskCount};
Any function defined in an external script file, as long as the function was passed the view root ID, can lookup the taskCount global variable specific to the current portlet instance. For example:
function wmte_doSomething(rootId) {alert(WMTE[rootId + '.taskCount']);}
Use this technique with function names as well. For example, an external script file might contain the following code:
if (!WMTE)var WMTE = {};WMTE.doSomething = function(rootId)
{ alert(WMTE[rootId + '.taskCount']); }
Invoke this function as WMTE.doSomething(rootId)or as WMTE['doSomething'](rootId).
For more information about CAF controls, see the webMethods CAF Tag Library Reference, as described in Finding Information about CAF Controls.
Related Topics