12 Create Custom Data Action Plug-ins
You can create custom data action plug-ins to use in Oracle Analytics.
Data action plug-ins extend Oracle Analytics and enable users to select data-points in visualizations and to invoke specific actions. Oracle Analytics provides a core set of data actions that cover many common use cases, but by writing your own data action plug-in, you can extend this functionality even further.
You must have a basic understanding of the following to create custom data action plug-ins:
- JavaScript
- RequireJS
- JQuery
- KnockoutJS
Topics:
About Data Action Plug-ins and the Data Actions Framework
Data action plug-ins leverage the data actions framework to provide custom, data-driven actions that are tightly integrated into the Oracle Analytics user interface.
When a user invokes a data action, the Data Action Manager passes the request
context (for example, qualified data reference, measure values, filters and
metadata) to the data action plug-in which is responsible for handling the
request. Oracle provides four types of data action plug-ins:
CanvasDataAction
,
URLNavigationDataAction
,
HTTPAPIDataAction
and
EventDataAction
. You can extend these data action
plug-in types along with their abstract base classes to provide your own
data actions.
Data Action Categories
The data action categories include Navigate to URL, HTTP API, Navigate to Canvas, and Event actions:
- Navigate to URL: Opens the specified URL in a new browser tab.
- HTTP API: Uses the
GET/POST/PUT/DELETE/TRACE
commands to target an HTTP API and doesn't result in a new tab. Instead the HTTP status code is examined and a transient success or failure message is displayed. - Navigate to Canvas: Enables the user to navigate from a source canvas to a target canvas in either the same or a different visualization. Any filters that are in effect in the source canvas are passed to the target canvas as external filters. When the target canvas opens, it attempts to apply the external filters to the visualization. The mechanism by which external filters are applied isn't described here.
- Event Actions: Publishes an event using the Oracle Analytics event router. Any JavaScript code (for example, a third-party plug-in) can subscribe to these events and handle their custom response accordingly. This provides the maximum flexibility because the plug-in developer can choose how the data action responds. For example, they can choose to display a user interface or pass data to multiple services at once.
Both the Navigate to URL and HTTP API data action category
types can use a token syntax to inject data or metadata from the visualization into the
URL
and POST
parameters.
URL Token Replacement
HTTP data actions can replace tokens in URLs with values from the context passed to the data action. For example, qualified data reference values, filter values, username, workbook path, and canvas name.
Token | Notes | Replace With | Example | Result |
---|---|---|---|---|
${valuesForColumn:COLUMN} |
NA | Column display values from the qualified data reference. | ${valuesForColumn:
"Sales"."Products"."Brand"} |
BizTech,FunPod |
${valuesForColumn:COLUMN, separator:"/"}
|
Any token that can potentially be replaced with
multiple values supports the optional separator option. The
separator defaults to a comma (,) but you can
set it to any string. You can escape double quotes inside this
string by using a backslash (\).
|
Column display values from the qualified data reference. | ${valuesForColumn:
"Sales"."Products"."Brand"} |
BizTech,FunPod |
${valuesForColumn:COLUMN,
separationStyle:individual}
|
Any separationStyle defaults to
delimited but you can set it to
individual if the user needs to generate
separate URL parameters for each value.
|
Column display values from the qualified data reference. | &myParam=${valuesForColumn:
"Sales"."Products"."Brand"} |
&myParam=BizTech&myParam=FunPod |
${keyValuesForColumn:COLUMN}
|
NA | Column key values from the qualified data reference. | ${keyValuesForColumn:COLUMN} |
10001,10002 |
${env:ENV_VAR}
|
Supported environment variables are:
sProjectPath , sProjectName ,
sCanvasName , sUserID , and
sUserName .
|
An environment variable. | ${env:'sUserID'} |
myUserName |
Data Action Context
You can define a context that is passed when the user invokes a data action.
You define how much of the context is passed to the data action when you create the data action.
Qualified Data Reference
When the data action is invoked a qualified data reference is generated for
each marked data point using an array of LogicalFilterTree
objects. A
LogicalFilterTree
consists of multiple
LogicalFilterNode
objects arranged in a tree structure. This object
includes:
- The attributes on the row or column edges of the data layout.
- The specific measure on the measure edge that addresses each marked cell.
- The specific measure value for each marked cell.
- Key values and display values.
Environment Variables
In addition to the data and metadata describing each marked data point, certain data actions may need further context describing the environment from where the data action is invoked. Such environment variables include:
- Project Path
- Project Name
- Canvas Name
- User ID
- User Name
Data Action Code Design
You create data actions using API classes.
- There are four concrete classes of data action that inherit from the
AbstractDataAction
class:CanvasDataAction
URLNavigationDataAction
HTTPAPIDataAction
EventDataAction
- You can create new types of data actions using the data action plug-in API. See Data Visualizer SDK Reference.
- The registry of data action types is managed by the
DataActionPluginHandler
. - Code that creates, reads, edits, deletes, or invokes instances of data actions does so by publishing events.
- Events are handled by the
DataActionManager
.
Data Action Model Classes
There are several different types of data action model classes.
AbstractDataAction
This class is responsible for:
- Storing the Knockout Model (subclasses are free to extend this with their own properties).
- Defining the abstract methods that subclasses must implement:
+ invoke(oActionContext: ActionContext, oDataActionContext:DataActionContext) <<abstract>>
Invokes the data action with the passed context - should only be called by the
DataActionManager
.+ getGadgetInfos(oReport): AbstractGadgetInfo[] <<abstract>>
Constructs and returns the
GadgetInfos
responsible for rendering the user interface fields for editing this type of data action.+ validate() : DataActionError
Validates the data action and returns null if valid or a
DataActionError
if it's invalid.
- Providing the default implementation for the following methods used
to render generic parts of the data action user interface fields:
+ getSettings():JSON
Serializes the data action's Knockout Model to JSON ready to be included in the report (uses komapping.toJS(_koModel)).
+ createNameGadgetInfo(oReport) : AbstractGadgetInfo
Constructs and returns the
GadgetInfo
that can render the data action's Name field.+ createAnchorToGadgetInfo(oReport) : AbstractGadgetInfo
Constructs and returns the
GadgetInfo
that can render the data action's Anchor To field.+ createPassValuesGadgetInfo(oReport) : AbstractGadgetInfo
Constructs and returns the
GadgetInfo
that can render the data action's Pass Values field.
Subclasses may not need all of the GadgetInfo
s that the
base class provides so they may not need to call all of these methods. By separating
out the rendering of each field in this way, subclasses are free to pick and choose
the gadgets they need. Some subclasses may even choose to provide a different
implementation of these common data action gadgets.
CanvasDataAction, URLNavigationDataAction, HTTPAPIDataAction, EventDataAction
These are the concrete classes for the basic types of data actions. These classes work by themselves to provide the generic user interface for these types of data action. They can also act as convenient base classes for custom data action plug-ins to extend.
- CanvasDataAction: Used to navigate to a canvas.
- URLNavigationDataAction: Used to open a web page in a new browser window.
- HTTPAPIDataAction: Used to make a
GET/POST/PUT/DELETE/TRACE
request to an HTTP API and handle theHTTP Response
programatically. - EventDataAction: Used to publish JavaScript events through the Event Router.
Each class is responsible for:
- Implementing the abstract methods from the base class.
invoke(oActionContext: ActionContext, oDataActionContext:DataActionContext)
This method should invoke the data action by combining the properties defined in the KOModel with the specified
DataActionContext
object.getGadgetInfos(oReport): AbstractGadgetInfo[]
This method should:
- Create an array containing
AbstractGadgetInfos
. - Call individual
createXXXGadgetInfo()
methods pushing eachAbstractGadgetInfo
into the array. - Return the array.
- Create an array containing
- Providing the additional methods for creating the individual gadgets that are specific to the particular subclass of data action.
Subclasses of these concrete classes may not need to use all of the gadgets provided by their superclasses in their custom user interfaces. By separating out the construction of each gadget in this way, subclasses are free to pick and choose the gadgets they need.
DataActionKOModel, ValuePassingMode
The DataActionKOModel
class provides the base KOModel
shared by the different subclasses of AbstractDataAction
. See DataActionKOModel Class.
Data Action Service Classes
There are several different data action service classes.
DataActionManager
All communication with DataActionManager
uses
ClientEvents
.DataActionManager
which
implements event handlers for:
- Managing the set of data actions defined in the current workbook.
- Invoking a data action.
- Retrieving all the data actions defined in the current workbook.
- Retrieving all the data actions that are applicable to the current marked data points.
DataActionContext, EnvironmentContext
When a data action is invoked, the DataActionContext
class contains the context that's passed to the target.
getColumnValueMap()
Returns a map of attribute column values keyed by attribute column names. These define the qualified data reference for the data points that the data action is invoked from.
getLogicalFilterTrees()
Returns a
LogicalFilterTrees
object describing the qualified data references for the specific data points that the data action is invoked from (see theInteractionService
for details).getEnvironmentContext()
An instance of the
EnvironmentContext
class describing the source environment such as:getProjectPath()
getCanvasName()
getUserID()
getUserName()
getReport()
Returns the report that the data action is invoked from.
DataActionHandler
The DataActionHandler
class registers the various data
action plug-ins. Its API is broadly consistent with the other plug-in handlers (for
example, VisualizationHandler
).
The DataActionHandler
class provides the following public
methods:
getClassName(sPluginType:String) : String
Returns the fully qualified class name for the specified data action type.
getDisplayName(sPluginType:String) : String
Returns the translated display name for the specified data action type.
getOrder(sPluginType:String) : Number
Returns a number used to sort lists of the types of data action into the preferred order.
The DataActionHandler
class provides the following static
methods:
getDependencies(oPluginRegistry:Object) : Object.<String, Array>
Returns a dependency map covering all the registered data action types.
getHandler(oPluginRegistry:Object, sExtensionPointName:String, oConfig:Object) : DataActionPluginHandler
Constructs and returns a new instance of the
DataActionHandler
class.
DataActionUpgradeHandler
The DataActionUpgradeHandler
class is called by the
UpgradeService
when a report is opened.
The DataActionHandler
class provides two main methods:
deferredNeedsUpgrade(sCurrentVersion, sUpgradeTopic, oDataActionJS, oActionContext) : Promise
Returns a
Promise
that resolves to a Boolean indicating whether the specified data action must be upgraded (true
) or not (false
). The method decides whether the data action must be upgraded by comparing the data action instance with the data action's constructor.performUpgrade(sCurrentVersion, sUpgradeTopic, oDataActionJS, oActionContext, oUpgradeContext) : Promise
Carries out the upgrade on the specified data action and resolves the
Promise
. The upgrade itself is carried out by calling theupgrade()
method on the data action (only the specific subclass of data action being upgraded is qualified to upgrade itself).getOrder(sPluginType:String) : Number
Returns a number used to sort lists of the types of data action into the preferred order.
Data Action Code Interactions
A data action interacts with Oracle Analytics code when it creates a user interface field, and when a user invokes a data action.
Create the Field for a New Data Action Instance
This interaction starts when Oracle Analytics wants to render a data action user interface field. To do so, it:
- Creates a
PanelGadgetInfo
that acts as the parentGadgetInfo
for theGadgetInfos
that the data action returns. - Calls
getGadgetInfos()
on the data action. - Adds the data action's
GadgetInfos
as children of thePanelGadgetInfo
created in the first step. - Creates the
PanelGadgetView
that renders thePanelGadgetInfo
. - Sets the
HTMLElement
that's the container of thePanelGadgetView
. - Registers the
PanelGadgetView
as a childHostedComponent
of aHostedComponent
that's already attached to theHostedComponent
tree.This renders the data action's gadgets inside the Panel gadget in the order they appear in the array returned by
getGadgetInfos()
.
Invoke a Data Action
This interaction starts when the user invokes a data action through the Oracle Analytics user interface (for example, from the context menu on a data point in a visualization).
In response to the user interaction, the code:
- Publishes an
INVOKE_DATA_ACTION
event containing the data action's ID, theDataVisualization
that the data action is invoked from, and aTransientVizContext
object. - The
DataActionManager
handles this event by:- Obtaining the data action instance from its ID.
- Obtaining the
LogicalFilterTrees
for the marked data points in the specifiedDataVisualization
. - Constructing a
DataActionContext
that contains all the information to pass to the data action's target. - Calling
invoke(oDataActionContext)
on the data action.
Example Data Action plugin.xml File
This topic shows an example plugin.xml file for a
CanvasDataAction
data action.
Example plugin.xml
<?xml version="1.0" encoding="UTF-8"?>
<tns:obiplugin xmlns:tns="http://plugin.frameworks.tech.bi.oracle"
xmlns:viz="http://plugin.frameworks.tech.bi.oracle/extension-points/visualization"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
id="obitech-currencyconversion"
name="Oracle BI Currency Conversion"
version="0.1.0.@qualifier@"
optimizable="true"
optimized="false">
<tns:resources>
<tns:resource id="currencyconversion" path="scripts/currencyconversion.js" type="script" optimizedGroup="base"/>
<tns:resource-folder id="nls" path="resources/nls" optimizable="true">
<tns:extensions>
<tns:extension name="js" resource-type="script"/>
</tns:extensions>
</tns:resource-folder>
</tns:resources>
<tns:extensions>
<tns:extension id="oracle.bi.tech.currencyconversiondataaction" point-id="oracle.bi.tech.plugin.dataaction" version="1.0.0">
<tns:configuration>
{
"resourceBundle": "obitech-currencyconversion/nls/messages",
"properties":
{
"className": "obitech-currencyconversion/currencyconversion.CurrencyConversionDataAction",
"displayName": { "key" : "CURRENCY_CONVERSION", "default" : "Currency Conversion" },
"order": 100
}
}
</tns:configuration>
</tns:extension>
</tns:extensions>
</tns:obiplugin>
Data Action Plug-in Files and Folders
The following files and folders are used to implement data action plug-ins.
bitech/client/plugins/src/
report
obitech-report
scripts
dataaction
dataaction.js
dataactiongadgets.js
dataactionpanel.js
dataactionupgradehandler.js
obitech-reportservice
scripts
dataaction
dataactionmanager.js
dataactionhandler.js
Choose the Best Data Action Class to Extend
Before you start writing your custom data action plug-in, decide which of the existing data action classes you want to extend. Choose the data action class that provides functionality that most closely matches what you want your data action to do.
Each data action inherits from the AbstractDataAction
class
as shown in the class diagram. The class diagram shows the two abstract data action
classes (AbstractDataAction
and
AbstractHTTPDataAction
) and the four concrete data action classes
(CanvasDataAction
, URLNavigationDataAction
,
HTTPAPIDataAction
, and EventDataAction
) that you
can extend. Each data action that you provide must extend one of these classes. Which
class you extend depends on the behavior you want to implement when you invoke your data
action. Most third-party data actions are likely to extend either
URLNavigationDataAction
, HTTPAPIDataAction
or
EventDataAction
.
Regardless of which class you extend, when your data action is invoked, you're provided with metadata describing the full context of the data-point from which the data action is invoked. See Data Action Context.
AbstractDataAction Class
AbstractDataAction
is the abstract base class from which all
types of data action inherit. It's responsible for providing common functionality and
default behavior that the subclasses can use.
AbstractDataAction
All types of data action are subclasses of the
AbstractDataAction
base class. It provides the core set of
functionality common to all data actions. Unless you're creating a complex data
action that carries out multiple types of action when invoked, or you need to do
something not supported by the concrete classes, you shouldn't extend this class
directly. If you need to create a complex data action then consider extending the
concrete class that most closely provides the functionality you require.
AbstractDataAction Syntax
+ AbstractDataAction(oKOModel)
+ getKOViewModel():DataActionKOModel
+ createFromJS(fDataActionConstructor, sClassName, oDataActionKOModelUS) : AbstractDataAction
+ invoke(oActionContext, oDataActionContext)
+ getGadgetInfos(oReport) : AbstractGadgetInfo[]
+ validate() : DataActionError
+ getSettings() : Object
+ requiresActionContextToInvoke() : Boolean
+ isAllowedHere() : Boolean
# createNameGadgetInfo(oReport) : AbstractGadgetInfo
# createAnchorToGadgetInfo(oReport) : AbstractGadgetInfo
# createPassValuesGadgetInfo(oReport) : AbstractGadgetInfo
DataActionKOModel Class
Each subclass of AbstractDataAction
is likely to create its
own subclass of DataActionKOModel
. The DataActionKOModel
base class provides the following properties:
DataActionKOModel, ValuePassingMode
sID:String
The unique ID given to the data action instance.
sClass:String
The class name of this specific type of data action.
sName:String
The display name given to the data action instance.
sVersion
sScopeID
eValuePassingMode:ValuePassingMode
The mode used when passing context values. The mode can be one of the
ValuePassingMode
values (ALL, ANCHOR_DATA, NONE, CUSTOM
).aAnchorToColumns: ColumnKOViewModel[]
The columns that this data action is anchored to. This is optional. If not supplied, then the data action is available on all columns.
aContextColumns : ColumnKOViewModel[]
The columns that this data action includes in the context passed to the data action target when the data action is invoked. If not supplied, all marked columns are included in the context.
CanvasDataAction Class
CanvasDataAction
is a subclass of the
AbstractDataAction
base class. You can extend this concrete class to
provide the functionality you require.
CanvasDataAction
Use the CanvasDataAction
class to navigate from a data point in a visualization to a different canvas. The canvas you're navigating to can be in the same workbook or a different one. All the active filters for the source visualization are passed to the target canvas along with new filters that describe the Qualified Data Reference of the data point itself. If your data action needs to navigate to a different canvas then this is the class your data action should extend.
+ CanvasDataAction(oKOModel)
+ create(s)ID_sName) : CanvasDataAction
+ upgrade(oOldDataActionJS) : Object
+ invoke(oActionContext: ActionContext, oDataActionContext:DataActionContext)
+ getGadgetInfos(oReport) : AbstractGadgetInfo[]
+ validate() : DataActionError
# createProjectGadgetInfo(oReport) : AbstractGadgetInfo
# createCanvasGadgetInfo(oReport) : AbstractGadgetInfo
EventDataAction Class
EventDataAction
is a subclass of the
AbstractDataAction
base class. You can extend this concrete class to
provide the functionality you require.
EventDataAction
Use the EventDataAction
class to publish a client-side
event. You can then register one or more subscribers that listen for that event and
perform their own actions. Use this type of data action in more complex use cases
where you've a large amount of code and can benefit from keeping your data action
code loosely coupled to the code that performs the necessary actions when the data
action is invoked.
+ EventDataAction(oKOModel)
+ create(sID_sName) : EventDataAction
+ upgrade(oOldDataActionJS) : Object
+ invoke(oActionContext: ActionContext, oDataActionContext:DataActionContext)
+ getGadgetInfos(oReport) : AbstractGadgetInfo[]
+ validate() : DataActionError
# createEventGadgetInfo(oReport) : AbstractGadgetInfo
AbstractHTTPDataAction Class
AbstractHTTPDataAction
is the abstract base class that the
URLNavigationDataAction
and HTTPAPIDataAction
subclasses inherit common functionality and default behavior from.
AbstractHTTPDataAction
The AbstractHTTPDataAction
abstract base class is
shared by both the URLNavigationDataAction
and
HTTPAPIDataAction
classes. If your data action needs to open a
web page in a new browser tab you must extend
URLNavigationDataAction
. If your data action needs to invoke an
HTTP API then you should extend HTTPAPIDataAction
. You may decide
it's better to extend AbstractHTTPDataAction
directly.
+ HTTPDataAction(oKOModel)
+ validate() : DataActionError
# createURLGadgetInfo(oReport) : AbstractGadgetInfo
URLNavigationDataAction Class
URLNavigationDataAction
is a subclass or the
AbstractHTTPDataAction
base class.
URLNavigationDataAction
Use the URLNavigationDataAction
class to open a
specific URL in a new browser tab. You compose the URL using tokens that are
replaced with values derived from data points that the user selects when they invoke
the data action. The data point values are passed as part of the data action context
to the external web page. For example, create a data action invoked using a
CustomerID
column that opens a customer's web page in your
Customer Relations Management application such as Oracle Sales Cloud.
+ URLNavigationDataAction(oKOModel)
+ create(sID_sName) : URLNavigationDataAction
+ upgrade(oOldDataActionJS) : Object
+ invoke(oActionContext: ActionContext, oDataActionContext:DataActionContext)
+ getGadgetInfos(oReport) : AbstractGadgetInfo[]
HTTPAPIDataAction Class
HTTPAPIDataAction
is a subclass or the
AbstractHTTPDataAction
base class. You can extend this concrete class
to provide the functionality you require.
HTTPAPIDataAction
Use the HTTPAPIDataAction
class to invoke HTTP APIs by
creating an asyncronous XMLHTTPRequest
(XHR) and submitting it to
the specified URL. The HTTP response code enables a message to be displayed briefly
on the canvas. For example, you can customize the request to send JSON or XML
payloads to a REST or SOAP server and you can customize the response handler to show
a custom user interface.
For the HTTPAPIDataAction
data action to work, you must
add the URL of the HTTP API you want to access to your list of Safe Domains and
grant it Connect access. See Register Safe Domains.
+ HTTPAPIDataAction(oKOModel)
+ create(sID_sName) : HTTPAPIDataAction
+ upgrade(oOldDataActionJS) : Object
+ invoke(oActionContext: ActionContext, oDataActionContext:DataActionContext)
+ getGadgetInfos(oReport) : AbstractGadgetInfo[]
# createHTTPMethodGadgetInfo(oReport) : AbstractGadgetInfo
# createPostParamGadgetInfo(oReport) : AbstractGadgetInfo
Generate Data Action Plug-ins from a Template
You use a series of commands to generate a development environment and populate it with a HTTP API Data Action along with the necessary folders and files that you need to create a custom data action plug-in.
All plug-in files follow the same basic structure. You can manually create the files and folders or you can generate them from a template. The tools to do this are part of the Oracle Analytics Desktop software development kit (SDK) which is included with Oracle Analytics Desktop. See Oracle Analytics Desktop SDK Reference.
Use these commands to generate your development environment and populate it with a HTTP API data action.
Generated Folders and Files
Your newly generated data action development environment contains these folders and files:
1 %PLUGIN_DEV_DIR%\src\customdataaction
2 company-mydataaction\
3 extensions\
4 oracle.bi.tech.plugin.dataaction\
5 company.mydataaction.json
6 nls\
7 root\
8 messages.js
9 messages.js
10 mydataaction.js
11 mydataactionstyles.css
12 plugin.xml
- Line 2: The
company-mydataaction
folder is the ID that you specify. - Line 6: The
nls
folder contains the files for externalizing strings that enable your plug-in to provide Native Language Support. - Line 7: The strings in the files under the
nls\root
folder are the default strings used when translations for a requested language aren't available. - Line 8: The
messages.js
file contains externalized strings for your plug-in that you can add. - Line 9: The
messages.js
file must contain an entry that you add for each additional language that you want to provide localized strings for. You must add a corresponding folder under thenls
folder for each locale that you want to add translations for. Each folder must contain the same set of files, with the same file names as those added under thenls\root
folder. - Line 10: The
mydataaction.js
file is the newly generated JavaScript module template that provides a starting point to develop your custom data action. - Line 11: The
mydataactionstyles.css
file can contain any CSS styles that you want to add, and which your data action's user interface can use. - Line 12: The
plugin.xml
file registers your plug-in and its files with Oracle Analytics.
Extend a Data Action Base Class
Once you've chosen the subclass of data action that you want to extend and have generated the necessary folders and files, you're ready to start writing the code specific to your new data action.
You can find your newly generated data action code under
%PLUGIN_DEV_DIR%\src\dataaction
. See Generated Folders and Files for an explanation of the files and folder structure. The main file you must edit
is the JavaScript file. For example, if your custom data action ID is
company.MyDataaction
, then the file you're looking for is
%PLUGIN_DEV_DIR%\src\dataaction\company-mydataaction\mydataaction.js
.
If
your data action has additional properties that need to be stored, then you must add
them as observable properties to the Knockout Model. If your data action is given
the ID company.MyDataaction
, then the Knockout Model is called
mydataaction.MyDataActionKOModel
which is located near the top
of mydataaction.js
. By default, this Knockout Model is configured
to extend the Knockout Model used by your data action's superclass so you only need
to add additional properties to the model.
For a data action
that's extending the HTTPAPIDataAction
base class, use code similar
to the
following:
1 - mydataaction.MydataactionKOModel = function (sClass, sID, sName, sVersion, sScopeID, aAnchorToColumns, eValuePassingMode, sURL,
eHTTPMethod, sPOSTParams)
2 - {
3 - mydataaction.MydataactionKOModel.baseConstructor.call(this, sClass, sID, sName, sVersion, sScopeID, aAnchorToColumns, eValuePassingMode, sURL, eHTTPMethod, sPOSTParams);
4 - };
5 - jsx.extend(mydataaction.MydataactionKOModel, dataaction.HTTPAPIDataActionKOModel);
- Line 1: This is the constructor for your Knockout Model. It accepts the properties that the model needs to store.
- Line 3: This is the superclass's constructor, otherwise known
as the
baseConstructor
to which you pass the values for all of the properties that are handled by one of the Knockout Model's superclasses. - Line 5: This sets the superclass for this Knockout Model class.
Use code similar to the following to add a string and an array to set properties that are persisted by the data action.
1 mydataaction.MydataactionKOModel = function (sClass, sID, sName, sVersion, sScopeID, aAnchorToColumns, eValuePassingMode, sURL, eHTTPMethod, sPOSTParams)
2 {
3 mydataaction.MydataactionKOModel.baseConstructor.call(this, sClass, sID, sName, sVersion, sScopeID, aAnchorToColumns, eValuePassingMode, sURL, eHTTPMethod, sPOSTParams);
4
5
6 // Set Defaults
7 sMyString = sMyString || "My default string value";
8 aMyArray = aMyArray || [];
9
10
11 // Asserts
12 jsx.assertString(sMyString, "sMyString");
13 jsx.assertArray(aMyArray, "aMyArray");
14
15
16 // Add observable properties
17 this.sMyString = ko.observable(sMyString);
18 this.aMyArray = ko.observableArray(aMyArray);
19 };
20 jsx.extend(mydataaction.MydataactionKOModel, dataaction.HTTPAPIDataActionKOModel);
Choose Which Data Action Inherited Methods to Override
Each data action must implement various methods in order to function properly, so you only need to override those methods that implement behavior that you want to change.
Generic Methods
If you're extending one of the concrete data actions classes, for
example HTTPAPIDataAction
, then most of the required methods are
already implemented and you only need to override the methods that implement the
behavior you want to change.
This section describes the various methods and what's expected of them.
All types of data action must implement the methods that are described here.
create(sID, sName)
The create()
static method is called when you're
creating a new data action and select a Data Action Type from
the drop-down menu. This method is responsible for:
- Constructing the Knockout Model class that your data action uses.
The Knockout Model class must have the ID and name that's passed to the
create()
method along with sensible defaults for all other properties. For example, for a currency conversion data action you might want to set the default currency to convert into Dollars. The Knockout Model is the correct place to provide your default values. - Constructing an instance of your data action from the Knockout Model.
- Returning the instance of your data action.
invoke(oActionContext, oDataActionContext)
The invoke()
method is called when the user invokes your data action from the context menu for a data point in a visualization. The method passes the DataActionContext
argument which contains metadata describing the selected data points, visualization, filters, workbook, and session. See Data Action Service Classes.
validate()
The validate()
method is called on each data action
when the user clicks OK in the Data
Actions dialog. The validate()
method returns a
null
to indicate that everything is valid or a
DataActionError
if something is invalid. If there's an error in
one of the data actions in the dialog, the error prevents the dialog from closing
and an error message is displayed to the user. This method validates the name of the
data action using the this.validateName()
method.
getGadgetInfos(oReport)
The getGadgetInfos()
method is called to enable the
user interface to display data action property fields. The method returns an array
of GadgetInfos
in the order you want them to appear in the user
interface. Gadgets are provided for all of the most common types of fields (for
example, text, drop-down, password, multi-select, radio button, check box) but you
can create custom gadgets if you want more complicated fields (for example, where
multiple gadgets are grouped together, or where different gadget fields display
depending on which option you select). It's a best practice to create a method that
constructs each GadgetInfo
you want in your array, as it makes it
easier for potential subclasses to pick and choose from the
GadgetInfo
s you've provided. If you follow this best practice
there are already various methods implemented by the different data action base
classes that can return a GadgetInfo
for each of the fields that
they use in their user interfaces. If you also need one of these
GadgetInfo
s then you call the corresponding
create****GadgetInfo()
method and push its return value into
your array of gadgets.
isAllowedHere(oReport)
The isAllowedHere()
method is called when the user
right-clicks on a data-point in a visualization and the user interface starts to
generate the context menu. If a data action exists that's relevant to the selected
data-points, then the method returns true
and the data action
appears in the context menu. If the method returns false
, then the
data action doesn't appear in the context menu. Consider accepting the default
behavior inherited from the superclass.
upgrade(oOldDataActionJS)
If you're creating your first data action then don't use the
upgrade(oOldDataActionJS)
method. Only use this method after
you've created your first Knockout Model and are making significant changes to
properties for a second version of your Knockout Model. For example, if the first
version of your data action stores a URL in its Knockout Model, but you decide that
the next version will store URL component parts in separate properties (for example,
protocol
, hostname
, port
,
path
, queryString
and
bookmark
).
The second version of your Knockout Model code would request to open a data action
that had been saved with the first version of your Knockout Model code which can
cause problems. To resolve this issue, the system identifies that your current data
action code version is newer than that of the data action being opened and it calls
the upgrade()
method on your new data action class and passes in
the old data action Knockout Model (serialized to a JSON object). You can then use
the old JSON object to populate your new Knockout Model and return an upgraded
version of the JSON object. This ensures that old data action metadata continues to
work as you improve your data action code.
HTTPAPIDataAction Methods
If you're extending the HTTPAPIDataAction
class, then it
provides the following additional method that you may choose to override:
getAJAXOptions(oDataActionContext)
The getAJAXOptions()
method is called by the data action's invoke()
method. The getAJAXOptions()
method creates the AJAX Options
object that describes the HTTP request that you want your data action to make. The getAJAXOptions()
method is passed the oDataActionContext
object that contains the metadata describing the selected data-points, visualization, filters, workbook, and session. Set the AJAX Options
as required by the HTTP API you're trying to integrate with and specify the functions you want to be called when the HTTPRequest
is successful or results in an error. See the JQuery website for an explanation of the jQuery.ajax
object and its properties.
The following implementation is inherited from the
HTTPAPIDataAction
class. You need to rewrite the inherited
method to specify requirements. For example, forming the HTTP request, and the code
that handles the HTTP response. This implementation is useful as it shows the
parameters passed to the getAJAXOptions()
function, the object that
it's expected to return, and gives a clear example of how to structure the code
inside the method.
1 /**
2 * This method returns an object containing the AJAX settings used when the data action is invoked.
3 * Subclasses may wish to override this method to provide their own behavior.
4 * @param {module:obitech-reportservices/dataactionmanager.DataActionContext} oDataActionContext The context metadata describing where the data action was invoked from.
5 * @returns {?object} A JQuery AJAX settings object (see http://api.jquery.com/jQuery.ajax/ for details) - returns null if there is a problem.
6 */
7 dataaction.HTTPAPIDataAction.prototype.getAJAXOptions = function (oDataActionContext)
8 {
9 jsx.assertInstanceOfModule(oDataActionContext, "oDataActionContext", "obitech-reportservices/dataactionmanager", "DataActionContext");
10
11 var oAJAXOptions = null;
12 var oKOViewModel = this.getKOViewModel();
13 var sURL = oKOViewModel.sURL();
14 if (sURL)
15 {
16 // Parse the URL
17 var sResultURL = this._parseURL(sURL, oDataActionContext);
18 if (sResultURL)
19 {
20 // Parse the POST parameters (if required)
21 var eHTTPMethod = oKOViewModel.eHTTPMethod()[0];
22 var sData = null;
23 if (eHTTPMethod === dataaction.HTTPDataActionKOModel.HTTPMethod.POST)
24 {
25 var sPOSTParams = oKOViewModel.sPOSTParams();
26 sData = sPOSTParams.replace(dataaction.AbstractHTTPDataAction.RegularExpressions.LINE_END, "&");
27 sData = this._parseURL(sData, oDataActionContext, false);
28 }
29 oAJAXOptions = {
30 type: eHTTPMethod,
31 url: sResultURL,
32 async: true,
33 cache: false,
34 success: function (/*oData, sTextStatus, oJQXHR*/)
35 {
36 oDataActionContext.getReport().displaySuccessMessage(messages.HTTP_API_DATA_ACTION_INVOCATION_SUCCESSFUL.format(oKOViewModel.sName()));
37 },
38 error: function (oJQXHR/*, sTextStatus, sError*/)
39 {
40 oDataActionContext.getReport().displayErrorMessage(messages.HTTP_API_DATA_ACTION_INVOCATION_FAILED.format(oKOViewModel.sName(), oJQXHR.statusText, oJQXHR.status));
41 }
42 };
43 if (sData)
44 {
45 oAJAXOptions.data = sData;
46 }
47 }
48 }
49 return oAJAXOptions;
50 };
Test, Package, and Install Your Data Action
You use Oracle Analytics Desktop to test your data action from its source location before you install it.
Use an Upgrade Handler for Knockout Model Changes
For some Knockout Model changes you need to upgrade your data action plug-in using an upgrade handler.
When you're making improvements to your data action plug-in without making
changes to the Knockout Model you normally edit your JavaScript or CSS files, create a
new ZIP file, and replace the existing data action plug-in with the new ZIP file.
However, if you've made changes to your data action's Knockout Model then you might need
to change the data action VERSION
property and provide an upgrade
handler.
Decide whether you need to use an upgrade handler:
- If you rename a property in your Knockout Model.
- If you combine multiple properties into a single property in your Knockout Model.
- If you split a single property into multiple properties in your Knockout Model.
- If you add a new property to the Knockout Model and the correct default value for it depends on other values in the Knockout Model.
- If you add a new property to the Knockout Model and can provide a default value that's correct for all existing usages of your data action.
- If you remove a property from the Knockout Model because it's no longer used by your data action code.
Upgrade Data Action Plug-ins
Upgrade your data action plug-ins to improve the data action code or upgrade the metadata to enable existing data actions to work with new data action code.
Data Action Plug-in File Reference
Each data action plug-in requires a plugin.xml file and each plugin.xml file can contain any number of data actions.
Data Action plugin.xml File Example
The plugin.xml file has three main sections, tns:obiplugin
,
tns:resources
, and tns:extension
.
Example plugin.xml
This example shows a typical plugin.xml file for one data action.
1 <?xml version="1.0" encoding="UTF-8"?>
2 <tns:obiplugin xmlns:tns="http://plugin.frameworks.tech.bi.oracle"
3 id="obitech-currencyconversion"
4 name="Oracle BI Currency Conversion"
5 version="0.1.0.@qualifier@"
6 optimizable="true"
7 optimized="false">
8
9
10 <tns:resources>
11 <tns:resource id="currencyconversion" path="scripts/currencyconversion.js" type="script" optimizedGroup="base"/>
12 <tns:resource-folder id="nls" path="resources/nls" optimizable="true">
13 <tns:extensions>
14 <tns:extension name="js" resource-type="script"/>
15 </tns:extensions>
16 </tns:resource-folder>
17 </tns:resources>
18
19
20 <tns:extensions>
21 <tns:extension id="oracle.bi.tech.currencyconversiondataaction" point-id="oracle.bi.tech.plugin.dataaction" version="1.0.0">
22 <tns:configuration>
23 {
24 "host": { "module": "obitech-currencyconversion/currencyconversion" },
25 "resourceBundle": "obitech-currencyconversion/nls/messages",
26 "properties":
27 {
28 "className": "obitech-currencyconversion/currencyconversion.CurrencyConversionDataAction",
29 "displayName": { "key" : "CURRENCY_CONVERSION", "default" : "Currency Conversion" },
30 "order": 100
31 }
32 }
33 </tns:configuration>
34 </tns:extension>
35 </tns:extensions>
36
37 </tns:obiplugin>
Data Action plugin.xml File Properties Section - tns:obiplugin
The tns:obiplugin
section defines properties common to all
types of plug-ins.
Plug-in Properties
The tns:obiplugin
section defines properties common
to all types of plug-ins.
1 <?xml version="1.0" encoding="UTF-8"?>
2 <tns:obiplugin xmlns:tns="http://plugin.frameworks.tech.bi.oracle"
3 id="obitech-currencyconversion"
4 name="Oracle BI Currency Conversion"
5 version="0.1.0.@qualifier@"
6 optimizable="true"
7 optimized="false">
- Line 1: The XML declaration.
- Line 2: The opening tag for the plug-in's root
XMLElement and the declaration for the
tns
namespace that's used throughout plugin.xml files. - Line 3: The plug-in's unique ID.
- Line 4: The plug-in's default display name (used when a localized version isn't available).
- Line 5: The plug-in's version number.
- Line 6: A boolean indicating whether or not the JS/CSS can be optimized (compressed).
- Line 7: A boolean indicating whether or not the JS/CSS has been optimized (compressed).
Data Action plugin.xml File Resources Section - tns:resources
The tns:resources
section registers all of the files that
contribute to your plug-in.
Resources
1 <tns:resources>
2 <tns:resource id="currencyconversion" path="scripts/currencyconversion.js" type="script" optimizedGroup="base"/>
3 <tns:resource-folder id="nls" path="resources/nls" optimizable="true">
4 <tns:extensions>
5 <tns:extension name="js" resource-type="script"/>
6 </tns:extensions>
7 </tns:resource-folder>
8 </tns:resources>
You need to register each JavaScript, CSS, Image, and Translation
Resource File here. The section is contained within the
<tns:resources>
element and contains any number of the
following elements:
<tns:resource>
These elements are used to register a single file (for example, a JavaScript or CSS file).
<tns:resource-folder>
These elements are used to register all the files under a specified folder at the same time. For example, an image folder or the folder containing the resource files for Native Language Support.
More information on how to register each type of file is provided in the following sections.
JavaScript Files
Each JavaScript file in your plug-in must be registered with a line similar to the one shown below.
<tns:resource id="currencyconversion" path="scripts/currencyconversion.js" type="script" optimizedGroup="base"/>
Where:
- id is the ID given to the file.
Set the ID to match the JavaScript filename without the .js extension.
- path is the relative path to the JavaScript file from the
plugin.xml file. JavaScript files should be stored under your plug-in's
scripts
directory.Use all lowercase for your JavaScript files with no special characters (for example, underscore, hyphen).
- type is the type of file being registered. It must be set to
script
for JavaScript files. - optimizedGroup groups multiple JavaScript files into a single
compressed file. Third-party plug-ins must leave this set to
base
.
CSS Files
Each CSS file in your plug-in must be registered with a line similar to the one shown below.
<tns:resource id="currencyconversionstyles" path="resources/currencyconversion.css" type="css"/>
Where:
- id is the ID given to the file.
Set the ID to match the CSS filename without the .css extension.
- path is the relative path to the CSS file from the plugin.xml
file. CSS files should be stored under your plug-in's
resources
directory.Use all lowercase for your CSS files with no special characters (for example, underscore, hyphen).
- type is the type of file being registered. It should always
be set to
css
for CSS files.
Image Folders
If your plug-in has images that you need to refer to from within your
JavaScript code, then put them in a resources/images
directory
within your plug-in's directory structure and add a
<tns:resource-folder>
element to your
plugin.xml
as follows:
<tns:resource-folder id="images" path="resources/images" optimizable="false"/>
If your images are only referenced by your CSS files, then you don't
need to add this <tns:resource-folder>
element to your
plugin.xml
file. In this case, you must still add them to
the resources/images
directory so that you can then refer to
them using a relative path from your CSS file.
Native Language Support Resource Folders
Oracle Analytics implements Native Language Support. This requires developers to externalize the strings they display in their user interface into separate JSON resource files. You can then provide different localized versions of those files in a prescribed directory structure and Oracle Analytics automatically uses the correct file for the user's chosen language. You can provide as many translated versions of the resource files as needed. A Native Language Support resource folder points Oracle Analytics to the root of the prescribed Native Language Support directory structure used by your plug-in. All plug-ins that use Native Language Support resource files must have a <tns:resource-folder>
entry that looks exactly like the example below.
1 <tns:resource-folder id="nls" path="resources/nls" optimizable="true">
2 <tns:extensions>
3 <tns:extension name="js" resource-type="script"/>
4 </tns:extensions>
5 </tns:resource-folder>
See Generated Folders and Files for details about the contents of the files and the prescribed directory structure that you should follow.
Data Action plugin.xml File Extensions Section - tns:extension
For each data action you want your plug-in to provide, you must register a
data action extension using a <tns:extension>
element similar to
this:
<tns:extension id="oracle.bi.tech.currencyconversiondataaction" point-id="oracle.bi.tech.plugin.dataaction" version="1.0.0">
<tns:configuration>
{
"host": { "module": "obitech-currencyconversion/currencyconversion" },
"resourceBundle": "obitech-currencyconversion/nls/messages",
"properties":
{
"className": "obitech-currencyconversion/currencyconversion.CurrencyConversionDataAction",
"displayName": { "key" : "CURRENCY_CONVERSION", "default" : "Currency Conversion" },
"order": 100
}
}
</tns:configuration>
</tns:extension>
Where:
- id is the unique ID you give to your data action.
- point-id is the type of extension you want to register. For
data action extensions, this must be set to
oracle.bi.tech.plugin.dataaction
. - version is the extension API version that your extension definition uses (leave this set to 1.0.0).
The <tns:configuration>
element contains a JSON
string that defines:
- host.module - This is the fully qualified name of the module
containing your data action. This fully qualified module name is formulated as
%PluginID%/%ModuleName%
, where:%PluginID%
must be replaced with the plug-in ID you specified in the id attribute of the<tns:obiplugin>
element.%ModuleName%
must be replaced with the resource ID you specified in the id attribute of the<tns:resource>
element for the JavaScript file containing your data action.
- resourceBundle - This is the Native Language Support path to
the resource file that contains this data action's localized resources. If your
resource files are named messages.js and stored correctly in the prescribed
nls
directory structure, then set this property to%PluginID%/nls/messages
(where%PluginID%
must be replaced with the plug-in ID you specified in the id attribute of the<tns:obiplugin>
element at the top of theplugin.xml
file). - properties.className - This is the fully qualified class name
given to the data action you're registering. This fully qualified class name is
formulated as
%PluginID%/%ModuleName%.%ClassName%
, where:%PluginID%
must be replaced with the plug-in ID you specified in the id attribute of the<tns:obiplugin>
element.%ModuleName%
must be replaced with the resource ID you specified in the id attribute of the<tns:resource>
element for the JavaScript file containing your data action.%ClassName%
must be replaced with the name you gave to the data action class in your JavaScript file.
- properties.displayName - This property contains an object
and two further properties:
- key is the Native Language Support message key that
can be used to lookup the data action's localized display name from
within the specified
resourceBundle
. - default is the default display name to use if for some reason the localized version of the display name can't be found.
- key is the Native Language Support message key that
can be used to lookup the data action's localized display name from
within the specified
- properties.order - This property enables you to provide a hint that's used to determine the position that this data action should appear when shown in a list of data actions. Data actions with lower numbers in their order property appear before data actions with higher numbers. When there's a tie, the data actions are displayed in the order they're loaded by the system.