Reputation: 15303
I have a sample object with which I am trying to make a navigation bar, with each li
to have a custom class name like this:
<ul>
<li class="mainLink1">
<a href="m1/home.html">home</a>
<ul class="subParent1">
<li class="sublink1"><a href="s1/home.html">s1/home</a></li>
<li class="sublink2"><a href="s2/home.html">s2/home</a></li>
</ul>
</li>
<li class="mainLink2">
<a href="m2/service.html">service</a>
<ul class="subParent2">
<li class="sublink1"><a href="s1/service.html">s1/service</a></li>
<li class="sublink2"><a href="s2/service.html">s2/service</a></li>
</ul>
</li>
</ul>
I know that all these class names have to be generated by a helper function, but I'm confused because I could not get proper results. Here is my try.
My html with template:
<div id="navigate"></div>
<script type="text/handlebars-x-template" id="menu">
<ul>
{{#list}}
<li><a href="{{link}}">{{name}}</a></li>
{{#if list.sub}}
<ul>
{{#each this}}
<li><a href="{{link}}">{{name}}</a></li>
{{/each}}
</ul>
{{/if}}
{{/list}}
</ul>
</script>
My helper function and implementation:
var obj = [{"name":"home","link":"m1/home.html","sub":[{"sname":"s1/home","slink":"s1/home.html"},{"sname":"s/home","slink2":"s2/home.html"}]},{"name":"service","link":"m2/service.html","sub":[{"sname":"s1/service","slink":"s1/service.html"},{"sname":"s/service","slink2":"s2/service.html"}]}]
Handlebars.registerHelper("list", function(context, option){
console.log(context, option);
})
var temp = Handlebars.compile($("#menu").html());
var html = $("#navigate").html(temp(obj));
I agree that my try is very bad. Any help to correct it and make to apply the class names using @index property.
Upvotes: 2
Views: 6207
Reputation: 55750
First your custom helper
has no context , this is nothing but the context object that is passed in with the name of the helper
Handlebars.registerHelper("list", function(context, option) {
So by default context
argument will be options
Context is the one that is passed to the helper
{{#list this}}
^------ This is the context
Next your object is an Array of objects, so your approach will not work. You would require to either change the way you are using the template structure, or iterate over the object and pass in a single object to your template..
And there is no key
called list
that holds the sub
property
{{#if list.sub}}
Supposed to be
{{#if this.sub}}
Code
Handlebars.registerHelper("list", function(context, options) {
// Return fn from options that will pass in the object to
// the truthy function
console.log(context + ' :: ' + options);
return options.fn(this);
})
// Compile your template
var temp = Handlebars.compile($("#menu").html());
var $ul = $('#navigate > ul');
// Append it to the container after iterating over array of objects
for(var i=0; i<obj.length; i++) {
$ul.append(temp(obj[i]));
}
UPDATE
Then in that case you would not require the template helper in the first place. Just use the each
loop and @index
to iterate over the lists.
Template
<script type="text/handlebars-x-template" id="menu">
{{#each this}}
<li class="mainLink{{@index}}">
<a href="{{link}}">{{name}}</a>
{{#if this.sub}}
<ul class="subParent{{@index}}">
{{#each this.sub}}
<li class="sublink{{@index}}"><a href="{{slink}}">{{sname}}</a></li>
{{/each}}
</ul>
{{/if}}
</li>
{{/each}}
</script>
Upvotes: 2