Determine authentication workflow
The first step in embedding any technology within a web application is to establish a session granting the application rights to the embedded resource. When embedding MicroStrategy, you have the option to use the default authentication flow setup within library, or to use the REST API to seamlessly authenticate behind the scenes. For our example we will use the REST API approach.
function createAuthToken(){ return new Promise(function(resolve, reject) { var body = { //"username": "", //"password": "", //"loginMode": 1 "loginMode": 8 // login as Guest }; var xhr = new XMLHttpRequest(); xhr.open('POST', 'https://demo.microstrategy.com/MicroStrategyLibrary/api/auth/login'); xhr.withCredentials = true; xhr.setRequestHeader('Content-Type', 'application/json'); xhr.setRequestHeader("Accept", "application/json"); xhr.send(JSON.stringify(body)); xhr.onreadystatechange = function() { if (xhr.readyState === 2) { resolve(xhr.getResponseHeader('x-mstr-authToken')); } else { reject({ status: this.status, statusText: xhr.statusText }); } }; }); };
Create Dashboard
We can now leverage the javascript embedding library (which comes with the MicroStrategyLibray application) to take and existing dashboard and render it within our application using the code snippet below. Note that during the creation process we have the option to provide the function responsible for obtaining our authentication token.
function createDossier(authToken){ //populate div with Dashboard: microstrategy.dossier.create({ placeholder: document.getElementById("divForDossier"), url: 'https://demo.microstrategy.com/MicroStrategyLibrary/app/EC70648611E7A2F962E90080EFD58751/5EED2C9044658AF0A99E759DB804758B', enableCustomAuthentication: true, enableResponsive: true, customAuthenticationType: microstrategy.dossier.CustomAuthenticationType.AUTH_TOKEN, getLoginToken: createAuthToken, }).then(function(dossier) { //any code you want to run after dashboard loads }); }
Enable desired embedded controls
When creating the dashboard, developers have a number of optional parameters that can govern what additional end user controls they would like to display, such as navigation, exporting, sharing, and filtering options. Run the code sample below to enable many of our various controls.
function createDossierFullControls(authToken){ //populate div with Dashboard: microstrategy.dossier.create({ placeholder: document.getElementById("divForDossier"), url: 'https://demo.microstrategy.com/MicroStrategyLibrary/app/EC70648611E7A2F962E90080EFD58751/5EED2C9044658AF0A99E759DB804758B', enableCustomAuthentication: true, enableResponsive: true, customAuthenticationType: microstrategy.dossier.CustomAuthenticationType.AUTH_TOKEN, getLoginToken: createAuthToken, dockedTOC: { dockedPosition: "left", theme: "light", canClose: false, dockChangeable: false, isDocked: true }, navigationBar: { enabled: true, gotoLibrary: true, title: true, toc: true, reset: true, reprompt: true, share: true, comment: true, notification: true, filter: true, options: true, search: true, bookmark: true }, optionsFeature: { enabled: true, help: true, logout: true, manage: true, showTutorials: true }, shareFeature: { enabled: true, invite: true, link: true, email: true, export: true, download: true }, tocFeature: { enabled: true }, }).then(function(dossier) { //any code you want to run after dashboard loads }); }
Simple page navigation
Functions are provided to allow you to easily navigate to the next and previous pages of the dashboard.
function nextPage(dossier){ dossier.goToNextPage(); }
function previousPage(dossier){ dossier.goToPrevPage(); }
Building your own navigation controls
Additional functions are provided to give the application contextual awareness of where the user currently is and to provide the full TOC list to allow the application to navigate anywhere within the dashboard at any time.
function getTOC(dossier){ var toc = dossier.getTableContent(); alert(JSON.stringify(toc, undefined, 4)); }
Retreiving existing filters and available inputs
Dossiers allow dashboard developers to explicitly define filtering criteria at the chapter level, which apply to all child pages. Run the function below to extract details on the available filters.
function getFilters(dossier){ dossier.getFilterList().then(function(filters){ alert(JSON.stringify(filters, undefined, 4)); });
Submitting a filter answer
From the sample above, we can see that this chapter has an existing filter for the year attribute. We can request use the provided information to filter all of our pages for the year 2018.
function applyFilter(dossier){ dossier.filterSelectMultiAttributes( { 'selections':[{'name':'2018'}], 'filterInfo': {'key': 'W105'} } ); }
Submitting multiple filter answers
In a similar fashion, we can also provide years 2018 and 2019 in our request as the underlying filter supports multiple selections. The behavior of the applyFilter functions is to replace the existing state.
function applyFilter2(dossier){ dossier.filterSelectMultiAttributes( { 'selections':[{'name':'2018'},{'name':'2019'}], 'filterInfo': {'key': 'W105'} } ); }
Deselect all elements
Additional convenience methods were included to allow the complete removal, or unsetting of the filter
function clearFilter(dossier){ dossier.filterDeselectAllAttributes( { 'filterInfo': {'key': 'W105'} } ); }
Select all elements
Similarly, all elements can be applied as selection with a single call
function applySelectAllFilter(dossier){ dossier.filterSelectAllAttributes( { 'filterInfo': {'key': 'W105'} } ); }
Register Graphics On Selection Event
Events are the essential features that enable a deeper integration with the parent application by allowing two-way communication and providing details on how the user is interacting with the embedded content. Run the sample below to add a listener to visualization selections.
function addOnGraphicsSelectedListener(dossier){ dossier.registerEventHandler( 'onGraphicsSelected', function(selection){ alert(JSON.stringify(selection, undefined, 4)); } ) alert("Graphics Selection listener is applied. Go ahead and click on a visualization to test it out"); }
Register Navigation Event
We can also apply a similar event to detect when the dashboard changes to another page.
function addNavigationListener(dossier){ dossier.registerEventHandler( 'onPageSwitched', function(selection){ alert(JSON.stringify(selection, undefined, 4)); } ) alert("Navigation listener is applied. Change the page from the TOC menu to test it out"); }
Register Filter Event
Events also exist to capture any manipulations to filters.
function addFilteringListener(dossier){ dossier.registerEventHandler( 'onFilterUpdated', function(selection){ alert(JSON.stringify(selection, undefined, 4)); } ) alert("Filtering listener is applied. Change the filter criteria to test it out"); }