6

Beginner here trying to figure out best way to structure some JSON and output the below nested <ul>

Each of the bolded items below are the values in the JSON. How might I structure the JSON and then how to build the DOM structure with jQuery? Any help greatly appreciated.

<ul>
    <li>Topic 1
        <ul>
            <li id="foo_item1a">
                <a href="destination_Item1a">
                    <strong>Lorem</strong>
                    <span>Item 1a</span>
                    <em>Ipsum</em>
                </a>
            </li>
            <li id="foo_item1b">
                <a href="destination_Item1b">
                    <strong>Dolor</strong>
                    <span>Item 1b</span>
                    <em>Sit</em>
                </a>
            </li>
        </ul>
    </li>
    <li>Topic 2
        <ul>
            <li id="foo_item2a">
                <a href="destination_Item2a">
                    <strong>Lorem</strong>
                    <span>Item 2a</span>
                    <em>Ipsum</em>
                </a>
            </li>
            <li id="foo_item2b">
                <a href="destination_Item2b">
                    <strong>Dolor</strong>
                    <span>Item 2b</span>
                    <em>Sit</em>
                </a>
            </li>
        </ul>
    </li>
</ul>

1

4 Answers 4

5

I have become a big fan of mustache.js recently for doing exactly this kind of thing.

http://github.com/janl/mustache.js/

Edit:

if I tweak calvinf's JSON format a little then this is an example using mustache.js:

<html>
  <head>
   <script type="text/javascript" src=" http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <script type="text/javascript" src="http://github.com/janl/mustache.js/raw/master/mustache.js"></script>
    <script type="text/javascript">
    var topics = {
    topics: [
    {
    title : "Topic 1",
    items : [
      {title: "1a", link: "http://www.example.com/", text: "Link Text or HTML"},
      {title: "1b", link: "http://www.example.com/", text: "Link Text or HTML"}
    ]
    },
    {
    title : "Topic 2",
    items : [
      {title: "2a", link: "http://www.example.com/", text: "Link Text or HTML"},
      {title: "2b", link: "http://www.example.com/", text: "Link Text or HTML"}
    ]
    }
    ]};


 var template = "<ul>{{#topics}}<li>{{title}}<ul>{{#items}}<li id=\"foo_item{{title}}\"><a href=\"{{link}}\">{{text}}</a></li>{{/items}}</ul>{{/topics}}</ul>";

      $(document).ready(function() {
  $("#topics").html(Mustache.to_html(template, topics));
      });

    </script>
    <title></title>
  </head>
  <body>
   <div id="topics"></div>
  </body>
</html>

If you want a speed benchmark for JavaScript templating libraries I found this link useful:

http://www.viget.com/extend/benchmarking-javascript-templating-libraries/

Sign up to request clarification or add additional context in comments.

4 Comments

mustache.js is a good templating system to check out. I'd also take a look at jquery-tmpl as it'll likely be included in jQuery 1.5 based on comments jeresig has made. github.com/jquery/jquery-tmpl
Resig's templating is super-dangerous, as it fails to HTML-encode by default (or even optionally). Anything you build on it is doomed to a thousand HTML-injection XSS security holes. Stay well away. (Mustache does not make this grievous error.)
@bobince -- while I completely agree that not have the option of HTML-encoding input in a client-side Javascript is no good at all, isn't it a better practice to handle the HTML-encoding on the server side?
@Sean: Only if you're producing the HTML itself on the server side, which presumably you're not if you're templating with mustache. Passing HTML-encoded text back in a JSON object for placement in a template is inappropriate; what if you wanted to use the same text in another context too, like writing to an attribute via DOM, or putting in an alert() box? The process of HTML-encoding should always be done at the point of inserting text into HTML.
5

You can use DOM-like methods to set attributes and text content instead to avoid the HTML-escaping issues you'll have with plain html()-setting and the more naïve of the templating systems. For example using jQuery 1.4 and with JSON input along the lines of calvinf's example:

var ul0= $('<ul>');
$.each(topics, function() {
    var li0= $('<li>', {text: this.title});
    var ul1= $('<ul>');
    $.each(this.items, function() {
        ul1.append($('<li>', {id: 'foo_'+this.title})
            .append($('<a>', {href: this.link, text: this.text})
                .append($('<strong>', {text: this.data0}))
                .append($('<span>', {text: this.data1}))
                .append($('<em>', {text: this.data2}))
            )
        );
    });
    li0.append(ul1);
    ul0.append(li0);
});

Comments

3

First recommendation is taking a look at the JSON site. It has some examples of JSON code in JavaScript.

If you're structuring the whole thing out of JSON, I'd do it like this.

var topics = {
  topic1: {
    title : "Topic 1",
    items : [
      {title: "1a", link: "http://www.example.com/", text: "Link Text or HTML"},
      {title: "1b", link: "http://www.example.com/", text: "Link Text or HTML"}
    ]
  },
  topic2: {
    title : "Topic 2",
    items : [
      {title: "2a", link: "http://www.example.com/", text: "Link Text or HTML"},
      {title: "2b", link: "http://www.example.com/", text: "Link Text or HTML"}
    ]
  }
};

If you only need a subset of the information you could do it differently, but this should give you something to start with.

To update the DOM with these values, you can loop through the appropriate array from the JSON object and then populate the values. Use the jQuery .html( htmlString ) function.

I hope this helps you get started.

Comments

2

I would recommend the excellent underscore.js's template function for this sort of thing.

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.