techie.brandon techie.brandon - 2 months ago 27
Javascript Question

conditional on last item in array using handlebars.js template

I am leveraging handlebars.js for my templating engine and am looking to make a conditional segment display only if it is the last item in array contained in the templates configuration object.

{
columns: [{<obj>},{<obj>},{<obj>},{<obj>},{<obj>}]
}


I've already pulled in a helper to do some equality/greater/less-than comparisons and have had success identifying the initial item this way but have had no luck accessing my target array's length.

Handlebars.registerHelper('compare', function(lvalue, rvalue, options) {...})

"{{#each_with_index columns}}"+
"<div class='{{#equal index 0}} first{{/equal}}{{#equal index ../columns.length()}} last{{/equal}}'>"+
"</div>"+
"{{/each_with_index}}"


Does anyone know a shortcut, different approach, and some handlebars goodness that will keep me from having to tear into the handlebars.js engine to determine best course?

Answer

As of Handlebars v1.1.0, you can now use the @first and @last booleans in the each helper for this problem:

{{#each foo}}
    <div class='{{#if @first}}first{{/if}}
                {{#if @last}} last{{/if}}'>
      {{@key}} - {{@index}}
    </div>
{{/each}}

A quick helper I wrote to do the trick is:

Handlebars.registerHelper("foreach",function(arr,options) {
    if(options.inverse && !arr.length)
        return options.inverse(this);

    return arr.map(function(item,index) {
        item.$index = index;
        item.$first = index === 0;
        item.$last  = index === arr.length-1;
        return options.fn(item);
    }).join('');
});

Then you can write:

{{#foreach foo}}
    <div class='{{#if $first}} first{{/if}}{{#if $last}} last{{/if}}'></div>
{{/foreach}}