Drill-back Support for WebFOCUS Content Embedded in Salesforce.com

Topics:

WebFOCUS Embedded Business Intelligence (BI) solutions currently support integration between WebFOCUS and Salesforce.com (SFDC) with:

This section describes additional integration functionality that allows WebFOCUS content to drill-back into SFDC portal tabs, passing in values those tabs use to display specific Opportunities, and so on. The user interface for this feature is a SFDC portal application that contains a Visualforce tab, which displays a Visualforce page.

Configuring the Visualforce Page

The Visualforce page should be coded, as shown in the following example:

<apex:page controller="PageReferenceController">
<html>
    <head>

    </head>
<body>
<apex:form >
    <apex:actionFunction name="redirect" action="{!redirectToOppsPage}" rerender="msgs">
            <apex:param name="opps_url_param" value="" assignTo="{!opps_url}"/>                
    </apex:actionFunction>
</apex:form>

<script type="text/javascript">
        window.addEventListener("message", receiveMessage, false);
        function receiveMessage(event)
        {
        	if(typeof event.data === 'string')
        	{
            	if(event.data.indexOf('NAVIGATE') >= 0)
            		{
                		var params = event.data.split(';');
           
                		var action_tokens = params[0].split('=');
                		var url_tokens = params[1].split('=');
                		                		redirect(url_tokens[1]);
            		}
        	}
        }
    
</script>
<iframe id="wf_dashboard" src="https://server:port/ibi_apps/run.bip?BIP_REQUEST_TYPE=BIP_LAUNCH&BIP_folder=IBFS%253A%252FWFC%252F
Repository%252FRetail_Samples%252F&BIP_item=sfdc_page_for_drillback" style="width: 100%;">
        
</iframe>

<script type="text/javascript">
    function resize_iframe()
    {
    	document.getElementById('wf_dashboard').height = window.innerHeight-30;
    }
    window.onresize = function (event)
    {
    	console.log('resizing ' + window.innerHeight);
    	resize_iframe();
    }
    
    resize_iframe();
    
</script>
</body>
</html>
</apex:page>

The following section in this Visualforce page states the name of the Apex class that will get called from this page (PageReferenceController).

<apex:page controller="PageReferenceController">

The following section defines a function named redirect and states the action, which is to call another function named redirectToOppsPage.

<apex:actionFunction name="redirect" action="{!redirectToOppsPage}" rerender="msgs">

The following section defines a parameter for this Visualforce page named opps_url_param with an initial value of null, and it should be assigned to the value of opps_url, which is defined in the Apex class.

<apex:param name="opps_url_param" value="" assignTo="{!opps_url}"/>

The following section starts the definition of a JavaScript block.

<script type="text/javascript">

The following section adds an event listener to listen for messages from embedded iframes that contain content from a different origin (specifically, WebFOCUS content in this example) and executes the function receiveMessage when a message is received.

window.addEventListener("message", receiveMessage, false);

The following section starts the receiveMessage function, which has one parameter, event.

function receiveMessage(event)

The following section checks the data of the event to make sure it is a string.

if(typeof event.data === 'string')

The following section looks at that string to check if it contains the string NAVIGATE.

if(event.data.indexOf('NAVIGATE') >= 0)

The following section is the code that parses the message text. The message originates from the WebFOCUS procedure that will perform the drill-back. In the example provided, it is 'ACTION=NAVIGATE;URL='||SF_URL;.

var params = event.data.split(';');
           
                		var action_tokens = params[0].split('=');
                		var url_tokens = params[1].split('=');
                		                		redirect(url_tokens[1]);

The following section executes the redirect action defined in <apex:actionFunction name="redirect" and passes the URL to drill-back.

redirect(url_tokens[1]);

This calls the redirectToOppsPage function defined in the Apex class described in Configuring the Apex Class.

The following section defines the iframe ID and source that should run to populate the iframe.

<iframe id="wf_dashboard" src="https://server:port/ibi_apps/run.bip?BIP_REQUEST_TYPE=BIP_LAUNCH&BIP_folder=IBFS%253A%252FWFC%252FRepository%252FRetail_Samples%252F&BIP_item=sfdc_page_for_drillback" style="width: 100%;">

The following section defines another JavaScript function used to resize the iframe based on the WebFOCUS contents innerHeight.

<script type="text/javascript">
    function resize_iframe()
    {
    	document.getElementById('wf_dashboard').height = window.innerHeight-30;
    }
    window.onresize = function (event)
    {
    	console.log('resizing ' + window.innerHeight);
    	resize_iframe();
    }
    
    resize_iframe();

Configuring the Apex Class

The following Apex class is called by the Visualforce page and defines the opps_url method and the redirectToOppsPage function.

public class PageReferenceController {
    
    public String opps_url {get; set;}

