Actuate.com

Programming with the JSAPI

Jump to: navigation, search

The JSAPI contains several JavaScript classes that allow report content to be rendered and customized. The entry point for the JSAPI is the actuate JavaScript class. Before using this class, the page being written must contain a reference to the JSAPI located on the Actuate BIRT Viewer installation. For example:

<script type=”text/javascript”  language=”JavaScript” src=http://localhost:8900/ActuateJavaComponent/jsapi></script>

Once this reference has been added to your html or JSP page, the actuate JavaScript class’s load method can be used to load the components you wish to use. Currently, there are three supported components: viewer, parameter, and data service.

Contents

Viewer Component

The Viewer component is an interactive report viewer component that is used to display and manipulate reports and or reportlets (which are portions of a report). The component includes interactive features such as table of contents, page navigation, exporting the report to additional formats as well as enabling other interactions such as sort, filter, group, calculated columns and others for table and chart elements for a report. The following example shows a simple way to create a viewer instance in an HTML or JSP page:

<html>
    <head>
         <script type="text/javascript" language="JavaScript" src="http://localhost:8900/iportal/jsapi"></script>
    </head>
    <body onload="init();">
               <h1>Simple Viewer</h1>
                      <div id="myDivContainer" style="border-width: 1px; border-style: solid;"></div>	
               <script type="text/javascript" language="JavaScript">
                      var myViewer;
                     /*** Initialization function, called by the body's onload event.	 */

                     function init()
                     {
	   // initialize the birt library, then call createViewer as a callback.
	   actuate.load("viewer");
	   actuate.initialize( "http://localhost:8900/iportal/", null, "administrator", "", createViewer );
                     }
                     /**
	 * Function which creates the viewer.
	 * It is called as a callback to BirtLib.initialize().
                     */
                      function createViewer()
                    {
	    // instantiate a viewer object, by specifying the report file to be used and the HTML container to use.
 	   myViewer = new actuate.Viewer( "myDivContainer" );
	   myViewer.setReportName("/Mashup/QuickReport.rptdesign" );
	   // execute the viewer creation
	   myViewer.submit();
                     }
               </script>
      </body>
</html>

To embed a viewer in an HTML page the developer needs to do the following:

  • Include a reference to the JSAPI script library. A typical location for this library is http://<server_name>:<port/iportal/jsapi
  • Call the initialize method to initialize the session. Refer to Managing Security topic to understand different security schemes
  • Use the Actuate JavaScript class to load the required components such as the “Viewer” component in this example. The load method currently takes viewer, parameter, or dataservice as a parameter.
  • Use the Actuate Viewer component class to instantiate a new Viewer component. The constructor for the actuate.Viewer class takes a parameter that is the DOM ID of the DIV element that will host the viewer.
  • Associate a report design or document with the newly created component and call the submit method of the component to load the report in the viewer component.

Although in the example above, the initialization is done in the “init” method which is called on the HTML body “onload” event, it is important to note that the Actuate JSAPI is designed to work anywhere in a web page, and use of the onload event is not required. Most of the examples in this article use the event but could have easily used any valid DIV element. A DIV element example is show below.

<div id="viewer1" style="width: 600px; height: 450px;border-width: 1px; border-style: solid;">     
        <script type="text/javascript" language="JavaScript" src=" http://localhost:8900/iportal/jsapi "></script>
        <script type="text/javascript" language="JavaScript">
        function createViewer(iportalurl, username,serverurl,volume)
          {
                 var viewer = new actuate.Viewer( "viewer1" );
                 viewer.setReportName("/Public/Customers List by Country.rptdesign");
                 viewer.setWidth(600);
                 viewer.setHeight(450);
                 viewer.submit( );
           }
       actuate.load("viewer");
       actuate.initialize( "/iportal", null, null,null, createViewer );                   
       </script>
</div>

The figure below displays a screenshot of the final HTML output with the Actuate Interactive Viewer embedded in the page.

