Matías Cánepa
Matías Cánepa

Reputation: 5974

How to achieve recursive templates with jquery

I get a json from database, then load dynamically a template and apply that json. The data stored in this variable is self-referenced (the typical id - parent_id). I'm unable to do a recursion of that data.

the json:

var my_json = {"modules":[
    {
        "id_modules": "1",
        "id_modules_parent": "0",
        "mod_name": "mod 1",
        "sub_modules": [
            {
                "id_modules": "2",
                "id_modules_parent": "1",
                "mod_name": "mod 1a",
                "sub_modules": ""
            },
            {
                "id_modules": "3",
                "id_modules_parent": "1",
                "mod_name": "mod 1b",
                "sub_modules": ""
            }
        ]
    },
    {
        "id_modules": "4",
        "id_modules_parent": "0",
        "mod_name": "mod 2",
        "sub_modules": [
            {
                "id_modules": "5",
                "id_modules_parent": "4",
                "mod_name": "mod 2a",
                "sub_modules": [
                    {
                        "id_modules": "7",
                        "id_modules_parent": "5",
                        "mod_name": "mod 2aa",
                        "sub_modules": ""
                    }
                ]
            },
            {
                "id_modules": "6",
                "id_modules_parent": "4",
                "mod_name": "mod 2b",
                "sub_modules": ""
            }
        ]
    }
]}

This is how I render the template:

$.get("template_file.txt", function(template)
{
    $.tmpl(template, my_json).appendTo("#some_div");
});

and finally the template (template_file.txt):

<ul class="modules_ul">
    {{each(i, module) modules}}
        <li>${module.mod_name}</li>
        {{each(j, submodule) module.sub_modules}}

            {{tmpl(submodule) ".modules_ul" }} //what goes here?

        {{/each}}
    {{/each}}
</ul>

Can anybody help me? Thanks in advance!

Edit: added a jsfiddle to play around

SOLUTION: see mblase75's answer in this post

Upvotes: 3

Views: 1057

Answers (3)

Mat&#237;as C&#225;nepa
Mat&#237;as C&#225;nepa

Reputation: 5974

It should be like this

<ul class="modules_ul">
    {{each(i, module) modules}}
        <li>${module.mod_name}</li>
        {{if module.sub_modules}}
            {{tmpl(module.sub_modules) "template_name"}}
        {{/if}}
    {{/each}}
</ul>

Upvotes: 1

STO
STO

Reputation: 10638

This recursive templates works for me. There are few difference with your example: template is inline, template is accessed by id, not by class, and additional if checks is added before rendering nested template.

By the way, what kind of error do you get? Is template is not rendered at all?

<script type="text/javascript">
    var data =
    {
        name: "Root",
        children:
        [
            { name: "Child1",
                children:
                [{ name: "SubChild1"}]
            },
            {
                name: "Child2",
                children:
                [{ name: "SubChild2"}]
            }
        ]
    };

    $(function () {
        $("#template").tmpl(data).appendTo("#target");

    });
</script>
<script type="text/html" id="template">
<div id="template">
    <h3>
        ${name}</h3>
    <div style="position:relative; margin-left:10px">
        {{if children}} 
            {{each(i, child) children}} 
                {{tmpl(child) "#template" }}
            {{/each}}
        {{/if}}
    </div>
</div>
</script>
<div id="target">
</div>

Upvotes: 0

Blazemonger
Blazemonger

Reputation: 92903

Why not do it without a template? You'll need to create a JavaScript function that will recurse itself:

function recursive(modules) {
    var arr_html = new Array;
    for (var j=0; j<modules.length; j++) {
        arr_html.push("<ul>");
        arr_html.push("<li>"+modules[j].mod_name+"</li>");
        if (modules[j].sub_modules.length) // it's an array
            arr_html.push(recursive(modules[j].sub_modules));
        arr_html.push("</ul>");
    }
    return arr_html.join("");
}
$('body').append(recursive(my_json.modules));

Upvotes: 0

Related Questions