Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The Portals Extension Module has been created to allow 3rd party content and applications to be integrated inside Portals. This documentation is split into several parts and each relevant section also includes a list of API functions.

...

Topics:

Table of Contents
maxLevel2
stylenone

...

Including Portals API in your application

...

Code Block
languagejs
Questback.portalsApi.query.language().then(function(result) {
    console.log(result.language);
});

query.

...

Get information about the client device.

...

token

Returns the Portals Api token, which can be used in external software to additionally validate the user via EFS web service.

Code Block
Questback.portalsApi.query.deviceInfotoken().then(function(result) {
    console.log(result.device.isMobiletoken);
});

query.ajax (reserved for future use)

Makes an ajax call to the internal portals server API and returns the result. Since Portals itself does not provide a public portals server API, this function is reserved for future use.

...

languagejs

...

If the user is logged in, the token field will contain the users api token, which you can validate by calling the following EFS web service. Otherwise, token will be an empty string.

Code Block
portal.users.getUserDataByToken

If the token is valid the userId and portalId is returned. Otherwise an exception is thrown. Please refer to the web services documentation for more details on this service call.

query.deviceInfo

Get information about the client device.

Code Block
languagejs
Questback.portalsApi.query.deviceInfo().then(function(result) {
        consoleconsole.log(result.device.isMobile);
    })
    .catch(function(error) {
        console.log(error);

query.ajax (reserved for future use)

Makes an ajax call to the internal portals server API and returns the result. Since Portals itself does not provide a public portals server API, this function is reserved for future use.

Code Block
languagejs
Questback.portalsApi.query
    .ajax('GET', '/api/portal/client/pages')
    .then(function(result) {
        console.log(result);
    })
    .catch(function(error) {
        console.log(error);
    });

...

Trigger actions in Portals

...

Code Block
languagejs
Questback.portalsApi.bus.subscribe(
  Questback.portalsApi.mySight.tableauEventVizResize, function(event) {
    if (event.mysight.pageModuleIdentifier === 'page-module-identifier-to-handle') {
        // Do something
    }
});

Use Portals styles

You can use Portals CSS styles by importing its stylesheets into your iframe. The following examples will guide you through the setup process.

Retrieve file paths

First you need to get the paths of the stylesheet files and font definitions:

Code Block
Questback.portalsApi.initialize().then(function() {
    Questback.portalsApi.query.portalInfo().then(function(result) {
        // Continue here with step 7.2
    });
});

The result parameter will contain the necessary information in its layout field:

Code Block
{
    portal: {...},
    layout: {
        customCss: "<https://PORTALS-DOMAIN/portals/PORTALS-ID/css/compile.css?v=123456",>
        portalsCss: "<https://PORTALS-DOMAIN/portals/PORTALS-ID/css/custom.css?v=123456",>
        extensionCss: "<https://PORTALS-DOMAIN/portals/PORTALS-ID/css/extension.css?v=123456",>
        fontCss: "<https://fonts.googleapis.com/css?family=Lato",>
        fontDefinition: "'Lato', sans-serif",
    }
}

These paths do not change for a given portal (besides the value of the cachebuster parameter called v), so it is possible to retrieve them once, store them and hardcode them into your code, to save postMessage requests and improve startup times a little.

Importing the extension stylesheet

After retrieving the stylesheet urls you need to import the files by adding link tags into your documents head:

Code Block
var head = document.getElementsByTagName('head')[0];
var linkExtension = document.createElement('link');
linkExtension.setAttribute('rel', 'stylesheet');
linkExtension.setAttribute('type', 'text/css');
linkExtension.setAttribute('href', result.layout.extensionCss);
head.appendChild(linkExtension);

You should note that it takes some time to retrieve the file from the server, so there is a short time in which your application is rendered without the styles in the file. You might want to prevent your application from beeing shown to the user before the above code has been executed.

The extension.css is a subset of the portals stylesheet and contains the necessary styles for the most common use cases. If you want to include the complete portals stylesheet you can import result.layout.portalsCss instead of result.layout.extensionCss. But be aware that this might introduce conflicts with existing styles in your application.

Importing the custom stylesheet

If you have added custom css in the Look & Feel section of the CMS, that contains styles which you want to apply to you application, then you should import the custom.css file, too.

Code Block
var linkCustom = document.createElement('link');
linkCustom.setAttribute('rel', 'stylesheet');
linkCustom.setAttribute('type', 'text/css');
linkCustom.setAttribute('href', result.layout.customCss);
head.appendChild(linkCustom);

Importing the portals default font

To use the same font as your portal use the following code:

Code Block
if (result.layout.fontCss) {
    var linkFont = document.createElement('link');
    linkFont.setAttribute('rel', 'stylesheet');
    linkFont.setAttribute('type', 'text/css');
    linkFont.setAttribute('href', result.layout.fontCss);
    head.appendChild(linkFont);

    // Apply font-family definition
    var body = document.getElementsByTagName('body')[0];
    body.style.fontFamily = result.layout.fontDefinition;
}

Using the styles

The extension.css contains classes for the most common use cases.

Color variables

Code Block
/* Color variables definitions */
:root {
    --ext-primary-color: #006BFE;
    --ext-secondary-color: #606c76;
    --ext-success-color: #2ccc76;
    --ext-warning-color: #fbbf5f;
    --ext-danger-color: #fd6e72;
    --ext-info-color: #006bff;
    --ext-text-color: #444444;
    --ext-sidebar-background-color: #0a061d;
    --ext-sidebar-text-color: #ffffff;
}

Type color classes

Classes exist for the most common type and property combinations:

Code Block
.ext-text-primary
.ext-text-secondary
.ext-text-success
.ext-text-warning
.ext-text-danger
.ext-text-info

.ext-background-primary
.ext-background-secondary
.ext-background-success
.ext-background-warning
.ext-background-danger
.ext-background-info

.ext-border-primary
.ext-border-secondary
.ext-border-success
.ext-border-warning
.ext-border-danger
.ext-border-info

Profile background classes

The profile background classes exist, too:

Code Block
.ext-profile-background-0
.ext-profile-background-1
.ext-profile-background-2
.ext-profile-background-3
.ext-profile-background-4
.ext-profile-background-5
.ext-profile-background-6
.ext-profile-background-7
.ext-profile-background-8
.ext-profile-background-9

Other classes

Code Block
.ext-text-color
.ext-sidebar-background
.ext-sidebar-text

Buttons

You can style your buttons by using the portals button classes:

Code Block
<button class="btn btn--md btn--primary btn--gloss">Click</button>

The button size can be set by adding one of the following classes:

Code Block
btn--xs
btn--sm
btn--md
btn--lg

The type can be set by adding one the following classes:

Code Block
btn--default
btn--primary
btn--secondary
btn--cancel
btn--clear
btn--success
btn--warning
btn--danger
btn--info
btn--contrast
btn--transparent

To enable hover effects, add the following class:

Code Block
btn--gloss

To display a button as disabled, add the following class:

Code Block
btn--disabled

If the button has the "disabled" attribute, the styles of "btn--disabled" are applied automatically.

Input fields

You can use styles for input fields as well. Write your markup as follows:

Code Block
<div class="input input--animated">
    <input type="text" oninput="this.value ? this.classList.add('input-filled') : this.classList.remove('input-filled');">
    <label>
        <span class="text-ellipsis">This is the label</span>
    </label>
</div>

Please pay attention to the order of the elements and their classes. The oninput event handler is required to add or remove the input-filled class according to the inputs value. If your input receives an initial value you have to add the input-filled class manually.

Selectboxes

You can use native html selectboxes and they will be styled as close as possible to the original portals selectboxes. As those are generated by JavaScript, an exact replication is not possible.

Code Block
<div class="input input--animated input--select">
    <select class="input-filled">
        <option value="1">Value 1</option>
        <option value="2">Value 2</option>
        <option value="3">Value 3</option>
    </select>
    <label>
        <span>This is the label</span>
    </label>
</div>

As native html selectboxes always have a value selected, the input-filled class is always set on the select element.

Opening a dialog in Portals

The portalsApi has four methods that give you the ability to open a dialog outside of the scope of your iframe.

Code Block
Questback.portalsApi.trigger.openDialog(text, title)
Questback.portalsApi.trigger.openConfirmDialog(text, title)
Questback.portalsApi.trigger.openIframeDialog(url, title, height, heightUnit)
Questback.portalsApi.trigger.openIframeConfirmDialog(url, title, height, heightUnit)

Dialog buttons

The methods openDialog and openIframeDialog open a dialog with a single "Close" button. The corresponding methods openConfirmDialog and openIframeConfirmDialog open a dialog with a "Cancel" and an "Ok" button.

Text dialogs

The methods openDialog and openConfirmDialog take a string as first parameter, which is the text shown in the main area of the dialog. The title is optional.

Iframe dialogs

The methods openIframeDialog and openIframeConfirmDialog render an iframe in the main area of the dialog with the url given at the first parameter. The title, height and heightUnit are optional. The paramters height and heightUnit define the height of the iframe in the dialog.

Simple call

The simplest way to open a dialog is by calling one of the dialog methods, give a text/url and not worry about any events:

Code Block
Questback.portalsApi.trigger.openDialog('This is a simple dialog!');

Handle dialog close

The dialog can either be closed or canceled/accepted and this event can be handled by implementing Promise methods, like this:

Code Block
Questback.portalsApi.trigger.openDialog('This is a simple dialog!')
    .then(function() {
        console.log("Dialog has been closed");
    });

The confirm dialogs make use of the then and catch methods:

Code Block
Questback.portalsApi.trigger.openConfirmDialog('This is a confirmation dialog!')
    .then(function() {
        console.log("Dialog closed by ok button");
    })
    .catch(function() {
        console.log("Dialog closed by cancel button");
    });

The catch method does not indicate that an error happened, it just tells you about the way the dialog was closed. Both methods do not get any parameters. This means that no data from the dialogs iframe is transported back to the calling iframe.

If you want to transport data between the iframes or trigger actions in the other iframe make use of the PortalsApi's message bus functionality, documented under Using the Portals message bus.