Web Client Plug-in Developers Guide

Web Client Plug-in Developers Guide

Intended Audience

This document was created as a walk-through tutorial on how to create custom plug-in modules that extend the functionality of the base i2b2 Web Client.

The author(s) assume that the reader is an experienced software developer or architect who has some experience programming JavaScript and some knowledge of advanced JavaScript topics such as JSON, AJAX, and using JavaScript toolkit (APIs).

Plug-In Example #1 – Hello World

The first example plug-in is a Hello World example. This example demonstrates the steps needed to setup the directory structure, create a simple plug-in configuration file, register a plug-in with the web client framework, and have an example HTML interface loaded by the framework.

Creating a Plug-in's base directory

Your deployment of the i2b2 web client will have a directory which contains all the JavaScript code related to the i2b2 web client Framework. The default location of this directory is /js-i2b2.

This directory contains the Framework configuration file (i2b2_loader.js) and two directories (cells and hive). Within the cells directory are the directories for the core cells in addition to the plug-ins folder. Within the plug-ins folder we will create a new folder to hold our examples called "examples".

Within the examples folder create a new folder called ExampHello. We will be using the string "ExampHello" as the code that will be used to uniquely identify the plug-in from other plug-ins and cells. For our example we chose to use the abbreviation code "ExampHello" for our aptly-named "Hello World" example plug-in.

Within every plug-in directory there is an assets directory to contain all multimedia assets that are used by the plug-in. All CSS, HTML and image files are contained within this directory.

Create the directory "/js-i2b2/cells/plugins/examples"
Create the directory "/js-i2b2/cells/plugins/examples/ExampHello"
Create the directory "/js-i2b2/cells/plugins/examples/ExampHello/assets"


Registering a Plug-in with the Web Client Framework

For the Framework to be aware of our new plug-in, we must add an entry to the module loader configuration file. Within the file /js-i2b2/i2b2_loader.js is a section containing JSON-based configuration information which has the following structure:

// THESE ARE ALL THE CELLS THAT ARE INSTALLED ONTO THE SERVER
i2b2.hive.tempCellsList = [
   { code: "PM",
   forceLoading: true //    <---- this must be set to true for the PM cell!
   },
   { code: "ONT" } ,
   { code: "CRC" } ,
   { code: "PLUGINMGR" ,
   forceLoading: true,
   forceConfigMsg: {
      params: []
  }
  }
];



This JSON structure is used to register a list of cells and plug-in modules that the framework will attempt to load if the authenticated user has been authorized to use them (via the data returned from the PM cell during successful login). The above example code listing has information for registering the following cells/plug-ins (in order):

  1. Project Management Cell (forced to automatically load when the framework is loaded)

  2. Ontology Cell

  3. Data Repository Cell

  4. Plugin Viewer Module (used to manage all non-Cell plug-in modules)



Unless a custom module is going to be running as an i2b2-compliant cell, configuration options must be included in this file using the "forcing" options below:

Configuration Option

Description

forceLoading: (Boolean)

Is the module automatically loaded during framework initialization

forceConfigMsg: (Object)

This data object is automatically populated to i2b2.CELLCODE.cfg.config when the module is loaded



These options can also be used to override configuration information that is being returned to the web client framework from the Project Management Cell during login authorization.
To do so we add the following to the configuration that results in the following file with our added configuration information:

Tip

Remember to add a comma to the end of the previous configuration in the list.

 

// THESE ARE ALL THE CELLS THAT ARE INSTALLED ONTO THE SERVER
i2b2.hive.tempCellsList = [
   { code: "PM",
   forceLoading: true //    <---- this must be set to true for the PM cell!
   },
   { code: "ONT" } ,
   { code: "CRC" } ,
   { code: "PLUGINMGR" ,
   forceLoading: true,
   forceConfigMsg: {
      params: []
   }
   },
   {code: "ExampHello" ,
   forceLoading: true, //    <---- this must be set to true for all plugins
   forceDir: "cells/plugins/examples"
      params: []
   } 
];


Important

It is important to know that the name provided in the code configuration attribute will be the namespace that mustbe used by your plug-in. the code "ExampHello" resolves to an absolute namespace of thei2b2.ExampHellowithin the JavaScript VM.

Creating a Plug-in's Configuration File

For the Framework to be able to properly load our new plug-in module, we must declare which files comprise the new module. This is accomplished by creating a JSON-based configuration file within the module's root directory. For our example that would be

        /js-i2b2/cells/plugins/examples/ExampHello/cell_config_data.js


The file would have the following structure:

// This file contains a list of all files that need to be loaded dynamically
// for this module. Every file in this list will be loaded after the module's Init()
// function is called
{
   files:[ "ExampHello.js" ],
   css:[ "ExampHello.css" ],
   config: {
      // additional configuration variables that are set by the system
      short_name: "Hello World",
      name: "Example #1 - Hello World",
      description: "This plugin cell demonstrates how to register your plugin
         with the i2b2 thin-client framework and display simple HTML.",
      category: ["celless", "plugin", "examples"],
      plugin: {
         isolateHtml: false,
         html: {
            source: 'injected_screens.html',
            mainDivId: 'ExampHello-mainDiv'
         }
      }
   }
}



The configuration file has three main parts to it:

  1. A list of JavaScript files

  2. A list of HTML CSS files

  3. A configuration section.



The files and CSS configuration sections are self-explanatory. All filenames listed will be prepended the with the plug-in's base directory to generate the full file access location used by the framework in loading the files.

Important

It is important to note that all version of Microsoft Internet Explorer limit the number of dynamically loaded style sheets to a total of 31 files. The web client framework uses several style sheets and each cell or plug-in may have dynamically loaded style sheets as well.