JSAPI Simple Viewer Example

The Viewer class contains many methods that can be used to customize the viewer. Some of these methods include the ability to turn off specific menu bars, enabling print and export operations, and turning on or off controls used to modify the report, including sort and grouping conditions. There are also methods that allow the developer to set the size of the viewer. For simplicity the examples above use the default options. The viewer also supports rendering reportlets which are portions of a report. For example in the above report, the pie chart is tagged in the designer with the bookmark, myChart. If the preceding code is altered as shown in the following example, only the pie chart is rendered

function createViewer()
{
	myViewer = new actuate.Viewer( "myDivContainer" );
	myViewer.setReportName("/Mashup/QuickReport.rptdesign" );
	myViewer.setReportletBookmark(“myChart”);
	// execute the viewer creation
	myViewer.submit();
}

The figure below displays a screenshot of the final HTML output with the Actuate Interactive Viewer displaying just the pie chart.
JSAPI Reportlet

The actuate.Viewer supports many methods used to configure the appearance and functionality of the viewer. Most of the appearance configurations are set using the actuate.viewer.UIoptions JavaScript class. For example, to disable the toolbar in the earlier example, the createViewer function can be changed as follows:

function createViewer()
{
	myViewer = new actuate.Viewer( "myDivContainer" );
	myViewer.setReportName("/Mashup/QuickReport.rptdesign" );
	myViewer.setReportletBookmark(“myChart”);
	var myUIOptions = new actuate.viewer.UIOptions();
	myUIOptions.enableToolBar(false);
	myViewer.setUIOptions( myUIOptions ); 
	// execute the viewer creation
	myViewer.submit();
}


The viewer also supports methods that operate on the viewer once it has been rendered. These include functions for exporting the report, exporting data, launching the table of contents or enabling the interactive viewer.

These functions can be called by adding custom buttons, hyperlinks, or events thereby allowing HTML developers to create highly customized user interfaces to interact with reports.

Currently, the JSAPI supports interactive features for chart and table elements as summarized below.

Table

  • Filter
  • Sort
  • Group
  • Aggregate
  • Hide/Show columns
  • Change column order
  • Format
  • Calculated columns
  • Conditional format

Chart

  • Filter
  • Change chart type
  • Format


The viewer component also has JavaScript classes that represent most of the report elements available within BIRT. As an example, the actuate.viewer.Chart class has methods for manipulating charts in the report. The actuate.viewer.Table class provides methods for manipulating tables. As a code example, assume you would like to display a table with a button for hiding a specific column. This can be done with the following script.

<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <script type="text/javascript" language="JavaScript" src="http://localhost:8900/iportal/jsapi"></script>
   </head>
   <body onload="init();">
       <h1>Drop Column example</h1>
       <button id="hideColumn" onclick="hideColumn();">Hide Column</button>
       <div id="myDivContainer" style="border-width: 1px; border-style: solid;"></div>	
       <script type="text/javascript" language="JavaScript">
                    var myViewer;
                    function init()
                   {
	      actuate.load("viewer");
	      actuate.initialize( "http://localhost:8900/iportal/", null, "administrator", "", createViewer );
	}
	function createViewer()
	{
	        myViewer = new actuate.Viewer( "myDivContainer" );
	         myViewer.setReportName("/Mashup/OrderDetails.rptdesign" );
	         myViewer.setWidth( 800 );
	         myViewer.setHeight( 300 );
	         myViewer.submit();
	  }
	function hideColumn()
	{
                             var element = myViewer.getCurrentPageContent().getTableByBookmark("mytable");
	         if ( element ) {
		element.hideColumn("PRODUCTCODE");
		element.submit();
	           }
	   } 
            </script>
     </body>
</html>



JSAPI Drop Column Example

