sachin kulkarni
sachin kulkarni

Reputation: 737

Nested list using jquery template

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

Answers (1)

Fr&#233;d&#233;ric Hamidi
Fr&#233;d&#233;ric Hamidi

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

Related Questions