An important best practice is to only define one CSS file in your plug-in's configuration file.

To use more than one CSS file in your plug-in, create a CSS file to subsequently load your other CSS files using the @import (file.css) command.



The configuration section contains various pieces of information that are used by the Framework. They are explained below:

JSON Configuration Variable

Description

config.short_name

Is displayed in the title tab area of the plug-in viewer's display window.

config.name

The title string that is displayed in the plug-in viewer's listing window.

config.description

The description that is displayed in the plug-in viewer's listing window.

config.category

A list of categories that this plug-in is a member of. All plug-ins must include "plugin" value. If the plug-in does not have its own backend cell then "celless" value should also be present.

config.icons

JSON object defining one or more icon files. These files must be located in the assets directory of the plug-in's base directory.

config.icons.size32x32

Filename for 32x32 pixel icon used in the plug-in listing window when in detailed view mode. (The fill must be in the plug-in's assets directory).

config.icons.size16x16

Filename for 16x16 pixel icon used in the plug-in listing window when in summary view mode. (The fill must be in the plug-in's assets directory).

config.plugin

JSON object which defines and configures the module as a plug-in.

config.plugin.isolateHtml

Boolean, should the framework isolated the plug-in's HTML an IFRAME.

config.plugin.html

JSON object that contains information about the plug-in's display HTML.

config.plugin.htm.source

Filename for the plug-in's display HTML (in the local assets directory).

config.plugin.html.mainDivId

The unique ID of the HTML Element (in the above declared source file) whose contents will be initially displayed.



Most of the information within the configuration section is used by the plugin viewer subsystem in ways that are reflected in the user interface.

 

 




Displaying HTML

The first step in the development of any plug-in module is the creation of a user interface. The i2b2 web framework eliminates the complexity of transforming simple HTML screens into an AJAX-based application.
To start, an HTML file must be created and put into the plug-in module's asset directory (/js-i2b2/cells/plugins/examples/ExampHello/assets). For our "Hello World" we will create a file called injected_screens.html and fill it with the following HTML:

<html>
   <body>
   <div id="ExampHello-mainDiv">
      This "Hello World" demonstrates how to register your plugin with the i2b2 Thin-Client framework and display some HTML.
   </div>
   <div>
      This text will not display because it is outside our targeted div
   </div>
   </body>
</html>



The text which emphasis added is what we want to display in the plug-in viewer's display window when the plug-in is selected and loaded.
The next step is to configure the plug-in (via the cell_config_data.js file) with the correct HTML file and ID for the HTML Element that contains the initial UI display.

plugin: {
   isolateHTML: false,
   html: {
   source: 'injected_screens.html' ,
   mainDivId: 'ExampHello-mainDiv' ,
   }
}



Since our configuration file has defined a CSS file to load we must create that file for the plug-in module to work properly. We will fully utilize the separate CSS file later in this document but will need to create a blank file (/js-i2b2/cells/plugins/ExampHello/assets/vwHello.css) for now.

Tip

For more information on the configuration files and in particular the plug-in configuration files please see the document called Web Client Configuration Files.



After saving all files, clearing your browser's cache (just in case) and refreshing the screen, you should see the "Hello World – Simple HTML" plug-in in the "Plugins" list window. When the listing is clicked, it should load the plug-in and display the HTML you created above.

Creating Constructor & Destructor Functions

 

Tip

Although it is not absolutely necessary, it is good practice to create constructor and destructor functions for your plug-in.



The plug-in constructor function is called after the Plugin Viewer has loaded the requested plug-in's initial HTML into the main DOM tree. When the constructor is called it is passed a reference to the DOM node that contains the plug-in's HTML.
If your plug-in contains a destructor function, it is called by the Plugin Viewer before it removes the plug-in's GUI from the main DOM tree.

Be Careful

If your destructor function does not return true then the unload process is canceled.


i2b2.ExampHello.Init = function(loadedDiv) {
   // this function is called after the HTML is loaded into the viewer DIV
   i2b2.ExampHello.view.containerDiv = loadedDiv;
   alert("Hello World! This message is from the initialization routine.");
};


i2b2.ExampHello.Unload = function() {
   // this routine should be used to save the state of the plugin so that work can
   // resume if reloaded or to release memory currently held in plugin variables.
   return confirm("Are you sure you want to unload the Hello World plugin?");
};


Plug-In Example #2 – Tabs and Drag / Drop

Starting from our Hello World plug-in it is easy to build a second plug-in that uses standard tabs display and can accept SDX drop messages. Begin building this plug-in by copying the previous plug-in example into the directory /js-i2b2/cells/plugins/ExampTabs and change the filenames to reflect the naming convention of the new plug-in, resulting in the filenames:

  1. ExampTabs.js

  2. ExampTabs.css 


The new filenames should be reflected in the cell configuration file found at:

     /js-i2b2/cells/plugins/ExampTabs/cell_config_data.js

To register the new plug-in in the module loader configuration file add the following lines: 

// THESE ARE ALL THE CELLS THAT ARE INSTALLED ONTO THE SERVER
i2b2.hive.tempCellsList = [
    { code: "PM",
    forceLoading: true // <------- this must be set to true for the PM cell!
    },
    { code: "ONT" } ,
    { code: "CRC" } ,
    { code: "PLUGINMGR" ,
    forceLoading: true,
    forceConfigMsg: {
         params: []     }    },     {code: "ExampHello" ,     forceLoading: true, // <------- this must be set to true for all plugins     forceDir: "cells/plugins/examples"          params: []     },     {code: "ExampTabs" ,     forceLoading: true,     forceDir: "cells/plugins/examples"     forceConfigMsg: {          DefaultTab: 3 // <------- define variable for later use     }    } ];