In this example, we have a button that calls the hideColumn function. Within this function, we call the viewer component’s getCurrentPageContent to retrieve the currently displayed page’s content. We then call the getTableBookmark function to look for a table labeled with the “mytable” bookmark. If the table exists, the element will be an instance of the actuate.viewer.Table JavaScript class. This class has a function for hiding a column, which we use in this example. Finally, calling the submit function refreshes the table.

When using the interactive viewer, event handlers for most of the report elements can be registered as well.


Parameter Component

The Parameter component is a visual component that enables the display and collection of parameters for a given report. It provides a set of APIs to display, manipulate parameter definitions and accept parameter values that can be passed to reports prior to report execution. This component allows developers to create custom parameter pages with unique layouts for seamless integration into business applications. This component can also be used in conjunction with the viewer component to render the parameter page and report content within the same HTML (Mashup) page. The following example illustrates some of the features available with the parameter component. The figure below displays parameter defined within a given report design.

<html>
       <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<title>Viewer creation example</title>
	<script type="text/javascript" language="JavaScript" src="http://localhost:8900/iportal/jsapi"></script>
        </head>
        <body onload="init();">
	<h1>Parameter creation example</h1>
	<div id="myDivContainer" style="border-width: 1px; border-style: solid;"></div>	
	<script type="text/javascript" language="JavaScript">
          	      var myParam = null;
	       function init()
	      {
	 	actuate.load("parameter");
actuate.initialize( "http://localhost:8900/iportal/", null, "administrator", "", createParameter );
	        }
     	       function createParameter()
	      {
		myParam = new actuate.Parameter( "myDivContainer" );
		myParam.setReportName("/Mashup/ParameterExample.rptdesign" );
		myParam.submit();
	         }
	</script>
            </body>
</html>


JSAPI Parameter Creation Example

This report design has a cascaded parameter named customer_creditlimit and a string parameter named ProductName, which is nested in the My Product Group parameter group, and a date parameter that is not nested in any parameter group. The parameter component can be used to display these parameters using the following code.

This example is very similar to the viewer components creation. Notice that the load function is passed the “parameter” component name as the parameter. We have also changed the name of the callback function to createParameter. The createParameter function instantiates an instance of the actuate.Parameter JavaScript class, which takes the DOM id of the DIV element that will hold the parameter html. Within this function, we then set the report name and call the submit function to render the content. This example produces the following output.

The Parameter class has many methods that can be used to customize the parameter page. For example, by calling the setLayout function, the parameter page can be paginated.


function createParameter()
{
           myParam = new actuate.Parameter( "myDivContainer" );
           myParam.setReportName("/Mashup/ParameterExample.rptdesign" );
           myParam.setLayout( actuate.parameter.Constants.LAYOUT_GROUP );
           myParam.submit();
}


JSAPI Paginated Parameter Page

The parameter component also provides a function to specify individual DIV elements for each parameter group. For example, the following code can be used to rearrange where the parameter groups are displayed.

<html>
     <head>
               <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
              <script type="text/javascript" language="JavaScript" src="http://localhost:8900/iportal/jsapi"></script>
    </head>
    <body onload="init();">
         <h1>Parameter creation example</h1>
         <table>
             <tr>
	<td><div id="myDivContainer" style="border-width: 1px; border-style: solid;"></div></td>
	<td></td>
              </tr>
              <tr>
	<td><div id="mycreditlimitdiv" style="border-width: 1px; border-style: solid;"></div></td>
	<td><div id="myproductgroupdiv" style="border-width: 1px; border-style: solid;"></div></td>
               </tr>
            </table>
            <script type="text/javascript" language="JavaScript">
	var myParam = null;
	function init()
	{
               	       actuate.load("parameter");
	       actuate.initialize( "http://localhost:8900/iportal/", null, "administrator", "", createParameter );
	}
	function createParameter()
	{
               	        myParam = new actuate.Parameter( "myDivContainer" );
	        myParam.setReportName("/Mashup/ParameterExample.rptdesign" );
	        var myarray1 = new Array('customer_creditlimit');
	        var myarray2 = new Array('My Product Group');
	        myParam.setGroupContainer( myarray1, "mycreditlimitdiv" );
	        myParam.setGroupContainer( myarray2, "myproductgroupdiv" );
	         myParam.submit();
	    }
                 </script>
        </body>
