Search code examples
javascripthandlebars.jsmustache

How do I use nested iterators with Mustache.js or Handlebars.js?


I would like to use handlebars.js or mustache.js to iterate over a list of families, and then iterate over that family's members. Inside of both loops, I want to display properties of both. However, once I get into the second iteration, none of the family variables are visible.

{{#each families}}
  {{#each members}}
    <p>{{ ( here I want a family name property ) }}</p>
    <p>{{ ( here I want a member name property ) }}</p>
  {{/each}}
{{/each}}

Is this possible? I'd greatly appreciate any help!


Solution

  • You can nest sections easily with lists of objects. Use a data structure where families is a list that has an object members that has a list of any objects (or even more lists)like:

    {
      "families" : [
            {
              "surname": "Jones",
              "members": [
                {"given": "Jim"},
                {"given": "John"},
                {"given": "Jill"}
              ]
            },
            {
              "surname": "Smith",
              "members": [
                {"given": "Steve"},
                {"given": "Sally"}
              ]
            }
          ]
    }
    

    You would be able to populate a template like:

    <ul>
        {{#families}}
        <li>{{surname}}
          <ul>
            {{#members}}
            <li>{{given}}</li>
            {{/members}}
          </ul>
        </li>
        {{/families}}
      </ul>
    

    jsFiddle is currently down so here's the full working HTML with JS:

    <!DOCTYPE html>
    <head>
    
      <script src="http://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.3.0/mustache.min.js"></script>
      <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
      <script>
        $(function() {
          var tpl = $('#fam').html(),
            data = {
              "families" : [
                {
                  "surname": "Jones",
                  "members": [
                    {"given": "Jim"},
                    {"given": "John"},
                    {"given": "Jill"}
                  ]
                },
                {
                  "surname": "Smith",
                  "members": [
                    {"given": "Steve"},
                    {"given": "Sally"}
                  ]
                }
              ]
            },
            html = Mustache.to_html(tpl, data);
    
            $("#main").append(html);
    
        });
      </script>
    
    </head>
    
    <div id="main"></div>
    
    <script type="template/text" id="fam">
      <ul>
        {{#families}}
        <li>{{surname}}
          <ul>
            {{#members}}
            <li>{{given}}</li>
            {{/members}}
          </ul>
        </li>
        {{/families}}
      </ul>
    </script>