Implement a custom action JavaScript function

Pentaho Schema Workbench

Part Number

In order to implement the JavaScript function, you need to create a new Pentaho plugin that injects your JavaScript functions into Analyzer. Here is an example of an analyzer_extension_plugin.xml:

<?xml version="1.0" encoding="UTF-8"?>
<plugin title="analyzer-extension">
        <static-path url="/analyzer-extension/resources" localFolder="resources"/>
         <file context="analyzer">content/analyzer-extension/resources/analyzer_extension_plugin.js</file>

This basically tells the Pentaho Server to inject the analyzer_extension_plugin.js file into Analyzer so that those functions are now available to Analyzer to call when a user clicks on a custom action link.

Here is an example analyzer_extension_plugin.js.
cv.extension = cv.extension || {};

 * report - Analyzer report definition.
 * formula - The level or measure that was clicked on.
 * ctx - All levels that intersect on the clicked on level or cell.
 * filter - Filters applied on the report. Only includes filters which includes members.
cv.extension.customHandlerOne = function (report, formula, ctx, filter) {
    var year = ctx['[Time].[Years]']; // Returns the member unique name
    if (year) 
        year = cv.util.parseMDXExpression(year); // Extract the name of the member
    var url = window.CONTEXT_PATH + "api/repos/:public:Steel%20Wheels:Country%20Performance%20(heat%20grid).xanalyzer/viewer?yearParameter=" + year;
    if (window.parent && window.parent.parent && window.parent.parent.mantle_openTab) {
        window.parent.parent.mantle_openTab("Custom One", "Custom One", url);

cv.extension.customHandlerOne_validate = function (report, formula, ctx, filter) {
    var territory = ctx['[Markets].[Territory]'];
    if (territory == "[Markets].[Japan]")
        return false;
    return true;

You must define your custom action JavaScript function under the cv.extension namespace. The name of the JavaScript function must exactly match the name you used in the AnalyzerCustomAction annotation. The function requires four parameters:

  • report: This is the Analyzer report object. You normally will not use this, but if you want to access the report XML definition to inspect the state of the current report definition, you can access report.reportDoc.
  • formula: This is either the level MDX unique name or the measure unique name, depending on what the user clicked on.
  • ctx: This is a map of all the levels on the row or column zone and their corresponding MDX members. When clicking on a cell, this map will contain all row and column levels on the report. When clicking on a level member, this map will only contain outer levels which are usually to the left or above the clicked-on level.
  • filter: This is a level map-to-filter operator-to-member array of all report filters with the exception of numeric filters like Top10 or Greater than.

The filter object is a map of levels to predicate objects. A predicate object is a map of predicate operators to operator arguments. A single level such as [Customer].[Name] may have more than one predicate operator, such as contains "John" but does not contain "Doe".

The possible operators are: EQUALS, NOT_EQUAL, BEFORE, AFTER, BETWEEN, CONTAIN, and NOT_CONTAIN. For all operators with the exception of CONTAIN and NOT_CONTAIN, the operator arguments are MDX members such as [Time].[2014]. CONTAIN and NOT_CONTAIN have string literals as operator arguments. Numeric filters such as 'Top 10 Account by Sales' are not exposed in the filter object.

As an example, assuming the user clicks in the cell, then the member, ctx, and filter arguments will look like:

ctx: Object
     [Markets].[Territory]: "[Markets].[APAC]"
     [Measures].[MeasuresLevels]: "[Measures].[Sales]"
     [Order Status].[Type]: "[Order Status].[Shipped]"
     [Time].[Years]: "[Time].[2003]"
     __proto__: Object
filter: Object
    {EQUALS:['[Product].[Trucks and Buses]','[Product].[Trains]','[Product].[Planes]']}
    {EQUALS: ['[Time].[2013]','[Time].[2014]']}

formula: "[Measures].[Sales]"

Here are a couple of helpful tips for implementing the JavaScript functions:

  • You can use cv.util.parseMDXExpression to extract the name of the member. For example, [Year].[2013] would return: 2013.
  • You can construct your own URL and then open the URL in a new PUC tab, assuming Analyzer is running within PUC with the function: window.parent.parent.mantle_openTab.