JavaScript API

Trusted Tickets Best Practice Implementation

For a variety of reasons, Trusted Authentication / Trusted Tickets is often the best choice for SSO into a Tableau Server. Trusted Authentication actually establishes a Tableau Session in the browser, so you can use it once to establish SSO for a whole browser session.

In this post, I’ll describe a best practice method for implementing the Session-Level Sign-O and provide a small JavaScript file with actual implementation of all the concepts.

You can find the auth_helpers.js file on GitHub with all the code necessary for this process (except for the back-end Trusted Tickets request, which you need to build in your own web application environment).

(more…)

Apply All buttons in JavaScript and Extensions API

Both the Tableau JS API and Extensions API send commands using Asynchronous JavaScript, based on the Promises JavaScript framework. If you are not well-versed Promises or asynchronous JavaScript in general, it can be difficult to go from the basic examples in the reference guide to more complicated solutions.

Over the years, customers have frequently asked about doing an “Apply All” button using the JavaScript or Extensions API, where filters on multiple different fields can all be applied from a single button click. While there is no way to do this directly in either API at the current time, you can create a process that very efficiently applies all of the filter changes as quickly as possible. This article will show one solution to the “Apply All button” request.

(more…)

Securely Passing Parameters into a Tableau Viz at Load Time

The standard answer for enforcing user-based data entitlements in Tableau is to use Row Level Security, where the user is authenticated in Tableau Server and then tied into an “entitlements view” in the database so that the user only ever sees data they have access rights to.

However, we are very often asked about passing parameters in to the viz to filter down information directly at load time, often driven by an application that Tableau vizes are embedded in. This post is about a few methods of implementing this behavior, and the security implications of each of them.

Basics of Security

Everything must be HTTPS

I’ll start by saying, to do any of this securely, you need EVERY resource you are working with to be using the HTTPS protocol (latest TLS version). If anything is not HTTPS, you could be passing important information in the clear.

Using URL Parameters to set a Filter directly is NOT SECURE

You can use the URL Parameter syntax to directly set the values for a Filter on any field, but this is completely insecure. Why? Because the following two methods will clear any filter and reveal all of the rows of data. Unless you have the JS API turned off, there is no way to prevent this.


Sheet.clearFilterAsync(fieldName);
Sheet.applyFilterAsync(fieldName, "", tableau.FilterUpdateType.ALL);

Tableau Parameters are the (potentially) secure way to make an adjustable Data Source Filter

The only way to prevent a user from resetting a filter value is by making it a Data Source Filter.  Thankfully, you can use a Calculated Field for the Data Source Filter. If you use Tableau Parameters in the Calculated Field, the Parameter value(s) can be set to change what is filtered, and you will have a Data Source Filter that cannot be altered by the JS API (or the end user).

However, there are quite a few considerations to make this a truly secure method for setting filter values:

(more…)

Tableau and Write-Back – Together At Last

Editor’s Note: Huge thanks to special contributor Gordon Rose for this blog post.

Tableau helps people see and understand their data – and guarantees that it in the process, it will never make any changes to that data. Tableau is a strictly read-only technology. However, many customers want the ability to modify the data that lies behind a Tableau visualization (Viz), and then, either see those changes immediately reflected in the Viz and/or make other applications aware of those changes. With a small amount of supporting technology, Tableau’s read-only behavior can easily be integrated into so-called “write-back” use cases.

In this blog article, we’ll explore a way to do exactly that – one in which the write-back components are external to the Viz. An alternative approach is one in which those components are more tightly integrated into the Viz itself – that’s for a later blog article to explore. Ideally you will find that you can use one of these two approaches as a launching point for the development of your own write-back use case.

(more…)

Using the JavaScript API without Embedding

Editor’s Note 2021/04/20: In any current version of Tableau Server, use Tableau Extensions API for this type of functionality.

Tamás Földi always has amazing stuff, but this one really blows my mind- Tableau JavaScript API without Embedding .

Using the Web Data Connector to publish arbitrary extra content to Tableau Server is pretty amazing when you think about it; it also works for embedding web edit in an iframe.

Update for more recent Tableau Server versions (2017-11-15):

We recently encountered a customer wanting to implement this functionality and they were having trouble accessing the getWorkbook() method of the Viz object. Apparently Tableau Server now makes the Viz object available prior to it being fully initialized, and any web content starts to load immediately. So if you want to use this technique, you should put in an interval check to keep trying until the workbook is actually available. It looks something like this:


