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?


Solution 1:

Since Handlebars 1.1.0, first and last has become native to the each helper. See ticket #483.

The usage is like Eberanov's helper class:

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

Solution 2:

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}}