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.
It's hard to tell from the vast amount of code presented exactly what you're running into, so the general principle:
In order to find and operate on a DOM element, the element must exist. So for instance, this code will fail:
<script>$("#target").html("Updated");</script>
<p id="target">Not updated</p>
Live example | source
The target won't get updated. This code will work:
<p id="target">Not updated</p>
<script>$("#target").html("Updated");</script>
Live example | source
The only difference is that the script
tag is after the target, so you know the target exists in the DOM as of when you're trying to operate on it. (This is reliable; see what Google's dev team have to say about it, and the YUI guidelines.)
Libraries traditionally include "DOM ready" events because the built-in one, the load
event of the window
object, doesn't fire until very, very late in the process (once all external references have been loaded, including all images). But people wanted to do things earlier, even when images were still loading. The "ready" style events allow script code can be placed anywhere in the markup (people like putting it in head
, for some reason), but if it uses the "ready" event, it knows that it won't actually get called until all the markup has been processed.
So the upshot is: Either use the ready
event, or (better) move your code that relies on elements to after those elements in the markup (usually best right before the closing </body>
tag).