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:
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.
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.