Tuesday, July 31, 2012

Using a Global JS Function across BIRT Reports

BIRT provides a scripting model that allows report customizations by implementing event handlers.  These events can be written in Java or JavaScript.  This model is described on the Eclipse Birt Site.


We have written many posts on using scripting to modify BIRT report components.  Below are just a few:

In this post we will describe one way that you can share a server side JavaScript function across reports.  Suppose that you have a JavaScript function to reverse a string like:

//external js function
function reverseMyString( MyString )
{
 var rString = "";
 for (i = 0; i < MyString.length; i++)
 {
  rString = MyString.substring(i, i+1) + rString;
 }

 return rString;
}



This function can be put in a .js file and then placed in the BIRT resource folder.  If you do not have a resource folder configured for your BIRT project, it can be set from the designer window preferences dialog.


The js file can be added to the report by selecting the general properties for the report and clicking on the add file button under Javascript Files.

The global function can now be called in the expression builder or in script.
The evaluate function within the reportContext object can also be used to evaluate your script at runtime.
var testString = "ZYXWVU";
this.text = reportContext.evaluate("reverseMyString('"+testString +"')");
Using this same method, a handle to the function can also be retrieved.
var testString = "ZYXWVU";
//Evaluate Function Name
var myfunc = reportContext.evaluate("reverseMyString");
this.text = myfunc( testString );
When writing Chart script it is important to understand that the Chart Engine’s Script Context is not the same as the reports.  The Chart Engine also does the bulk of its generation and rendering during the report engine’s render phase.  Chart script events can get access to the reportContext object by using the following script.
//get reportContext
var rC = icsc.getExternalContext().getScriptable();
Once the reportContext object is obtained you can make all of the standard calls available to it.  These include getting a report parameters values, getting or setting a global variable, retrieving a localized message or calling the evaluate function.  For example, to reverse the chart title the following script could be used.
function beforeGeneration( chart, icsc )
{
var currChartTitle = chart.getTitle().getLabel().getCaption().getValue()+"";
//get reportContext
var rC = icsc.getExternalContext().getScriptable();
var myFunc = rC.evaluate( "reverseMyString" );
chart.getTitle().getLabel().getCaption().setValue(myFunc( currChartTitle ));
}
Or you could create a global js function in your js file that takes the chart as a parameter and reverses its title like:
//external js function
function reverseMyTitle( chart )
{
    var MyString = chart.getTitle().getLabel().getCaption().getValue() + "";
    var rString = "";
    for (i = 0; i < MyString.length; i++)
    {
        rString = MyString.substring(i, i+1) + rString;
    }
    chart.getTitle().getLabel().getCaption().setValue( rString);
} 
You could then call this function in chart script as shown below.
function beforeGeneration( chart, icsc )
{
//get reportContext
var rC = icsc.getExternalContext().getScriptable();
var myFunc = rC.evaluate( "reverseMyTitle" );
myFunc( chart );
}