register log on
Knowledge base
 

Implement drill-down to another report

KB Artcile # 2654
This example demonstrates how to implement a hierarchical reporting solution by first displaying top level "parent" report (Customers) and then drilling down to details for the selected record (Orders). Parent report has a hyperlink column, which is set up to invoke a child report and pass CompanyID for the record selected by user clicking on the hyperlink. Child report has a built-in filter by CompanyID and displays only those records (orders), which correspond to the selected record in the parent report (customer). To optimize the  work flow, child report has a hyperlink "Back to Customer List", which returns the user to the same page of the parent report, from which the user navigated to the child report.

No programming is necessary to implement the above-described scenario, the solution-specific parts of both reports need to be configured.

First let's look at the parent report:



The hyperlink was enabled at design time on the column properties page (column CustomerID):



To access hyperlink request properties, click on the hyperlink edit icon on the column properties page:



On the hyperlink properties page, the hyperlink feature should be enabled, the request type should be set to HTTP Redirect (client side or server side), and the request target should specify web service API which invokes the child report. To pass security context to the child report from the parent report, property Session Token may need  to be checked.  As a design choice, property Open in New Window may be checked to display child report on a new web page, otherwise the child report is presented on the same page as the output from the parent report. 



Below is the complete content of the Request Target property, which includes the web service API call to the child report. (Note, that before using the code below, please unwrap the entire URI into a single line, eliminating line breaks, which were added in this article for readability):

<%oData.oGlobalParameter.DemoURI%>WebReport/Output/proxy.aspx?
Method=LoadReportPage&
ReportCode=DEMO7NWOrdersWithDrillUp&
CustomerID=<%alltrim(sourcedata.CustomerID)%>&
CompanyName=<%oServer.oSystem.Base64Encode(alltrim(sourcedata.CompanyName))%>&
IsPromptPageEnabled=0&
ParentReportContextToken=<%oData.oReport.cContextToken%>&
ParentReportPageNumber=<%oData.oReport.cCurrentPageNumber%>
The web service call to the child report is a simple URI, which specifies execution of the WebReport service LoadReportPage against the DEMO7NWOrdersWithDrillUp report, passing customer identifier via parameter CustomerID, and customer name via parameter CompanyName. Note that in this example, we base64 encoded the value of CompanyName to avoid possible issues with special characters included in the value of company name (the child report will decode the value of CompanyName before using it).

The other parameters in this web service call specify the following (these parameters are optional and they are added in this solution to demonstrate additional capabilities which may enhance end user experience):

  • IsPromptPageEnabled - specifies that the child report should not generate a prompt page displaying the value of CustomerID, which it uses as a filter. With value 0 passed to the child report, the value of customer identifier is read from the URI query string, applied to the filter and report generates results immediately without displaying the prompt page;
  • ParentReportContextToken - specifies a reference to the instance of the parent report, which the child report will use when a user clicks on the "Back to Customer List" hyperlink
  • ParentReportPageNumber - specifies a reference to the page number of the parent report to be opened, when a user clicks on the "Back to Customer List" hyperlink

This is what child report looks like:



Child report has two report parameters declared to maintain the values of CustomerID and CustomerName parameters passed to the report from the parent report for the entire life of the report instance:



Each parameter has an evaluatable expression defined on its properties page, which references the value passed via URI query string. For example, for the report parameter CustomerID, its properties page looks like this:



Note, that the report parameter CustomerID is initialized with the default value using an evaluatable expression, which reads the value of parameter CustomerID from query string:

<%oServer.oWeb.GetQueryStringParameter("CustomerID")%>

Another report parameter, CompanyName has a similar initialization expression, except it adds base64 decoding:

<%oServer.oSystem.Base64Decode(oServer.oWeb.GetQueryStringParameter("CompanyName"))%>

Parameters, which reference parent report instance identifier and parent report return page number are initialized with the following expressions accordingly:

<%oServer.oWeb.GetQueryStringParameter("ParentReportContextToken")%>

and

<%oServer.oWeb.GetQueryStringParameter("ParentReportPageNumber")%>


The first report parameter CustomerID is used in filter definition, which is set up from the report properties page:

 



The image below shows filter properties page: note that on this page we specified that the filter is applied against column CustomerID, and it uses the exact match criterion (as set with the operator "=") against the value provided by the report parameter CustomerID (which is initialized with the value from the URI query string parameter CustomerID, as described above):



The final modification, which needs to be done in the child report is to display at the top the name of the selected customer, which is passed to the child report from the parent report via query sting parameter CompanyName and which is maintained via report  parameter with the same name, as well as to display a hyperlink leading the the same page on the parent report, from where the request to the child report was made.

The value of the CompanyName and the hyperlink to the parent report may be placed in different parts of the report; in this solution, they are both placed in the output page header content. The output page header content may be accessed and modified at design time starting from the report properties page:


 


The header content is a simple HTML, which contains an evaluatable expression referencing report parameter CompanyName, as well as other report parameters described earlier in this article, which build the hyperlink to the parent report:

<table class="aaContainerTable">
<tr>
<td class="aaContainerCell" style="text-align:left;font-size:14pt;padding:9px 12px 12px 6px;">
<%oData.oReportParameter.CompanyName%> (<%oData.oReportParameter.CustomerID%>) - Orders
</td>
<td class="aaContainerCell" style="text-align:right;padding:9px 12px 12px 6px;">
<a class="aaTextLink2" style="font-weight:bold;"
href="<%oData.oGlobalParameter.DemoURI%>webreport/output/proxy.aspx?
method=GetReportPageByPageNumber&ReportCode=DEMO7NWCustomersWithDrillDown&
IsPromptPageEnabled=0&ContextToken=<%oData.oReportParameter.ParentReportContextToken%>&
RequestCode=Absolute&PageNumber=<%oData.oReportParameter.ParentReportPageNumber%>">
Back To Customer List
</a>
</td>
</tr>
</table>