Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 201
techie.brandon Avatar asked Jul 13 '12 22:07

techie.brandon


2 Answers

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}}
like image 177
Jacob van Lingen Avatar answered Sep 18 '22 15:09

Jacob van Lingen


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}}
like image 121
Kara Brightwell Avatar answered Sep 19 '22 15:09

Kara Brightwell