</html>

JSAPI Parameter Creation Example

In this example, a table is used to display three different DIV elements. The first DIV element contains all parameters not in a group. The second two DIV elements contain specific parameter groups, which are set using the setGroupContainer function. This example produces the following output.


Parameter components can be linked with Viewer components within the same HTML page. This can be achieved by instantiating both the report and viewer components and linking the parameters component with the viewer component using the viewer component’s setParameters method. You will notice that the load function is used to load both components. A button has been added between the DIV elements housing each of the components that executes the runReport function. The runReport function retrieves the parameter components parameter map by calling the getParameteraMap function, which is passed to the viewer component’s setParametes function prior to submitting the viewer.

<html>
     <head>
          <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
           <title>Viewer creation example</title>
           <script type="text/javascript" language="JavaScript" src="http://localhost:8900/iportal/jsapi"></script>
      </head>
      <body onload="init();">
            <h1>Parameter/Viewer example</h1>
             <div id="myDivContainer" style="border-width: 1px; border-style: solid;"></div>	
             <button onclick="runReport()">Run Report </button>
              <div id="myViewerDivContainer" style="border-width: 1px; border-style: solid;"></div>
              <script type="text/javascript" language="JavaScript">
                 var myViewer = null;
                 var myParam = null;
                 function init()
                 {
	   actuate.load("parameter");
	   actuate.load("viewer");
                       actuate.initialize( "http://localhost:8900/iportal/", null, "administrator", "", createParameter );
                   }
                   function createParameter()
                  {
	    myParam = new actuate.Parameter( "myDivContainer" );
                        myParam.setReportName("/Public/ BIRT and Business Reports Examples/Sales By Territory.rptdesign" );
	     myParam.submit();
	 }
	 function runReport()
	 {
          	      myViewer = new actuate.Viewer( "myViewerDivContainer" );
                          myViewer.setReportName("/Public/ BIRT and Business Reports Examples/Sales By Territory.rptdesign" );
	  myViewer.setParameters(myParam.getParameterMap());
	  myViewer.submit();		
               </script>
      </body>
</html>

The parameter component also supports capturing events, which can be used for many things. For example in the preceding code, the run button could be removed and the following code entered for the parameter and viewer components.

function createParameter()
{
            myParam = new actuate.Parameter( "myDivContainer" );
            myParam.setReportName("/Public/ BIRT and Business Reports Examples/Sales By Territory.rptdesign" );
            myParam.registerEventHandler(actuate.parameter.EventConstants.ON_CHANGED, runReport );	
            myParam.submit();
}
function runReport()
{
             myViewer = new actuate.Viewer( "myViewerDivContainer" );
             myViewer.setReportName("/Public/ BIRT and Business Reports Examples/Sales By Territory.rptdesign" );
             myViewer.setParameters(myParam.getParameterMap());
             myViewer.submit();			
}


The registerEventHandler function is the only additional line, which instructs the AJAX framework to call the runReport function every time the report parameter is changed. The parameter contains many more functions that support features such as returning and modifying the actual parameter definitions, which are not covered in this whitepaper.

Data Service Component

The Dataservice component can be used to download report data from report designs, report documents, and Actuate information objects. This component also allows filters and sorters to be applied to the results.

dataService = new actuate.DataService(“http://severhost:8700/iportal” ); 
var request = new actuate.data.Request( "MyTable" ); 
request.setStartRow( 1 ); 
request.setMaxRows( 50 ); 
dataService.downloadResultSet( “/public/customers.rptdocument”, request, downloaddata_cb ); 

 function downloaddata_cb(resultSet) 
{ 
           //process the downloaded resultset here… 
 }

Mashup Example

Today, Business Mashups or composite applications are becoming popular as a mechanism to integrate and present data from multiple applications on a single web page. Well-known industry analysts such as Gartner regard Mashups in the Top 10 list of strategic technologies.

Actuate JSAPI facilitates injection of Actuate content into any Mashup page thereby integrating Actuate content with other applications for integrated workflows and contextual information. This section describes how the JSAPI facilitates the creation of Mashup pages.

Mashup pages usually don’t work in isolation but instead the components typically communicate with each other. The Actuate JSAPI Viewer component enables a developer to register event handlers to trap events that allow communication with other components in the Mashup. Currently, the viewer component supports event handlers that get triggered when the content of the viewer has changed, when the page changes, when an error occurs, or when a specific report element is selected after enabling the interactive viewer. As an example, suppose you have two reports being displayed in two viewer components within the same Mashup that you want to keep synchronized while they are displayed. If the report consumer changes the page number in viewer one, viewer two should automatically change its page to that of the first one and vice versa. The following script provides an example of how to accomplish this task.

<html>
<head>
	<script type="text/javascript" language="JavaScript" src="http://localhost:8900/iportal/jsapi"></script>
</head>
<body onload="init();">
	<h1>Sync Viewer example</h1>
	<div id="myDivContainer1" style="border-width: 1px; border-style: solid;"></div>	
	<div id="myDivContainer2" style="border-width: 1px; border-style: solid;"></div>	
	<script type="text/javascript" language="JavaScript">
   	    var myViewer1;
	    var myViewer2;
	    var viewer1Loaded = false;
	    var viewer2Loaded = false;
	    function init()
	   {
	           actuate.load("viewer");
	           actuate.initialize( "http://localhost:8900/iportal/", null, "administrator", "", createViewer );
	     }
     	    function createViewer()
	    {
	           myViewer1 = new actuate.Viewer( "myDivContainer1" );
	           myViewer1.setReportName("/Public/BIRT and Business Reports Examples/Sales By Customer.rptdocument" );
	           myViewer1.setWidth( 600 );
	           myViewer1.setHeight( 400 );
	          myViewer1.registerEventHandler( actuate.viewer.EventConstants.ON_CONTENT_CHANGED, contentChanged1 );
	          myViewer2 = new actuate.Viewer( "myDivContainer2" );
	          myViewer2.setReportName("/Public/BIRT and Business Reports Examples/Sales By Territory.rptdocument" );
   	         myViewer2.registerEventHandler( actuate.viewer.EventConstants.ON_CONTENT_CHANGED, contentChanged2 );
	         myViewer1.submit( );
	         myViewer2.submit( );
	        }
	function contentChanged1(viewer1){
	          if( viewer2Loaded ){			
                                     if( myViewer1.getCurrentPageNum() != myViewer2.getCurrentPageNum() ){
		           try{
myViewer2.gotoPage( myViewer1.getCurrentPageNum() );
			}catch( err ){
			       alert( err.getErrorMessage() );
			}
		              }
	             }
               	             if( !viewer1Loaded ) viewer1Loaded=true;
	}		
	function contentChanged2(viewer2){
	            if( viewer1Loaded ){	
                                          if( myViewer2.getCurrentPageNum() != myViewer1.getCurrentPageNum() ){
		          try{
myViewer1.gotoPage( myViewer2.getCurrentPageNum() );
			}catch( err ){
			alert( err.getErrorMessage() );
		           }
	                         }
	               }
	              if( !viewer2Loaded ) viewer2Loaded=true;
	     }
	</script>
         </body>
</html>

JSAPI Mashup Example

This example creates two viewer components and uses the registerEventHandler function to trap the content changed event. When the content change event is fired for a specific viewer component, the other viewer’s page number is updated to match. Two additional things to note is that report documents are used instead of report designs and the example uses a try catch block. The output for the example is shown below.

Views