var myInterval;
function start_timer(){
myInterval = setInterval(js_api_test, 200); //https://www.w3schools.com/jsref/met_win_setinterval.asp
}
function js_api_test() {
try {
var sheet = parent.parent.tableau.VizManager.getVizs()[0].getWorkbook().getActiveSheet(); //Error: "Unable to get property getWorkbook()"
clearInterval(myInterval); //https://www.w3schools.com/jsref/met_win_clearinterval.asp
console.log("Successfully retrieved Tableau sheet object");

// start doing anything else you'd like to do here

//
}
catch (err) {
console.log("No dice!");
}
}

You would place a call to the start_timer() function in the onload function of the body tag of your HTML page. Rather than jump directly into the code, you start a repeating interval timer that puts in a bit of delay, and will retry until it actually gets the workbook object. Once that object is found, the interval is cleared and you can start doing whatever you want relative to the viz the page is embedded within.

Using getData in Tableau 10 to create tables from any Viz

Tableau 10’s JavaScript API has a new getData interface which allows you to get summary and underlying data directly as JavaScript objects. I’ve already shown a use case to use these methods for simply grabbing values. But a wider use case is creating an HTML table from any Tableau visualization, particularly if 508 compliance requires that you make all data available via a screen reader. Even if you don’t need compliance, you may just want to control how Tableau displays its underlying data. The full working example is here on GitHub.

(more…)

Reverting to the Original View through the JavaScript API

An interesting use case came in from a customer today, asking about something that is hinted at in the documentation of the JavaScript API, but not fully spelled out. They wanted to know how to replicate the ‘Original View’ button in the toolbar. After a bit of testing, I found out something new and not particularly well documented.

The Workbook class of the JS API has the methods for working with the CustomViews, to know which exist, to choose one, or to save a new one. All good — but how to do you interact with the ‘Original View’?

You can do Workbook.getCustomViewsAsync() to an Array of CustomView objects, which have properties which you can use to load any particular one. But interestingly, the ‘Original View’ does not come through in this array; if there are no custom views, the array is empty, and the ‘Original View’ does not appear even after some custom views have been created.

The setCustomViewAsync() method takes a string Name parameter, which will make the workbook switch to the custom view with that name (You can get this name using the getName() method of any CustomView object). However, passing the string ‘Original View’ does not work; you will get an error.

After some testing, I found that if you use the setCustomViewAsync() method without passing any parameter for name, it reverts back to the Original View. I realize this is not clear at all from the documentation, but I’ve tested it out and it appears to work. So reverting back to the Original View is as simple as:


book = viz.getWorkbook();

book.setCustomViewAsync().then( function (e) { // do whatever...});

Holy Sheets: Understanding the Tableau Server JavaScript API

I love the JavaScript API tutorial on Tableau’s site, but even though this is my day job, the JavaScript API Reference still takes me in circles sometimes before I’ve figured out exactly how to solve a specific problem. I’m going to share what I’ve learned over the years, both explanations and some code for solving common problems.

How did I find these things out? There is the API Reference, as well as the Concepts page, which both provide different views and examples. I’ve paired that with a lot of testing using Firefox with Firebug and Chrome’s developer tools. Often the best way to understand what is happening is to do console.log(object); on a particular variable and compare against the API Reference to understand exactly what class you are dealing with at that moment.

(more…)

Setting Filter and Parameters Prior to Load using JavaScript API

Today I took a look at the updated Tableau JavaScript API documentation just for a quick reminder of some syntax, and noticed something I’d never seen before on this page.

“Academic Year” : “” … that seems to be a field name. I changed mine to see if I could set individual values:


options = {
hideTabs: true,
"Gender": "Men",
"College" : ["Arts & Sciences", "Communication"],
"YEAR([Date])" : [2009, 2010],
onFirstInteractive: function () {
console.log("Run this code when the viz has finished loading.");
}
};

and sure enough it worked. I’ve tested on 9.1, 9.2 and 9.3. Russell Christopher assures me this has always been possible, just never been documented. This means you can set the values for a filter prior to load, rather than loading the viz and then applying a FilterAsync action, which requires a reload. If you are setting the values of filters programmatically at load time, this could greatly improve your overall load times.

I’ve tested with Parameters as well — the same syntax works. I’m sure that as with URL parameters, you need your Tableau Parameter names to be distinct from any Field Names, otherwise Tableau will apply your value to filter the Field rather than changing the parameter. You can’t yet set continuous or relative date filters this way, but if you use parameters to make the date filter start and end dates, you can set the parameter values prior to load using this technique.

Note on Security: This mechanism is actually just a fast translation method to the existing URL parameters for filters and Tableau Parameters. It has all of the same limitations and definitely passes all the values across in the URL string of the GET request. So don’t ever use it to pass any values that should be secured or hidden.