VIVO Developers Guide
This developers guide contains information on how to extend VIVO with your own, custom tools.
A VIVO tool has two basic components: an class and an initializer function.
The Init Function
The init function takes two parameters: the id of the element and a string containing the parameters (the value of the vivo attribute). The init function takes the element id and the parameters and generates the javascript call to create a new instance of the class. The init functions will look very similar to one another. Let's look at the InPageTooltip init function:
function initInPageTooltipTool(id, params) {
var element = id;
var tooltipElement = null;
var parameters = "";
var paramsArray = params.split("|");
for (var i = 0; i < paramsArray.length; i++) {
var j = paramsArray[i].indexOf("=");
if (j > 0) {
var pName = paramsArray[i].substring(0,j);
var pValue = paramsArray[i].substring(j+1);
if (pName == "tooltipElement")
eval(pName + " = pValue");
else
parameters += pName + ": '" + pValue + "', ";
}
}
if (parameters.length > 0)
parameters = parameters.substring(0,parameters.lastIndexOf(","));
if (element && tooltipElement)
eval("new InPageTooltip(element, tooltipElement, {" + parameters + "})");
}
Tools usually have two element references. The first, element, is the element containing the vivo:<tool> attribute. The second is the element the tool does the action on. In this example, this second element is the tooltipElement. It is the element containing the tooltip.
The main meat of this function iterates over the parameters, re-parsing the string into one that looks like a named array assignment (i.e. "name1: val1, name2: val2, etc...").
Finally, if the element and the tooltipElement are defined, create an instance of the InPageTooltip class. We use eval here to take advantage of the parameters string. I think it is possible to not use eval and generate the parameters array while iterating through the string.
The Tool Class
The supplied tool classes are created using prototypes Class.create(). Then the prototype of the class is assigned as a named array. So the shell of a tool might look like this:
var newTool = Class.create();
newTool.prototype = {
initialize: function(element, actionElement, options) {
var self = this;
this.element = $(element);
this.actionElement = $(actionElement);
this.options = Object.extend({
action1: default1,
action2: default2}, options || {});
if (self.options.callbackFunction)
self.options.callbackFunction = eval(self.options.callbackFunction);
this.mylistener = this.myAction.bindAsEventListener(this);
Event.observe(this.element,this.options.action||'click',this.mylistener);
},
myAction: function(event) {
//perform some action;
}
};
Important Points
- The variable this.options contains the parameters. It is created by supplying default values, and passing in the options function parameter. The values in options override the default values.
- If overriding callback functions is supported, a non-default callback is set in this.options as a string. So after this.options is defined, init eval's the string to actually create the function.
- This shell code also illustrates how to bind event listeners in the tool. The event handler is a method of the tool (defined above as myAction). In init, the function is bound as an event listener, and the Event.observe (part of scriptaculous Event framework), is called with the element to observe, the action (e.g. click, hover, etc), and the bound event listener.
Register the Tool
The last part of tool development is to register the tool in VIVO. VIVO's start function registers the standard tools. To register a custom tool, do the following after the tool is created:
Vivo.toolTypes.put("vivo:mytool",initMyTool);
Vivo's toolTypes is a HashTable (see vivo-utils.js) that contains a mapping from the DOM attribute to the initialization function.
Custom tools can certainly be placed in the vivo source files. If this is done the pattern established with the standard tools can be used. If, however, the tool is in a separate source file, vivo.js needs to be referenced in the documents <head> before this tools source file. This is so the javascript engine has a reference to Vivo before the custom tool registers itself with Vivo.
The tool's source must be in the <head>! Vivo is initialized on page load, with happens before code in the body is executed. So, if the source is referenced in the body, any custom tools defined in the document will not be created.