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/remended way to do this?
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/remended way to do this?
Share Improve this question edited Nov 30, 2011 at 10:17 T.J. Crowder 1.1m200 gold badges2k silver badges2k bronze badges asked Nov 30, 2011 at 10:12 klironkliron 4,6834 gold badges33 silver badges49 bronze badges 3- Have you tried anything yet ? – Riz Commented Nov 30, 2011 at 10:15
-
1
Note that the JSON is invalid (
"content": nil
-- there is nonil
in JSON). – T.J. Crowder 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. – kliron Commented Nov 30, 2011 at 11:50
3 Answers
Reset to default 5If 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. 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);
}
});
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
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.)