views:

1854

answers:

2

I'm new to JQuery and web development in general. I'm trying to load some data from an XML file and build an unordered list. I've got that part working, now I'm trying to use the TreeView plugin so I can collapse/expand the data. The data is loaded like this:

$(document).ready(function(){
    $.ajax({
        type: "GET",
        url: "solutions.xml",
        dataType: ($.browser.msie) ? "text" : "xml",
        success: function(data) {
            var xml;
            if (typeof data == "string") {
                // Work around IE6 lameness
                xml = new ActiveXObject("Microsoft.XMLDOM");
                xml.async = false;
                xml.loadXML(data);
            } else {
                xml = data;
            }

            list = ""
            $(xml).find("Group").each(function() {
                group = $(this).attr("name");
                list += "<li><span>" + group + "</span><ul>";

                $(this).find("Solution").each(function() {
                    solution = $(this).attr("name");
                    list += "<li><span>" + solution + "</span></li>";
               });

               list += "</ul></li>";
            });

            $("#groups").html(list);           
        },

        error: function(x) {
            alert("Error processing solutions.xml.");
        }
    });

    $("#groups").treeview({
        toggle: function() {
            console.log("%s was toggled.", $(this).find(">span").text());
        }
    });
});

and the HTML looks like this:

<html>
  ...
  <body>
    <ul id="groups">
    </ul>
  </body>
</html>

The unordered list shows correctly, but the little [+] and [-] signs don't show up and the sections aren't collapsible/expandable. If I get rid of my Ajax loading and insert an unordered list inside of #groups manually it works as expected.

What am I doing wrong? Is there any other plugins or Javascript libs that could make this easier? The solution needs to work on IE6 locally (i.e. webserver).

Update: I found a work-around: If I define my treeview stuff like this it works:

function makeTreeview() {
    $("#container").treeview({
        toggle: function() {
            console.log("%s was toggled.", $(this).find(">span").text());
        }
    });
}
setTimeout('makeTreeview();', 50);

I think the problem is, when I create the treeview, the ajax stuff hasn't done it's work yet, so when treeview() is called, the unordered list hasn't been created yet. I haven't tested this with IE6 yet. Is there a nicer way to do this, without using SetTimeout()?

A: 

You need to get FireBug (Firefox add-in) and then you can see in the console what is being returned, and make sure it matches what you expect (And that it is actually doing the request..).

Once you get it working in FF, you can support the ancient 10-year old IE6 browser.


There's also some other things you may want to consider:

The whole ActiveXObject("Microsoft.XMLDOM") jumps out as me as unnecessary. If you pass XML in a string to $(), jQuery turns it into a DOM object.

Additionally, .Find can be replaced by:

$('Element', this);

So for example:

var xmlDoc = '<Group><Solution name="foo" /><Solution name="bar" /></Group>';
$('Solution', xmlDoc).each(function() { 
  document.write( $(this).attr('name') );
});

would spit out:

foo
bar

Also, with firebug, stick a console.log(list); at the end, to be sure you're generating the HTML you think you are. If you're really stuck in IE6, alert(list) somewhat works as a poor man's equivalent (as long as your file isn't too big).


In short, I think you're on the right track, you just need the tools to debug properly.

gregmac
Thanks for the suggestions. The XML stuff actually works fine, I just can't get the Treeview plugin to work in combination with it.
Mark A. Nicolosi
+1  A: 

I made the same type of call for another project. For other reasons you will probably want to wrap your ajax call in an anonymous function to create a closure so that your variables remain what you expect them to...

The success method is a callback function that happens after your call is complete , just create your treeview inside that method, or break it out into a seperate fumction if you need to for clarity.

in the example that you show - your treeview will still fail if the ajax call takes longer than 50ms - which could easily happen during initial load if more than two objects are being loaded from that same server.

This example used JSON, and concurrently loaded html data from a page method into a series of divs.

$(document).ready(function() { 
for (i= 1;i<=4;i++) 
{ 
(function (){
     var divname ="#queuediv"+i; 

    $.ajax({ 
      type: "POST", 
      contentType: "application/json; charset=utf-8", 
      dataType: "json", 
      url: "test12.aspx/GetHtmlTest", 
      data: "{}", 
      error: function(xhr, status, error) { 
          alert("AJAX Error!"); 
      }, 
       success: function(msg) { 
        $(divname).removeClass('isequeue_updating'); 
        $(divname).html(msg); 
        $("#somethingfromthemsg").treeview(); 
      } 
    });
})(); 
} 
});

Hope that helps!

Jim
Thanks Jim, this looks what I'm looking for. About the 50ms, I did have to increase that when I tested in IE6, due to it's slow nature. I'll test this tomorrow and mark your answer as correct, if it works.
Mark A. Nicolosi