Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

<object> created by function called from $(document).ready not rendered

In the sample I've put together, I need to:

  1. Use a jquery POST inside $(document).ready to grab a "ticket" I use later
  2. On success of the post, call another function ("AddTicketAndRender()") and pass in that ticket
  3. 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.
  4. 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&#47;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.

like image 272
Russell Christopher Avatar asked May 25 '12 16:05

Russell Christopher


People also ask

What does $( document .ready function () do?

$( document ).ready()A page can't be manipulated safely until the document is "ready." jQuery detects this state of readiness for you. Code included inside $( document ).ready() will only run once the page Document Object Model (DOM) is ready for JavaScript code to execute.

What is $( document .ready in JavaScript?

The ready() method is used to make a function available after the document is loaded. Whatever code you write inside the $(document ). ready() method will run once the page DOM is ready to execute JavaScript code.

What is difference between $( document .ready function () vs $( function ()?

The key difference between $(document). ready() and $(window). load() event is that the code included inside onload function will run once the entire page(images, iframes, stylesheets,etc) are loaded whereas the $(document). ready() event fires before all images,iframes etc.

Is $( document .ready necessary?

No, it is not necessary. You can either put the script tag right before the body closing tag or if you are supporting IE9+ you can use native JS.


1 Answers

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.

  1. 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.

  2. 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 );
like image 156
JMM Avatar answered Nov 02 '22 22:11

JMM