2

Javascript/jQuery newbie here.

My webserver is sending the contents of a directory tree as a JSON object. The object is arbitrarily nested depending on the number of subdirectories containing other subdirectories. It looks like this:

{
    "contents": [
        {
            "filename": "myfile",
            "mtime": 123456,
            "size": 2345,
            "content": nil
        },
        {
            "filename": "mydir",
            "mtime": 2345678,
            "size": 3456788,
            "content": [
                {...},
                {...}
            ]
        }
    ]
}

myfile is a normal file and so "content" is empty. mydir is a directory which may be empty, or contain other files or subdirectories.

I want to parse this JSON with javascript and generate an html ul representation of the contents. My question is: Is there an easy/recommended way to do this?

3
  • Have you tried anything yet ? Commented Nov 30, 2011 at 10:15
  • 1
    Note that the JSON is invalid ("content": nil -- there is no nil in JSON). Commented Nov 30, 2011 at 10:19
  • Thank you all for your answers. Fixed toplevel "contents" to "content". As I explain below, nil is actually null. Commented Nov 30, 2011 at 11:50

3 Answers 3

5

If you're receiving the JSON text via an ajax call using jQuery, jQuery will deserialize it into an object graph for you. If you've received it in some other way and have it in a string, you can deserialize it with jQuery.parseJSON.

However, the JSON you've quoted is invalid, specifically this bit:

"content": nil

There is no nil keyword in JSON. You'll want to fix the server to either leave the key off entirely, or use null, or something else. Valid JSON is defined on the JSON website, and you can use http://jsonlint.com for handy validation (and formatting). It might also be useful to use content or contents consistently; currently the top level uses contents but the subordinate entries use content.

Once you have the object graph, it's a fairly simple matter of a recursive function, looping through the array entries and, for entries that can have nested content, calling itself again to loop through that. Something vaguely like this (live copy):

jQuery(function($) {

  display("Loading the JSON data");
  $.ajax({
    type:     "GET",
    url:      "/path/to/the/data",
    dataType: "JSON",
    success:  function(data) {
      display("Got the data, rendering it.");
      $(document.body).append(renderContents(data.contents));
    },
    error:    function() {
      display("An error occurred.");
    }
  });

  function renderContents(contents) {
    var index, ul;

    // Create a list for these contents
    ul = $("<ul>");

    // Fill it in
    $.each(contents, function(index, entry) {
      var li;

      // Create list item
      li = $("<li>");

      // Set the text
      li.text(entry.filename);

      // Append a sublist of its contents if it has them
      if (entry.content) {
        li.append(renderContents(entry.content));
      }

      // Add this item to our list
      ul.append(li);
    });

    // Return it
    return ul;
  }

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }
});
Sign up to request clarification or add additional context in comments.

1 Comment

Thank's for the heads up. The nil part is actually an artifact as I wrote the json looking at the (clojure) object that gets converted into the json string on the server side. In the actual json the nils are converted to nulls. I corrected the content -> contents also as you suggested.
1

Use jQuery. In the jQuery ajax function use json for the dataType and it will automatically parse json and give a json object back. You can loop though the json array using jQuery each function and create your ui with data in it.

$.ajax({url:'ur url',dataType:'json',success:function(result){
var dhtml="<ul>";
$.each(result.contents,function(key,value){
        dhtml+="<li><span>"+value.filename+"</span><span>"+value.mtime+"</span></li>";
  })

dhtml+="</ul>";

$(body).append(dhtml);//Will add the result to ur html body
}
})

Jquery Each Api

Jquery ajax Api

7 Comments

You'll need to HTML-escape the filename, otherwise if it has (say) an ampersand (&) in it, it may cause trouble as you're interpreting that as HTML.
@Akhil: You can, but it violates separation of concerns. The server is producing JSON output. It might be used for all sorts of things; displaying in HTML is just one possibility.
But in the demo json there's no such data to be escaped na ?
@Akhil: You can't predict what the filenames will be, not properly escaping text from the server is just poor practice. (BTW, "na" is not an English word.)
@T.J.Crowder if as its a listing of files in a folder , there's is no chance for such special chars ..
|
1

The easiest way to loop through a traverse structure like this is usually to write a recursive ("self-calling") function:

// $parent is a jQuery object referring to an element 
// you what to create the tree in.
// data is your (parsed) JSON object.
function displayFileTree($parent, data) {
  if (data["contents"] && data["contents"].length) {
    var contents = data["contents"];

    // create a list element
    $list = $("<ul/>");

    // loop over the "contents"
    for (var i = 0, len = contents.length; i < len; i++) {

       // create list item, set its text and append it to the list
       $item = $("<li/>").text(contents[i].filename).appendTo($list);

       // call this function to create a sublist of the subitems
       displayFileTree($item, contents[i]);

    }

    // add list to parent
    $parent.append($list);
  }
}

(This function assumes the JSON is correct as suggested by T.J. Crowder's answer, and especially that it uses "contents" as the key everywhere and not "content".)

(EDIT: I started writing this before Crowder extended his answer with a similar solution.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.