Condition on the last element of the array using the handlebars.js template

I use handlebars.js for my template engine and want to display a conditional segment only if this is the last element of the array contained in the template configuration object.

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

I already pulled the helper to perform an equality comparison / larger / smaller than the comparison, and was successful in identifying the source element in this way, but I was not able to access my array 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, a different approach and some rudder support that won't let me tear myself away from the handlebars.js mechanism to determine the best course?

+50
javascript arrays templating helpers
Jul 13 '12 at 22:18
source share
5 answers

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

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



A quick helper that I wrote to do the trick:

 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}} 
+72
Aug 17 '12 at 8:23
source share

Since Handlebars 1.1.0, the first and last became native to each assistant. See Ticket # 483 .

Usage is similar to Eberanov's assistant class :

 {{#each foo}} <div class='{{#if @first}}first{{/if}}{{#if @last}} last{{/if}}'>{{@key}} - {{@index}}</div> {{/each}} 
+147
Nov 05 '13 at 8:56
source share

If you just try to process the first element of the array, this may help.

{{#each data-source}}{{#if @index}},{{/if}}"{{this}}"{{/each}}

@index is provided by each helper and for the first element, it will be zero and, therefore, can be processed by the headper.

+24
Feb 19 '13 at 1:58
source share

Decision:

 <div class='{{#compare index 1}} first{{/compare}}{{#compare index total}} last{{/compare}}'></div> 

Using helpers from the next blog and entity ...

https://gist.github.com/2889952

http://doginthehat.com.au/2012/02/comparison-block-helper-for-handlebars-templates/

 // {{#each_with_index records}} // <li class="legend_item{{index}}"><span></span>{{Name}}</li> // {{/each_with_index}} Handlebars.registerHelper("each_with_index", function(array, fn) { var total = array.length; var buffer = ""; //Better performance: http://jsperf.com/for-vs-foreach/2 for (var i = 0, j = total; i < j; i++) { var item = array[i]; // stick an index property onto the item, starting with 1, may make configurable later item.index = i+1; item.total = total; // show the inside of the block buffer += fn(item); } // return the finished buffer return buffer; }); Handlebars.registerHelper('compare', function(lvalue, rvalue, options) { if (arguments.length < 3) throw new Error("Handlerbars Helper 'compare' needs 2 parameters"); operator = options.hash.operator || "=="; var operators = { '==': function(l,r) { return l == r; }, '===': function(l,r) { return l === r; }, '!=': function(l,r) { return l != r; }, '<': function(l,r) { return l < r; }, '>': function(l,r) { return l > r; }, '<=': function(l,r) { return l <= r; }, '>=': function(l,r) { return l >= r; }, 'typeof': function(l,r) { return typeof l == r; } } if (!operators[operator]) throw new Error("Handlerbars Helper 'compare' doesn't know the operator "+operator); var result = operators[operator](lvalue,rvalue); if( result ) { return options.fn(this); } else { return options.inverse(this); } }); 

Please note that the starting index is correct.

+1
Jul 16 2018-12-12T00:
source share

I improved the assistant from Matt Brennan a bit, you can use this assistant with objects or arrays, this solution is required by the Underscore library:

 Handlebars.registerHelper("foreach", function(context, options) { options = _.clone(options); options.data = _.extend({}, options.hash, options.data); if (options.inverse && !_.size(context)) { return options.inverse(this); } return _.map(context, function(item, index, list) { var intIndex = _.indexOf(_.values(list), item); options.data.key = index; options.data.index = intIndex; options.data.isFirst = intIndex === 0; options.data.isLast = intIndex === _.size(list) - 1; return options.fn(item, options); }).join(''); }); 

Using:

 {{#foreach foo}} <div class='{{#if @first}}first{{/if}}{{#if @last}} last{{/if}}'>{{@key}} - {{@index}}</div> {{/foreach}} 
0
Oct 02 '13 at 16:57
source share



All Articles