Embedded Analytics and Interactivity
Overview
Qarbine may be embedded into your custom web applications to enhance your end user experiences. This promotes a more fluid workflow across your application and Qarbine created analyses. The user may perform interactions which drill into Qarbine generated output which in turn may allow the user to link back into your application for some other activities. End users maintain business context as they navigate pages and perform their workflows.
It uses an HTML IFrame to isolate Qarbine and the application from one another. Messages are exchanged between your application and the embedded IFrame to coordinate running analyses and handling user interactions. The web application interacts with your application and Qarbine compute nodes run within your Qarbine deployment.
Below is a simple example (./embedded/iFrameEmbeddedExample.html) used to illustrate some of these embedded features.
The example HTML file includes these scripts.
<script src="/app/lib/jquery/jquery-3.4.1.js"> </script>
<script type="text/javascript" src="js/iFrameEmbeddedHelper.js"> </script>
<script type="text/javascript" src="js/iFrameEmbeddedExample.js"> </script>
The “owning” application is the iFrameEmbeddedExample.js JavaScript code. It makes use of the helper functions within iFrameEmbeddedHelper.js. The page contents within the red rectangle above is an embedded IFrame. This isolates code between your application and the embedded Qarbine display. The helper coordinates the interactions between these two worlds.
The general sequence of events for embedded interaction is:
- Integrate the Qarbine iFrame into your web page
- Pass the template tag criteria to the helper
- Save the returned list of templates
- Some interaction occurs to run a template
- Lookup the template in the saved list
- Ask the helper to run that template optionally passing in runtime variables
- Wait to be told that the run has completed
- See the presented results
Review the example HTML and corresponding JavaScript files in ./embedded/ and ./embedded/js/ folder respectively in the /var/www/qarbine folder.
Preparation Steps
Determine your Qarbine URL
Determine the path to your Qarbine primary node URL by opening the sign on to your Qarbine application. Note the URL in the browser. For example, for the browser address below
the URL is “https://qarbine.acme.com”
Obtain an API Key
The embedded application can be configured to use an API key which takes on the permissions of the associated Qarbine Principal. Obtain an API key for the Principal to use by first opening the Administration tool. This can be done directly from the sign on page
The Administration Tool can also be accessed via the upper left hamburger menu as shown below if the signed on account has administrative privileges.
Next, activate the Principals tab.
Select the principal which reflects the desired catalog access visibility you want in your application. An example is shown below,
The right hand area populates with the principal’s properties. Confirm the principal is active.
If the principal refers to an Access Group then confirm it too is active.
Scroll down in the sign on Principal’s (i.e., endUser) property area and locate the area shown below.
Click
.
Copy the key by clicking . That value will be used by your application as the parameter highlighted in yellow below. The embed options are described in more detail below.
var embedOptions = {
account: 'apiKey',
pwd: '32dff7d…',
. . .
Note that you can restrict access based on IP address by setting the Principal property field shown below. The IP being tested is the one observed by the Qarbine endpoint service.
This setting is a CSV list of values which are IP addresses and masks commonly referred to as Classless Inter-Domain Routing (CIDR) values. Below is a table of sample CIDR mappings.
CIDR | Dotted Quad Mask |
---|---|
/8 | 255.0.0.0 |
/16 | 255.255.0.0 |
/24 | 255.255.255.0 |
/32 | 255.255.255.255 |
To restrict access to the 192.168.1.x subnet use a CIDR value of 192.168.1.0/24. A useful CIDR calculation tool is available at
Embedding Steps
Page Definition
For reference to this discussion see ./embedded/iFrameEmbeddedExample.html.
The embedded application’s general HTML page has 2 supporting elements:
- an iFrame for the presentation and
- a feedback widget.
A simple set of DOM element statements is shown below.
<div id=loadingFeedback style="margin-left:50px;margin:20px">
<b><i>Loading, please wait...</i></b>
</div>
<iframe id=iframeReportResult
style="border:1px solid gray;border-radius: 3px;"
name=qarbine height=500px width=1100px>
</iframe>
The embedded application includes the Qarbine embedded support library via
<script type="text/javascript" src="yourQarbinePath/app/js/iFrameEmbeddedHelper.js">
</script>
Installing the Embedding Support
For reference to this discussion see ./embedded/js/iFrameEmbeddedExample.js.
Once your page has been loaded (i.e., document.ready() or equivalent has been called) then the application creates a Qarbine embedded helper. The HTML page has this set of code.
$(document).ready(function() {
application = new IFrameEmbeddedExample();
application.start();
} );
The IFrameEmbeddedExample start function has
Set the qarbineServerUrlPrefix variable.
var qarbineServerUrlPrefix =
“the URL you determine from the step above”
A simple approach is to use
Specify the result widget options you would like. A subset example is shown below with more details following.
var reportWidgetOptions = {
allowAll: false,
canRunReportTemplate: true,
canEditResultProperties: false,
canBrowseResultProperties: false,
useWholePageWidth: true
};
Define the embedded options. These are discussed shortly.
var embedOptions = {
owner: this,
account: 'apiKey',
pwd: 'YOUR_API_KEY',
// Set path.
serverUrlPrefix: qarbineServerUrlPrefix,
//imageUrlPrefix: '/app/', // The default is '/app/'.
// Widgets and their options.
reportWidgetOptions: reportWidgetOptions,
iframeName: 'qarbine',
loadingFeedback: '#loadingFeedback',
cssRemoveBorderDecorations: false,
cssAdjustments: [ ],
// Set callbacks.
handleEmbeddedIsReady: this.handleEmbeddedIsReady.bind(this),
handleGetTaggedTemplatesReply:
this.handleGetTaggedTemplatesReply.bind(this),
handleRunTemplateReply: this.handleRunTemplateReply.bind(this),
};
It is important to update the ‘pwd’ option value based on the Administration tool interaction.
Set the helper’s options.
this.helper.setOptions(embedOptions);
Start the helper
this.helper.start();
The list of embed options is described below.
Field | Description |
---|---|
owner | The application that contains the helper. |
account | Use ‘apiKey’. |
pwd | The Qarbine API key from the Administration tool. |
serverUrlPrefix | The URL for the Qarbine primary node. |
imageUrlPrefix | The subfolder from the serverUrlPrefix.Prefix the image URL path which is, by default, relative in nature for the Qarbine application configuration because the main page may be on a different host than where our images live. |
reportWidgetOptions | The report widget options as described below. |
iframeName | The HTML name of the iFrame container. These MUST be unique on the page. |
loadingFeedback | The optional jQuery selector for the DOM element to show and then hide while performing requests. |
cssRemoveBorderDecorations | Set to true to remove both the border and the report result page shadow. This is useful when several IFrames are part of an overall dashboard page. |
cssAdjustments | A list of CSS adjustments. The elements are each an array with jQuery selector, css() argument 1, and argument 2. |
handleEmbeddedIsReady | Called when the helper has been set up and is ready to go. |
templateTags | The optional list of component tags to match. |
allTemplateTagsMustMatch | Boolean indicating whether components must have all of the tags to be deemed a match. |
handleGetTaggedTemplatesReply | Callback used when the helper’s getTaggedTemplates(templateTags, allMustMatch) function is called. |
handleRunTemplateReply | Callback used when the helper’s runTemplate(someTemplate, displayOptions) function is called. |
handleGetCheckedCellIdentifiers Reply | Callback used when the helper’s getCheckedCellIdentifiers(additionalCssClass) is called. |
handleCheckboxClickedReply | Callback used when the user changes the state of a checkbox emitted from the HTML checkbox custom cell.The identifier, class, and checkbox boolean state are passed to the function. The identifier value is prefixed by ‘cc_’. The application may wish to ask for all peer checkboxes by calling getCheckedCellIdentifiers with a cssClass discriminator argument. |
The example JavaScript code then sets some DOM variables.
Short Interaction Example
Open the page at https://your.host.name/embedded/iFrameEmbeddedExample.html
Wait for the web page to start.
Choose an option from the Examples drop down menu.
The selection runs and the result is shown.
Next,choose an option from the second drop down menu.
This selection runs the chosen template and shows the results.
The example JavaScript embed options has
templateTags: ['demo'],
If at this point you have defined some of your own templates, then simply save them with the ‘demo’ tag. They will then be runnable from within the example embedded example page. Refresh the page to have them appear in the drop down option list, choose one, and see the analysis result.
Running a Template
The example page uses a drop down for the user to make a selection. There are cases where the application development team wants to run a specific template because of the application context.
When it is time to run an analysis there are 2 primary styles of running analysis templates. The first is to reference the component using its storage path as shown below.
var fullPath = 'ReportTemplate`q_catalog|qf_example/Hello world';
var options = null;
var variables = null;
this.helper.runTemplateAt(fullPath, options, variables);
Note the first line above has a string containing a tick mark after ReportTemplate which is enclosed in single quotes.
A Qarbine component can be referenced using its encoded full path- much like a file directory path. This path can be obtained within the editors by clicking on the icon noted below.
The icon appears in several other places including the Catalog Tool’s detail section shown below.
A sample path for the component named “Hello world” in the catalog folder displayed as “example” is encoded as the string
The second style of running a template is when you have a stub template object such as when a list of templates is retrieved using the tag filtering described below. That set of statements is.
var options= null;
var variables = null;
this.helper.runTemplate(someTemplate, options, variables);
The differences between the two are
runTemplateAt(fullPath, …)
Versus
runTemplate(someTemplate, …)
A discussion of the options and variables parameters is described in more detail below.
Pagination and Page Display Options
The options argument to runTemplate() has the following fields which control the formatting of the results:
Format Setting | Comment |
---|---|
pageByPageNavigation | Display a single page at a time and use the arrow buttons to traverse the output pages. |
showPageHeadersAndFooters | Include the page footers and headers in the output display. |
showFillerLines | If showPageHeadersAndFooters is true then include the white space running downward to each page footer. |
showEndOfPageLine | If pageByPageNavigation is false then display a dashed line indicating a page break. |
Templates may set specific options or defer to the signed on user’s (Principal’s) preferences. The values can be either:
- null or "p" to defer to the preference of the template,
- "n" for explicitly 'no' (false also works), or
- “y” for explicitly 'yes' (true also works).
These may also be overridden when called to run in an embedded fashion. Here is the original template with its page by page navigation set to true.
The second page shows.
Rather than have the analysis results display on a page by page basis, the embedded run request may specify:
{
pageByPageNavigation: false,
showFillerLines: false,
showEndOfPageLine: false,
showPageHeadersAndFooters: false
}
The newly generated result looks like the following.
Note the template’s page header, page footer and page filler lines have all been suppressed.
Result Widget Presentation Options
The embedOptions passed to the helper during setup includes a variety of options which are propagated using the statement
this.helper.setOptions(embedOptions);
The reportWidgetOptions within the embedOptions includes some high level flags:
- noToolbar (default is false)
- allowAll (default is true), and
- useWholePageWidth (default is true).
The useWholePageWidth is used in conjunction with the template page layout width. Consider a template with the properties below.
With useWholePageWidth of false the output uses the template’s page layout’s width. The result is the pale yellow background to the right.
With useWholePageWidth of true the output is adjusted as shown below.
When designing template care must be taken when the results are to be exported to PDF or printed. The yellowish right hand side is a cue indicating where a standard page edge may be for example.
The embedOptions also contains reportWidgetOptions which controls the toolbar display. For example, all options may be presented using “allowAll: true”. The result is shown below.
Alternatively, a subset of objects may be presented as shown below.
These reportWidgetOptions toolbar icons and embedded flags are described below.
Icon and Flag | Action |
---|---|
| Run the template again. Templates can be programmatically run by your application per the discussion above.The default is true. |
| Prompt to choose on what compute node to perform the run.The default is true if at appropriate Qarbine feature level. |
| For the result, Save and Save as.The default is true. |
| Either edit or browse the result properties. |
| Opens the view options which apply on subsequent runs. |
| Page navigation. These are grayed when turned off and the complete result is shown.The default is false. |
| Find and Find next.The default is true. |
| Zoom out, zoom reset, and zoom in.The default is true. |
| Export the result.The default is false. |
| Print the result.The default is true. |
| Enable AI Assistant interaction with the result. This can be for the selections, current page, or all of the pages. |
| Presents a dialog to select a previously displayed result. A sample dialog is shown below. |
Embedding Tips
Getting the List of Templates
This is one option for embedding reporting functionality into applications. Within your application either the user or your application can indicate which templates you want retrieved from the catalog. Catalog component visibility is based on the account associated with the API key in the helper’s options.
The embedded helper’s options has a field handleGetTaggedTemplatesReply. This is a callback to receive the template list reply. An example option value is
handleGetTaggedTemplatesReply:
this.handleGetTaggedTemplatesReply.bind(this),
The simplest handleTaggedTemplatesReply function looks like this.
IFrameEmbeddedExample.prototype.handleGetTaggedTemplatesReply = function (taggedTemplates)
{
this.taggedTemplates = taggedTemplates;
}
The templates have a name, inFolderCollection, and inPath fields. A full sample is shown below.
A handleTaggedTemplatesReply function which formats a SELECT dropdown is shown below.
IFrameEmbeddedExample.prototype.handleGetTaggedTemplatesReply = function (taggedTemplates)
{
this.taggedTemplates = taggedTemplates;
var html = '<option>...</option>';
var ndx = 0;
for (var report of this.taggedTemplates)
{
html += '<option value=' + ndx + '>' +
report.name + '</option>';
ndx++;
}
this.jTaggedTemplates.html(html);
}
One way to initiate the retrieval request is shown below which uses the templateTags and allTemplateTagsMustMatch from the original helper options given to helper.setOptions().
this.helper.getTaggedTemplates();
You can also explicitly pass those 2 arguments as shown below,
var templateTags = [‘tag1’, ‘tag2’];
var allMustMatch = true;
this.helper.getTaggedTemplates(templateTags, allMustMatch);
An application can set a “changed” event callback for the dropdown such as shown below.
IFrameEmbeddedExample.prototype.choseTaggedTemplate = function (jEvent)
{
var val = this.jTaggedTemplates.val();
if (val == null)
return;
if (val == '...')
return;
var ndx = parseInt(val);
var someTemplate = this.taggedTemplates[ndx];
var options = null;
var variables = null;
this.helper.runTemplate(someTemplate, options, variables);
}
When the analysis run completes the handleRunTemplateReply callback is made.
Passing in Runtime Values
Overview
Many times an application presents data and the viewing user wants some more information related to one of the presented objects. The application developer can provide pop up menu options, navigation links, and buttons to support the user interaction with a particular object. In these cases there are likely Qarbine analysis templates which perform the analysis and all that is needed is the business context to run them. The context is usually a particular data object within the application.
To integrate this interaction within your application:
- identify the desired template components
- for each component determine what runtime values need to be passed in. This could be the object ID or a combination of values for example. The values can be used by queries or template formulas.
Many of the examples discussed below are accessible as shown below.
Using a Data Retrieval Formula with a Variables
A component may require a runtime value for its data retrieval query or to perform some other analysis such as a “what if the rate was X?”. The runtime value may be the data to report upon itself as well. There are many variations possible. Below is an example of a function which passes in the data to be reported upon.
IFrameEmbeddedExample.prototype.passInVariables = function ( )
{
var fullPath = 'ReportTemplate`q_catalog|qf_example/Hello world with passed data';
// Build a list of JSON objects to transfer.
var reportData = [
{name: 'Sylvester', _class: 'Cat'},
{name: 'Jaws', _class: 'Fish'},
{name: 'Snoopy', _class: 'Dog'}
];
var variables = {};
// Save the passed in data as a variable named 'reportData'.
// The variables are passed into the report execution machinery.
variables.reportData = reportData;
var options = {};
this.helper.runTemplateUsing(fullPath, options, variables);
}
The template’s properties are shown below.
Notice the main data retrieval uses a formula, instead of a database query, which in this case is just the ‘reportData’ variable value. The main data retrieval must always return a list of objects. If your intended template is designed to perform analysis on a single object, then create a list containing that object. More complex macro formulas are possible. Sample output for this example is shown below.
Overriding the Main Data Source
To provide additional template reusability a template’s main data retrieval can be completely overridden by passing in an element list. This is done using the special variable named ‘templateRootData’. An example of this is shown below.
IFrameEmbeddedExample.prototype.passInRootData = function ( )
{
var fullPath = 'ReportTemplate`q_catalog|qf_example/Hello world with passed data';
var variables = {};
var varName = 'templateRootData';
variables[varName] = [
{name: 'Hissy', _class: 'Snake'},
{name: 'Nessy', _class: 'Monster'},
{name: 'Beauty', _class: 'Horse'}
];;
var options = {};
this.helper.runTemplateAt(fullPath, options, variables);
}
Recall the template definition has inner data retrieval using a formula “@reportData. Whatever the main data retrieval is it is overridden and the passed in data is used. This avoids redundant data retrievals and associated compute, network, and other costs. Running the passInExample function results in the following output.
Using Complex JSON Objects
The examples above used simple JSON objects. With Qarbine though you can pass in JSON objects with very deep and wide data structures. This is no different than Qarbine’s handling of those same data structures that may be returned from your data source queries or REST requests. Bear in mind that some browsers may limit the size of the JSON strings being transmitted.
Using JavaScript Business Objects
The JSON data objects processed by many analysis templates are simple object structures with keys and values. Depending on your Qarbine feature level, the data objects processed by the analysis templates may be JavaScript objects with attached behaviors (methods\functions). These objects and their behaviors would be the same ones used by your application code. There is no reinventing the wheel or other painful experience. This requires the following:
- The data list elements passed to Qarbine have a “_class” field corresponding to the JavaScript class name
- The template definition includes the Qarbine resource(s) containing the necessary supporting JavaScript code.
The availability of this feature is based on the Qarbine edition and version.
Consider the template named as shown below
It references a resource containing the JavaScript code with the supporting functions.
A snippet of the resource code is shown below to give you an idea of its contents.
class Cat extends Animal
{
constructor()
{
super();
}
sound( )
{
return “meow";
}
. . .
The analysis template has a layout including the sections shown below.
Note the last column. It has a label “Sound” on the group header. On the body the “sound” function is called for each list element. For a Cat, “meow” is returned. For a Dog, “bark, bark”, etc. Your methods can certainly be more complex and you can pass arguments as well ;-)
Below is example code to pass in application data and have the analysis use JavaScript business objects during processing.
IFrameEmbeddedExample.prototype.passInExampleWithClass = function ( )
{
var fullPath = 'ReportTemplate`q_catalog|qf_example/Hello world with passed data and resource';
var reportData = [
{name: 'Sylvester', _class: 'Cat'},
{name: 'Jaws', _class: 'Fish'},
{name: 'Snoopy', _class: 'Dog'}
];
var variables = {};
variables.templateRootData = reportData;
variables.classInstantiating = true;
var options = {};
this.helper.runTemplateAt(fullPath, options, variables);
}
The result of running this data is shown below.
Using a Data Source with Query Variables
Another style of passing in runtime values is for the variables to be used by the data source retrieval query. Below is an example which uses the simple substitution pattern of “@storeLocation”.
db.sales.aggregate([
{$match : {storeLocation: @storeLocation,
"saleDate":{"$gte": ISODate('2013-01-01T05:00:00Z'),
"$lte": ISODate('2013-12-31T23:59:59Z')}}},
{ $sort: { saleDate:1} },
{$project: {_id:0, couponUsed: 0,
storeLocation: 0, purchaseMethod: 0} },
{$limit: 30}
])
More complex substitutions can use the macro language expressions which are delimited by
“[! ... !]”
For example, you can convert an array of objects into a CSV string usable in a query such as in the example below.
db.animals.find( { type: {$in: [! listWith("cat", "dog") !] } } )
.sort( {_class: 1} )
Qarbine recognizes JavaScript arrays, strings, booleans, and numbers.
Summary Report with a Detail Drill Down
There are times when you want several independent but related reports to be navigated interactively. Some use cases are known as “drill downs”. For example, there may be a high level analysis listing customers and overall balances. This may provide a drill down option to run a more detailed analysis on a single account. The account ID from the summary analysis can be used to drive the data retrieved for the second analysis. Additional variables may be passed in as well to further drive the type of analysis that takes place.
The primary report can be run via code such as is shown below.
IFrameEmbeddedExample.prototype.exampleDrillDown = function ( )
{
var fullPath = 'ReportTemplate`q_catalog|qf_example/Sales count by store in 2013 master';
this.helper.runTemplateUsing(fullPath);
}
Sample output is shown below.
This template uses the button custom cell for drilling into the details of a store location. The availability of custom cells may vary by edition and version. Clicking on the Austin line’s button runs the drill down template as shown below.
This style of drill down is easily accomplished with Qarbine. The data source behind the template performs an aggregation of the number of orders in each store for the year 2013. The store location field happens to be ‘_id’. The button custom cell is used for the drill down interaction. The cell formula is,
componentAction('run', 'template',
'ReportTemplate`q_catalog|qf_example/Sales in @storeLocation for 2013 detail',
null,
'storeLocation', #_id,
'bypassIfHaveAllValues', true)
The second argument above can be obtained when editing the template by clicking the toolbar button highlighted below.
The referenced drill down template was designed with a supporting prompt to obtain a storeLocation value. When run the prompt shows the following.
This is a very simple Prompt component. It has a single element which uses a list widget. The data for the list widget is obtained from a Data Source in the Qarbine catalog via
dataSourceData("DataSource`q_catalog|qf_example/Store locations")
Reviewing that Data Source shows its original query is simply,
db.sales.aggregate([
{$group: {_id: "$storeLocation",} },
{$sort: {_id: 1} },
{$project: {storeLocation: "$_id", _id: 0} }
])
In the drill down template the storeLocation variable value is used by its referenced Data Source in its query as shown below.
db.sales.aggregate([
{$match : {storeLocation: @storeLocation,
"saleDate":{"$gte": ISODate('2013-01-01T05:00:00Z'),
"$lte": ISODate('2013-12-31T23:59:59Z')}}},
{ $sort: { saleDate:1} },
{$project: {_id:0, couponUsed: 0, storeLocation: 0,
purchaseMethod: 0} },
{$limit: 30}
])
Since our main report result is going to directly pass in the storeLocation value, the button’s action parameters include the bypassIfHaveAllValues value of true. Clicking on Austin’s
button runs the drill down analysis for that store location..
Qarbine Prompt Interactions
Qarbine Template can refer to Prompt components to obtain runtime values. These are basically no-code-like dialog prompters presented to the user. The template referenced below contains a reference to a prompt component.
IFrameEmbeddedExample.prototype.exampleWithPrompt = function (storeLocation)
{
var fullPath = 'ReportTemplate`q_catalog|qf_example/Sales in @storeLocation for 2013 detail';
var variables = {};
variables.bypassIfHaveAllValues = false;
var options = {};
this.helper.runTemplateAt(fullPath, options, variables);
}
Running the template presents the dialog to the user. Note that you can also apply some styling to these dialogs so that their look is similar to your application. See the Prompt Designer document for details.
Sample output is shown below.
Passing in Variables vs. Using Prompts
There are times when rather than prompting the user using a dialog for a value, the application wants to pass it in directly and bypass the dialog. We want to avoid defining one template with a prompt reference and basically a copy of it with a different name without the prompt reference. That’s a maintenance nightmare. Below is an example where the storeLocation value is passed in and the prompt bypassed.
IFrameEmbeddedExample.prototype.example10 = function ( )
{
var fullPath = 'ReportTemplate`q_catalog|qf_example/Sales in @storeLocation for 2013 detail';
var variables = {};
// The variables will be passed into the report execution machinery.
// The target template requires a storeLocation variable which is usually prompted for.
// Here we pass it in directly and bypass the user prompt.
variables.storeLocation = 'London';
variables.bypassIfHaveAllValues = true;
var options = {};
this.helper.runTemplateUsing(fullPath, options, variables);
}
Sample output is shown below.
Analysis Results and Application Interactions
Overview
Qarbine can generate a variety of interactive web pages. Some of this capability is through hyperlinks and pop up menus. Another way is through custom cells which are Qarbine provided or developer written extensions. Qarbine generated pages can replace the tedious manual coding of some application content. The output also includes various printing and exporting options.
Button Clicks
Overview
Some workflows display reports with business object context and from those the user wants to perform some interactions on those presented objects. Qarbine can generate these pages and provide HTML buttons for various interactions. This improves developer productivity and provides a faster turn around for end user application requests.
Defining the Template
There is a custom cell which presents an HTML button on the webpage result. Below is a simple example.
To add this custom cell to a template, click a free spot in the template’s body line and choose the drop down below located in the right hand side of the Template Designer.
Select the custom cell highlighted below.
You can drag and drop the custom cell or click
The cell is added to the template. The right hand side shows the custom cell’s properties and main options.
A sample cell formula to provide a unique value is shown below.
When the button is clicked the doSomething() function is called with the arguments 12, “Hello”, and the current data object’s_id value. With the “tool” argument the function is expected to be defined by the options.owner object (basically your application). Your application can then perform some action in the callback.
Qarbine related actions could be to then run another analysis template in a secondary embedded widget area. This is one way to create your own set of interrelated template results in a dashboard which are updated based on the user’s interactions with your widgets or those presented in a Qarbine result. Likewise you may be embedding another summary visualization BI tool in your application and have user interactions with it cause an embedded Qarbine template to run and vice versa.
Embedded Interaction
A simple example application function is shown below.
IFrameEmbeddedExample.prototype.doSomething = function (varyingArgs)
{
// Used to demonstrate callbacks into the iFrame's owner.
alert('In doSomething(). Arguments: ' +
JSON.stringify(Array.from(arguments)) );
}
A template can be run in an embedded fashion and the results include HTML buttons. A sample result line is shown below.
The user can click on the button to perform an action. The click interaction propagates over to your application function to perform some action. In this case a simple alert is shown.
Popup Menu Interaction
Overview
Templates can include pop up menu options for result cells as well that can:
- run another component,
- open another component,
- call a JavaScript function in your application (similar to buttons above),
- perform a Google search, or
- open another browser tab for a given URL.
The information behind icon in the button discussion above is shown below.
Cell Drill Down Actions
Run or open another component by specifying the component's class, folder location and name. There are 3 argument slots available for these 3 values. These values may be specified separately, or in combination as shown below.componentAction(runOrOpen, class`fullFolderPath/name, null, null, key1, value1, ...)
componentAction(runOrOpen, class, fullFolderPath/name, null, key1, value1, ...)
componentAction(runOrOpen, class, fullFolderPath, name, key1, value1, ...)
Run a retrieved catalog object. This can be used for catalog reports.componentObjectAction(runOrOpen, catalogObject, key1, value1, ...)
Open a dialog with the given title along with the key\value pairs listed.dialogAction(title, key1, value1, ...)
Perform a JavaScript function. The function to call is located by the targetObjectName. This may be 'window' or a specific global variable name. Use 'tool' for embedded cases. Next, the name of the function in that target object is specified by fnName. Any arguments to that function are then provided.javaScriptAction(targetObjectName, fnName, value1, ...)
Perform a Google search. The "what?" is the first argument. The optional area argument may be one of Application, Books, Finance, Images, News (default), Patents, or Video.googleAction(what [, area])
Open another tab with the URL based on the provided arguments.urlAction(URL, Get|Post, key1, value1, ...)
Shown below is a template result which includes a pop up menu for the titles.
Right clicking on the “Ant-Man” output displays the popup menu.
The “Sales Analysis” menu option runs another template passing in the title and the object ID.
The “Google Search” menu option opens a new tab and runs a Google search for the title within the “books” area of Google. The URL is
The top portion of the result page is shown below.
Defining the Template
The pop up menu options are presented by right clicking on a result title. The associated title cell is on the body line and is selected below.
The properties of the cell are shown in the right side of the Template Designer. Scrolling
Scroll down to see the interaction options.
Access the pop up menu dialog by clicking .
A sample dialog is shown below.
The first menu option definition is shown below.
The third menu option definition is shown below.
The second menu option definition is shown below.
This is using the componentAction() function to run the given template and passing it the id and title runtime variables. The 2nd argument for the component to run was obtained by opening the TARGET template, clicking on the icon highlighted below, and pasting inside double quotes into the componentRun() function of the SOURCE menu option.
The copied value provides a fully qualified path to the component so arguments 3 and 4 to componentRun() are both null. After the component arguments are any key\value pairs to pass as runtime arguments to the target drill down template. These can range from simple values to complex macro formulas.
Embedded Interaction
The end user interaction flow is shown below with a very simple drill down template that just displays the passed in values.
Usually the runtime values are used by the template’s associated main Data Source to control data retrieval. For example, the Data Source query text could use “[! @id !]” and “[! @title !]” variable placeholders. In this case the id and title value were just displayed to simplify this discussion.
The same template may be used behind different menu options as well. For example, one menu option with label “Analyze at 10%” may run an analysis using a 10 percent rate factor,
componentAction("run", "theTemplatePath", null, null, 'id', #_id, ‘factor’, 0.10)
Another menu option with label “Analyze at 15%” may pass in a 15 percent rate factor.
componentAction("run", "theTemplatePath", null, null, 'id', #_id, ‘factor’, 0.15)
You could also have a single menu option that runs a template and uses a prompt to obtain the “factor” variables. Qarbine provides a lot of flexibility for how you build your embedded analysis interactions.
Checkboxes within a Result
Overview
Some workflows display reports with business object context and from those the user wants to select some objects for further application interaction. Qarbine can generate these pages and provide HTML checkboxes for such interactions. The availability of custom cells may vary by edition and version. Note there is also a custom cell which displays boolean values using static checkbox images. This custom cell is specifically for HTML web page interaction.
Defining the Template
There is a custom cell which presents an HTML checkbox on the webpage result. Below is a simple example.
To add this custom cell to a template, click a free spot in the template and choose the drop down below located in the right hand side of the Template Designer.
Select the custom cell highlighted below.
You can drag and drop the custom cell or click
The cell is added to the template. The right hand side shows the custom cell’s properties and main options.
A sample cell formula to provide a unique value is shown below.
In some cases it may be useful to use a stringified version of an object’s identifier as the custom cell result value as was done in this example. Your application callback can then use this ID to perform some workflow interaction such as using it as a parameter in an optimized query .
As with other cells you may specify the template cell options below.
The sample template used for this discussion uses an inline data source. It is accessed within the template properties dialog as shown below.
The template grid layout used is shown below.
You may want to concatenate several values together using the concat() macro function. For example, your owning application may want the sales region and customer id values to be the identifier provided in order to perform some other tasks. The formula may be
concat(#region_id, ‘.’, #customer_id)
In your application callback simply split() each identifier element to obtain the region and customer ID values.
Embedded Interaction
You can run the above movies oriented template in an embedded fashion and have the user interact with the results. Here is a function to initiate the request to obtain the checkbox values. The user clicking a button or some other action would initiate this interaction lifecycle.
IFrameEmbeddedExample.prototype.getCheckedCellIdentifiers = function (event)
{
var additionalCssClass = 'phooey'; // Or leave as null
this.helper.getCheckedCellIdentifiers(additionalCssClass);
}
The additionalCssClass corresponds to the “CSS class” value from the HTML Checkbox custom cell in the template.
The helper’s options has a callback field handleGetCheckedCellIdentifiersReply. Below is a sample callback function to receive the checkbox values.
IFrameEmbeddedExample.prototype.handleGetCheckedCellIdentifiersReply = function (idList)
{
alert(String(idList));
}
Below is a sample dialog.
Using Checkbox Groups
By default the identifiers from all checkboxes on the displayed page are returned to the application from the getCheckedCellIdentifiers() call. You can define the template’s custom HTML checkbox cell to add an additional CSS class to the emitted checkboxes. This class can be used to segregate checkboxes across different output areas when there are logically different checkbox sets. The CSS value may be the result of a macro expression.
Consider the template below which has 2 checkbox cells.
The group header custom cell has
The body custom cell has
Sample output is shown below
You can be notified on user interactions with the checkboxes by setting option.handleCheckboxClickedReply to a callback. Below is a very simple example.
IFrameEmbeddedExample.prototype.handleCheckboxClickedReply =
function (domId, domClass, checkboxState)
{
alert(`Clicked ${domId}, class ${domClass}, state ${checkboxState}`);
}
Below is the alert shown when checking the “dog checkbox.
To get all of the checked animal types displayed your application can have these statements
var additionalCssClass = "animalType";
this.helper.getCheckedCellIdentifiers(additionalCssClass);
To get all of the checked animals displayed your application can have these statements
var additionalCssClass = "animal";
this.helper.getCheckedCellIdentifiers(additionalCssClass);
The results of those two requests come back through the options.handleGetCheckedCellIdentifiersReply callback.
To differentiate between animals across the type groups you could have the CSS class expression be
The callback for checking
would then show
Your application can process these values and perform some action.