Visualize.js – Hyperlinks API

Visualize.js – Hyperlinks

In the post, we will discuss how we can handle hyperlink execution in jaspersoft reports that are embedded using visualize.js.

If you have not worked on rendering reports through visualize js , this post may not be the best place to start. You may check this one out.

As we all know, jasper hyperlink’s are of various types – report execution, reference, local / remote anchor or pages. We will look into what information do we get about the hyperlinks in the embedded reports when we click on them and how we can utilize this information to take appropriate action on the event.

As an example, we will take one of the sample report from the jasper samples that come with the installation – SalesByMonthReport. I have made a small change to this report and added a hyperlink in the page footer of the type “reference” which opens “http://helicaltech.com/” webpage.

RenderedReport1

Below is the HTML and the Java Script Code for embedding the report using Visualize JS with hyperlink handling –
—- HTML —–

<!----- JQuery,underscore js is required for this code, has been included from external resources in jsfiddle--->
<script type='text/javascript' src="http://192.168.2.141:8082/jasperserver-pro/client/visualize.js"></script>
<div id="container"> Main report Appears here</div>
<div id="container2">Drilldown Appears here</div>

 I have created 2 place holder divisions, “container” to render the “SalesByMonthReport” report. This report has a drilldown report which opens when we click on any of the months in the table. When user clicks on any of these hyperlinks, we will display the drilldown report in “container2”

— Java Script —

var reportUri = "/public/Samples/Reports/SalesByMonthReport"
visualize({
    auth: {
        name: "superuser",
        password: "superuser"
    }
}, function (v) {
   var report = v.report({ 
        resource: reportUri, 
        container: "#container", 
        params:{"startMonth": ['1'],"endMonth": ['12']},  //defaults
        linkOptions: {
       	   beforeRender: function (linkToElemPairs) {
                linkToElemPairs.forEach(showCursor);
            },
            events: {
                "click": function(ev, link){
                    console.log(link);
                  if(link.type == 'ReportExecution'){
                  		v("#container2").report({
                            resource: link.parameters._report,
                            params: {
                                monthNumber: [link.parameters.monthNumber]
                            }, 
                        });     
                  }
                  else if(link.type == 'Reference'){
                  	window.open(link.href);
                  }
                }
            }    
        },
        success:function () {
            alert('Report rendered successfully');
        },
        error: function (err) {
            alert(err.message);
        }  
    });
    
   function showCursor(pair){
           var elink = pair.element;
               elink.style.cursor = "pointer";
    }
});

  Let’s concentrate on the “linkOptions” portion of the call to the Report API. It allows you to control the behaviour of the Hyperlinks.

beforeRender: function (linkToElemPairs) {
    linkToElemPairs.forEach(showCursor);
}

  In “beforeRender”, we are just trying to change the cursor type when mouse moves over the element which has the hyperlink. I am not going into details of this code. However, we can see that there is a way to add any logic that might be required before the links are rendered.

events: {
            "click": function(ev, link){
				console.log(link);
				if(link.type == 'ReportExecution'){
					v("#container2").report({
						resource: link.parameters._report,
						params: {
							monthNumber: [link.parameters.monthNumber]
						}, 
					});     
				}
				else if(link.type == 'Reference'){
					window.open(link.href);
				}
			}
	}

  In “events”, we can define the behaviour in case of various events, mainly the click event. Inside the click event callback function, we get access to the definition of the hyperlink on which click has happened. You basically get access to all the hyperlink properties that we define at design time.
In our example, we have 2 types of hyperlinks – report execution & reference. Lets see what we get for each of these types and what action we have taken on them using the information.

Report Execution : When user would click on the link on months in the table –

Hyperlink-Reference-report

Below is the JSON we get in the “link” parameter of the click callback (“click”: function(ev, link))

Hyperlink-ReportExecution

As you see, in our code, we check for “link.type” value and then in case it is “ReportExecution”, we use “link.parameters._report” & “link.parameters.monthNumber” values to call the Report API again and display the drilldown report in “container2”.

Reference : When user would click on the hyperlink in the page footer –

Hyperlink-ReportExecution-report

Below is the JSON we get in the “link” parameter of the click callback (“click”: function(ev, link))

Hyperlink-Reference

As you see, in our code, we check for “link.type” value and then in case it is “Reference”, we use “link.href” to open the hyperlink in a new window.

So, with this, we have successfully handled 2 different types of Hyperlinks that we come across in reports. Similarly, you can also write your logic to handle the other types as per your requirement.

