<object> created by function called from $(document).ready not rendered
html, javascript, jquery
Solution
FYI, your tableau.russellchristopher.org link doesn't work. I don't know how you would have this working in jsfiddle either -- I get a cross origin error when I try it.
One obvious problem is that your script element that contains the template is in the nether region between `</head>` and `<body>`. Put it inside `body`.
Here's what I think might be happening: it looks like the Tableau JavaScript API is setup to process the `object.tableauViz` elements when `DOMContentLoaded` or `load` fires. You're inserting the `<object>` markup into the document in the callback for an async request. So I'm thinking that the load events are firing, and the Tableau API is doing it's initialization before your `<object>` markup is inserted into the document.
Perhaps register your own listeners for those events and call `console.log()` to see if they execute before your `$.post` callback.
Unfortunately, the `createVizesAndStartLoading()` method that performs the initialization (e.g. retrieving `object.tableauViz` elements from the document) does not appear to be accessible. It looks like you might be able to add your element by calling `window.tableau.createViz()`, but unfortunately `createVizesAndStartLoading()` does some pre-processing (e.g. setting `width` / `height` values) that you'd either need to duplicate or forego.
Retrieve template synchronously
Try this instead of your `$.post()`:
$.ajax( {
url : trustedURL,
data : {
username : userName,
server : serverURL,
client_ip : "",
target_site : ""
},
async : false
} ).done( addTicketAndRender );
Problem
In the sample I've put together, I need to: - Use a jquery POST inside $(document).ready to grab a "ticket" I use later - On success of the post, call another function ("AddTicketAndRender()") and pass in that ticket - In AddTicketAndRender(), replace a placeholder value in an HTML template with the ticket that was passed in. The HTML template defines an object I need to render. Add the HTML template to body and render: ``` function addTicketAndRender(incomingTicket){ //For now, just touch the spinner, don't worry about the ticket. var template = $('#tableauTemplate').html(), filledTemplate = template.replace('{placeholder}','yes'); $('body').append( filledTemplate );} ``` I have this working in jsfiddle: http://jsfiddle.net/vm4bG/4/ However, when I combine the HTML and JavaScript together into a single htm file, the visualization I want isn't getting rendered in Chrome, IE, or Firefox. Here is complete source from the HTM that isn't working. Can anyone see something that is obviously wrong? My markup & script is below and/or here: http://tableau.russellchristopher.org:81/rfc1.htm ``` <html> <head> <script type="text/javascript" src="http://public.tableausoftware.com/javascripts/api/viz_v1.js"></script> <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script> </head> <!-- template code follows --> <script type="text/template" id="tableauTemplate"> <div class="tableauPlaceholder" id="tableauPlaceholder" style="width:654px; height:1469px;background-image: url('http://tableau.russellchristopher.org:81/Background.gif'); top: 0px; left: 0px; width: 100%; margin-left: 76px;"> <object class="tableauViz" width="654" height="1469"> <param name="host_url" value="http%3A%2F%2Fpublic.tableausoftware.com%2F"/> <param name="site_root" value="" /> <param name="name" value="AnalyticsIncJavaScript/AnalyticsInc" /> <param name="tabs" value="no" /> <param name="toolbar" value="yes" /> <param name="static_image" value="tableau.russellchristopher.org:81/Background.gif"/> <param name="animate_transition" value="yes" /> <param name="display_static_image" value="yes" /> <param name="display_spinner" value="{placeholder}" id="display_spinner" /> <param name="display_overlay" value="yes" /> <param name="display_count" value="yes" /> </object> </div> </script> <!-- end of template --> <body> <script> function addTicketAndRender(incomingTicket){ // grab tableau template code and replace ticket placeholder with incomingTicket from $.post console.log("Add and Render"); //For now, just touch the spinner, don't worry about the ticket. var template = $('#tableauTemplate').html(), filledTemplate = template.replace('{placeholder}','no'); $('body').append( filledTemplate ); console.log(incomingTicket); console.log("Appended."); } $(document).ready(function() { console.log("ready"); var trustedURL = "http://tableau.russellchristopher.org/trusted", userName = "foo", serverURL = "http://tableau.russellchristopher.org/"; $.post(trustedURL, { username: userName, server: serverURL, client_ip: "", target_site: "" }, function(response) { addTicketAndRender(response); }); }); </script> </body> </html> ``` Calls to console.log in the success function are logging correct information - so I know I'm getting where I need to - but the object doesn't seem to be doing what it needs to.