    public PageReference redirectToOppsPage() {
            PageReference pageRef;
                 pageRef = new PageReference(opps_url);
                 pageRef.setRedirect(true);
                 return pageRef;  
    }

The function performs the drill-back to the URL that was set in opps_url. Specifically, it defines a page reference using the value of opps_url and returns that page reference to the Visualforce page, which is the caller of the function.

Configuring the WebFOCUS Procedure

This section provides an example of a WebFOCUS procedure that you can use as a model.

DEFINE FILE retail_samples/wf_retail_lite ADD
 OPP_ID/A255V=IF WF_RETAIL_LITE.WF_RETAIL_PRODUCT.PRODUCT_CATEGORY  EQ 'Accessories' THEN '0064C000003lIAsQAM'
 ELSE IF WF_RETAIL_LITE.WF_RETAIL_PRODUCT.PRODUCT_CATEGORY EQ 'Camcorder' THEN '0064C000003lIBCQA2'
 ELSE IF WF_RETAIL_LITE.WF_RETAIL_PRODUCT.PRODUCT_CATEGORY EQ 'Computers' THEN '0064C000003lIBHQA2'
 ELSE IF WF_RETAIL_LITE.WF_RETAIL_PRODUCT.PRODUCT_CATEGORY EQ 'Media Player' THEN '0064C000003lIBbQAM'
 ELSE IF WF_RETAIL_LITE.WF_RETAIL_PRODUCT.PRODUCT_CATEGORY EQ 'Stereo Systems' THEN '0064C000003lIBgQAM'
 ELSE IF WF_RETAIL_LITE.WF_RETAIL_PRODUCT.PRODUCT_CATEGORY EQ 'Televisions' THEN '0064C000003lIBlQAM' ELSE '0064C000003lIBqQAM'  ;

 SF_URL/A255V='https://ibi--wfdboard.lightning.force.com/lightning/r/Opportunity/'||OPP_ID||'/view' ;
 SF_POSTMESSAGE/A1024V = 'ACTION=NAVIGATE;URL='||SF_URL;
END

ENGINE INT CACHE SET ON
SET PAGE-NUM=NOLEAD
-DEFAULTH &WF_HTMLENCODE=OFF;
SET HTMLENCODE=&WF_HTMLENCODE

SET ARGRAPHENGINE=JSCHART
SET EMBEDHEADING=ON
SET GRAPHDEFAULT=OFF
-DEFAULTH &WF_STYLE_UNITS='PIXELS';
-DEFAULTH &WF_STYLE_HEIGHT='405.0';
-DEFAULTH &WF_STYLE_WIDTH='770.0';
-DEFAULTH &WF_TITLE='WebFOCUS Report';
GRAPH FILE retail_samples/wf_retail_lite
SUM WF_RETAIL_LITE.WF_RETAIL_SALES.REVENUE_US
FST.SF_POSTMESSAGE AS 'SF_URL' NOPRINT
BY WF_RETAIL_LITE.WF_RETAIL_PRODUCT.PRODUCT_CATEGORY
ON GRAPH PCHOLD FORMAT JSCHART
ON GRAPH SET AUTOFIT ON
ON GRAPH SET GRWIDTH 1
ON GRAPH SET UNITS &WF_STYLE_UNITS
ON GRAPH SET HAXIS &WF_STYLE_WIDTH
ON GRAPH SET VAXIS &WF_STYLE_HEIGHT
ON GRAPH SET LOOKGRAPH PIE
ON GRAPH SET AUTOFIT ON
ON GRAPH SET STYLE *
*GRAPH_SCRIPT

setPieDepth(0);
setPieTilt(0);
setDepthRadius(0); 
setPlace(true); 
setPieFeelerTextDisplay(1); 
setCurveFitEquationDisplay(false);
*END
INCLUDE=IBFS:/FILE/IBI_HTML_DIR/ibi_themes/Warm.sty,$
TYPE=REPORT, TITLETEXT=&WF_TITLE.QUOTEDSTRING, $
TYPE=DATA, COLUMN=N1, BUCKET=color, $
TYPE=DATA, COLUMN=N2, ALT='salesforce_redirector', TARGET='_self', BUCKET=measure, 
JAVASCRIPT=parent.parent.postMessage( \
     FST.SF_POSTMESSAGE \
     'https://ibi--wfdboard--c.cs61.visual.force.com' \
     ), 
$
TYPE=DATA, COLUMN=N3, BUCKET=tooltip, $
*GRAPH_SCRIPT

setReportParsingErrors(false);
setSelectionEnableMove(false);
*GRAPH_JS_FINAL
"pieProperties": {
    "holeSize": "65%"
},
"agnosticSettings": {
    "chartTypeFullName": "Pie_Ring"
}

*END
ENDSTYLE
END

The following section in this WebFOCUS procedure defines a variable named SF_URL, which specifies the URL format used by SFDC to display an Opportunity.

SF_URL/A255V='https://ibi--wfdboard.lightning.force.com/lightning/r/Opportunity/'||OPP_ID||'/view';

The following section defines a variable called SF_POSTMESSAGE, which is the message that will be passed to the Visualforce page event listener.

SF_POSTMESSAGE/A1024V = 'ACTION=NAVIGATE;URL='||SF_URL;

The following section defines the drill-down, which is a JavaScript drill-down.

JAVASCRIPT=parent.parent.postMessage( \
     FST.SF_POSTMESSAGE \
     'https://ibi--wfdboard--c.cs61.visual.force.com' \
     ), 

You must use parent.parent to access the parent container of the WebFOCUS content, and then the parent container of that container, which will be the topmost content.

This drill-down then calls postMessage and passes the SF_POSTMESSAGE variable content and the URL that is the originator of the Visualforce page execution.

WebFOCUS

Feedback