JS fiddle of the example : http://jsfiddle.net/b42ax3m2/63/

You may also check the below blog links for learning about – authentication, report rendering, input controls API of visualize JS.
First encounter with Visualise.js
Visualize.js – The Input Controls API

References:
Visualize JS API reference

– Shraddha
Helical IT Solutions

Visualize.js – The Input Controls API

Visualize.js – The Input Controls API

In my first blog about visualize.js, we looked at the basics, a small introduction of the API with example. The example covered 3 basic things – authentication, report rendering and sending parameters to the report. In this blog, I am planning to look into the API for the Input Controls, as those are one of the basic building blocks of the reports. What information about the input controls can we access through this API? How can it be utilized to render/display similar input controls on the embedded report?

Let’s explore this with an example –
I am taking the same report as from the previous blog as an example. It is a simple report which displays Product Sales for a selected store. It has 2 input controls – ‘State’ (id : ip_state) and ‘StoreID’(id: ip_storeid). The ‘StoreID’ cascaded on ‘State’.

Visualize.js API to access the input controls

The API gives you all the input controls defined on the report along with its metadata information including the reference to cascaded input controls, both parent/children.
API to access input controls on a report looks like

visualize({auth: {...}}, function (v) {
    var inputControls = v.inputControls({
        resource: "/public/MyReports/Test1",
        params:{"ip_state":["WA"]},
        success: renderInputControls
    });

resource – is the uri of the report for which the input controls are to be fetched.
params – provide parameter values for the input controls. This is in case of cascaded input controls, you may want to provide a specific value for input parameter for the cascaded control.
In our example above, we have passed the value for ‘State’ as “WA” and the ‘StoreID’ input control will utilize this parameter value and return the values accordingly.

What information about the input controls can we access through this API? – The input controls Array

The response to this API is a JSON Array which is an array of Input control objects. Each object gives information for a single input control. Below is the response for the sample report –

"inputControl" : [{
			"id" : "ip_storeid",
			"type" : "singleSelect",
			"uri" : "repo:/public/MyReports/Test1_files/ip_storeid",
			"label" : "Store ID",
			"mandatory" : false,
			"readOnly" : false,
			"visible" : true,
			"masterDependencies" : ["ip_state"],
			"slaveDependencies" : [],
			"state" : {
				"uri" : "/public/MyReports/Test1_files/ip_storeid",
				"id" : "ip_storeid",
				"options" : [{
						"selected" : false,
						"label" : "---",
						"value" : "~NOTHING~"
					}, {
						"selected" : false,
						"label" : "Store 2",
						"value" : "2"
					}, {
						"selected" : true,
						"label" : "Store 17",
						"value" : "17"
					}.........
				]
			}
		}, {
			"id" : "ip_state"....
			"masterDependencies" : [],
			"slaveDependencies" : ["ip_storeid"],
			...............
		}
	]
}

How can it be utilized to render/display similar input controls on the embedded report?

In the example below, I have utilised the “Options” in the API response object to display in a selection list in my HTML page. The renderInputControls() is defined as a “success” callback in the “inputControls()” API call. The report() function is invoked to render the report with default parameters.

HTML Code:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<script type="text/javascript " src="http://localhost:8081/jasperserver-pro/client/visualize.js "></script>
<div id="container ">Embedded a Sample Report</div>
<select id="stateselector"></select>
<select id="storeidselector"></select>
<div id="testreport"></div>

JavaScript Code

visualize({ auth: {..}}, function (v) {
    var inputControls = v.inputControls({
        resource: "/public/MyReports/Test1",
        params:{"ip_state":["WA"]},
        success: renderInputControls
    });
    var report = v.report({
        resource: "/public/MyReports/Test1",
        container: "#testreport",
        params: {"ip_state":["WA"], "ip_storeid": ["17
    });

    $("#stateselector").on("change", function () {
        inputControls.params({ "ip_state":[$(this).val()] })
        .run(function (data){renderInputControlStoreID(data);});
    });
    
    $("#storeidselector").on("change", function () {
        report.params({"ip_state":[$("#stateselector").val()],"ip_storeid": [$(this).val()]}).run();
    });
});

function renderInputControls(data) {
    renderInputControlState(data);
    renderInputControlStoreID(data);
}

function renderInputControlState(data) {
    var stateInputControl = _.findWhere(data, {id: "ip_state"});
   
    var select = $("#stateselector");
    _.each(stateInputControl.state.options, function (option) {
        select.append("" + option.label + "");
    });
}

function renderInputControlStoreID(data) {
    var storeidInputControl = _.findWhere(data, {id: "ip_storeid"});
    
    var select = $("#storeidselector").empty();
    _.each(storeidInputControl.state.options, function (option) {
        select.append("" + option.label + "");
    });
} 

Cascading the input controls
In above example, the function defined on change of “stateselector”, refreshes the “storiedselector” by invoking “inputControls.params()” with new value of “ip_state” to get new values for “ip_storeid”. It then invokes “renderInputControlStoreID()” to render new values in “storeidselector”.

Refreshing the Report with the new parameters
In the example, the function defined on change of “storeidselector” refreshes the report. It invokes the “report.params()” function of visualize.js with new parameter values.

Though this example is not a very good one, it covers the basic flow. The information in the API could be utilized much more effectively to dynamically embed and cascade the input controls in your native page.
Hope this gives you a good start-off though!!

References:

1) JS fiddle for the example in the report
2) http://community.jaspersoft.com/wiki/visualizejs-api-notes-and-samples

– Shraddha
Helical IT Solutions

First encounter with Visualise.js

First encounter with Visualise.js

As we all know, visualise.js is a javascript framework introduced in JasperServer 5.6, for integration of jasperserver reports & visualizations inside web applications. It is available only with commercial editions of JasperServer 5.6.

Prior to 5.6, there were 2 methods for embedding, the simple HTTP/iframe integration method and the REST web APIs. The iframe way, though simple, did not give much control and limited branding options as it accesses the jasperserver UI itself from within the iframe. It however supports integration of Adhoc/Self service BI. REST APIs provided greater control, leverage to the repository services, greater control on the look and feel. However, it meant more coding, limited interactivity. Visualise.js leverages the REST APIs of jasperServer and provides a simple javaScript API, that could be easily used along with CSS to create webpages that seamlessly integrate interactive reports, with a few lines of code.

The API ranges from basic APIs for authentication, report rendering, resource search, accessing input controls to accessing/control of report events, errors, report hyperlinks. It also provides a way to interact with the JIVE UI components which provides a way to achieve higher interactivity.

After having a look at what visualise has to offer, lets see what it takes to embed a simple report using visualise.js. Below is a code snippet that shows a javascript code that renders a report into a div tag inside the webpage. This report takes one parameter, the store id.

HTML Page contents


<script type="text/javascript" src="http://localhost:8081/jasperserver-pro/client/visualize.js"></script>
<div id="container">Embedded a Sample Report</div>
<div id="testreport"></div>

JavaScript code using visualize.js

visualize({
    auth: {
        name: "joeuser",
        password: "joeuser",
        organization: ""
    }
}, function (v) {
  // Report API
    v("#testreport").report({
        resource: "/public/MyReports/Test1",
        params:{"storeid":["19"]},
        error: handleError
    });
    //showing Error
    function handleError(err) {
        alert(err.message);
    }
});

1. Loading the visualise.js script

<script type="text/javascript" src="http://localhost:8081/jasperserver-pro/client/visualize.js"></script>

This is the script tag which loads the visualize.js script from the location where it is present on the running instance of your JasperServer 5.6 (commercial edition).

2. A HTML container for the report
The division with ID “testreport” is the container for the report. This element will be passed to the visualize.js function when a report is rendered.

3. Authentication with JasperServer
Visualise is the function in visualize.js that establishes a connection with the JRS instance which hosts the report to be embedded. Its first parameter is an object which contains the configuration information required for connectivity – the URL of the JRS instance(server) and the authentication properties (auth).
The above example only shows authentication properties. The server URL is not provided, it internally takes the same server from which we requested the visualize script.

4. Rendering the report
The code for rendering the report is present in the callback function defined in the visualize call. ‘v’ is the client to the JRS instance for which session has been established.

v("#testreport").report({
        resource: "/public/MyReports/Test1",
        params:{"storeid":["19"]},
        error: handleError
 });

As can be seen, the selector to the container element in the html (#testreport) has been passed. The parameters are pretty self explanatory. “handleError” is a function which would handle any errors generated by report API.

5. Passing parameters to the report
As seen above, the “params” key in the argument to the report function is used to pass all the parameters to the report. The value has to be an array, even for single values to be passed.

And it is done !!

Hope this gives you basic understanding about visualise.js. A few more blog posts to follow, exploring other APIs of visualise.js. Till then, happy embedding !!

Imp References –
http://community.jaspersoft.com/wiki/visualizejs-api-notes-and-samples

– Shraddha
Helical IT Solutions