Embedding Tableau Web Edit in a web application

Madhav Kannan
Dec 27, 2019 · 2 min read

For a while now, Bryant Howell’s excellent guide on embedding web edit in an iframe (which can be found here) was the only way to provide a seamless web authoring experience for end users on a web application, as the Tableau JavaScript API currently does not have a provision for it.

As mentioned in his blog, one of the biggest concerns with embedding web edit was how best to capture the newly-generated URL, in the event of a new workbook being created as compared to overwriting the existing workbook (which would have the same URL). While the blog provides a method to achieve this, it requires a fair amount of pre-work to be accomplished, which may not feasible in all situations.

Luckily, the JavaScript API now allows us to use a web edit URL as a source, which allows us to bypass the pre-work and implement web edit with much simpler logic.


Thus we start with a typical embedded visualization, with the HTML something like the below -

<body onload=”initViz();”>
<button hidden onclick=”launchEdit();” id=”edit”>Edit Viz</button>
<div id=”vizContainer” style=”width:800px; height:700px;”></div>
</body>

and the JavaScript something like the below -

var containerDiv, viz;
var viz_options = {
onFirstInteractive: function () {
$(“#edit”).show();
}
};
// Initial visualization setting
function initViz() {
containerDiv = document.getElementById(“vizContainer”);
var viz_url = “http://<server>/t/<site>/views/<workbook>/<view>”;
loadViz(containerDiv, viz_url, viz_options);
}
// Loading the visualization
function loadViz (containerDiv, url, options) {
if (viz) {
viz.dispose();
}
viz = new tableau.Viz(containerDiv, url, options);
}

Here a viz loads in the defined container, while also displaying the Edit button once it loads successfully. Once the Edit button is clicked, it launches a function called launchEdit() which looks like this -

function launchEdit() {
viz.getCurrentUrlAsync().then(function(current_url){
$("#edit").hide();
edit_url = current_url.split('?')[0].replace('/views', '/authoring');
edit_options = {
hideTabs: true,
hideToolbar: true,
onFirstInteractive: function () {
var iframe = document.querySelectorAll('iframe')[0];
iframe.onload = function(){
// Getting the URL post exit from web edit window
$("#edit").show();
viz.getCurrentUrlAsync().then (function(current_url){
console.log (current_url);
loadViz (containerDiv, current_url, viz_options);
})
}
}
};
loadViz (containerDiv, edit_url, edit_options);
})
}

On clicking Edit, the JavaScript API allows us to get the current viz URL through an asynchronous call that allows us to swap out the keyword ‘views’ with the keyword ‘authoring’ to open the web edit URL of the same dashboard.

While opening this view, an event listener is also added to the loaded iframe within the container that checks for when the web edit window is manually closed by the user within the container, and accordingly allows us to retrieve the new URL (using the JavaScript API’s getCurrentUrlAsync() functionality), which will allow us to capture the appropriate viz URL whether edits have been discarded or saved (either as an overwrite or as a new workbook), and display the same in the container.

The entire code can be found here.

*This method does not work with Internet Explorer due to its inability to retrieve the current URL as part of the onload functionality.

Madhav Kannan

Written by

Trying to extend Tableau in any way possible…

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade