Reputation: 737
My jquesy ajax call returns this result.
var clientData = [
{ name: "test1", id: 1, parentid: 0, desc: "test desc1" },
{ name: "test2", id: 2, parentid: 0, desc: "test desc1" },
{ name: "test3", id: 3, parentid: 0, desc: "test desc1" },
{ name: "test1-1", id: 4, parentid: 1, desc: "test desc4" },
{ name: "test1-2", id: 5, parentid: 1, desc: "test desc5" },
{ name: "test2-1", id: 6, parentid: 2, desc: "test desc6" }
];
and i want to create nested ul li listing for this data using jquery template.
like.
can anyone please help me for writing jquery template.
code i created li element using template and appended it to the ul like....
<script id="menuTemplate_inner" type="text/x-jquery-tmpl">
{{if parentid == 0}}
<li class="f_level" id="cat_${id}">
{{else}}
<li class="inner_level" id="cat_${id}">
{{/if}}
${name} (${desc})
</li>
</script>
i dont know the way to make it nested
Upvotes: 0
Views: 1739
Reputation: 262939
First, hierarchical templates are usually fed hierarchical data, so they can invoke sub-templates more naturally. The example below would be a more appropriate representation for your data and lead to simpler templates:
var clientData = [
{ name: "test1", id: 1, parentid: 0, desc: "test desc1", children: [
{ name: "test1-1", id: 4, parentid: 1, desc: "test desc4" },
{ name: "test1-2", id: 5, parentid: 1, desc: "test desc5" }
] },
{ name: "test2", id: 2, parentid: 0, desc: "test desc1", children: [
{ name: "test2-1", id: 6, parentid: 2, desc: "test desc6" }
] },
{ name: "test3", id: 3, parentid: 0, desc: "test desc1" }
];
Now, assuming you cannot change the representation of the data you're working with, you can indeed build a hierarchy of elements from a flat array with a single template, mainly because:
Templates can invoke themselves recursively,
Template invocations can take arguments (an object which is merged with $item
).
If we consider a template as a "regular" function (after all, that's exactly what it gets compiled into), it would make sense to take a parentId
argument and only render the items who match the specified parent. You're already using 0
(no parent) for top-level items, which suits us fine, and allows us to call the function recursively with the current item as the new parent.
Let's start with the first invocation. We need to pass the top-level parent id 0
(but we won't call it parentId
to avoid confusion with the existing parentid
property in your data items). Paradoxically, we also have to pass the data array. This seems redundant because it's already the first argument to tmpl(), but that's because the invoked template only sees the current item, not the original array, unless we explicitly pass it. The resulting code is something like:
$("#menuTemplate_inner").tmpl(clientData, {
clientData: clientData, // Pass original array.
forParent: 0 // Start at top-level.
}).appendTo("ul");
Now, the template itself. It has three tasks to perform:
Render the current item if it matches the parent specified,
Expose the appropriate class (f_level
for top-level, inner_level
otherwise), which can be achieved with the ${} template tag and the ternary conditional operator,
Call itself recursively with the original data array and the current item as the new parent, which is achieved by the {{tmpl}} template tag.
The resulting template is:
<script id="menuTemplate_inner" type="text/x-jquery-tmpl">
{{if parentid == $item.forParent}}
<li class="${ parentid ? 'inner_level' : 'f_level' }" id="cat_${id}">
${name} (${desc})
</li>
<ul>
{{tmpl($item.clientData, {
clientData: $item.clientData,
forParent: id
}) "#menuTemplate_inner"}}
</ul>
{{/if}}
</script>
You can test it in this fiddle.
Upvotes: 2