Reputation: 2440
I want to create a handlebars helper that works like {{#each}}
but gives me the possibility to specify a number so that every n
iterations some additional code is run.
The reason I need this is that I need to spit out the content in rows of three items, so every three items I need to open and close a new container div.
Of course I could simply let backbone format the array in packages of three items and iterate over that using {{#each}}
but I thought it would be more elegant to create a helper so that I can say something like
{{#each_pack data 3}}
<div class="container">
{{#each pack_items}}
<span>{{content}}</span>
{{/each}}
</div>
{{/each_pack}}
I'm not entirely sure how to do this.
How do I make pack_items
available to the inside block?
Upvotes: 2
Views: 319
Reputation: 2440
I solved this in a way that lets me use the exact same syntax I just proposed. Here is the code:
window.Handlebars.registerHelper('each_pack', function(context, packsize, fn){
var ret = '';
/*
Function that creates packages of size
packsize from a given array
*/
var packagify = function(array, packsize){
var i = 0;
var length = array.length;
var returnArray = [];
var pack = [];
while(i < length){
/*
If this is not the first entry,
if this is the packsize-d entry
or this is the last entry,
push the pack to the return array
and create a new one
*/
if(((i % packsize) == 0 && i != 0) || (i == (length - 1))){
returnArray.push(pack);
pack = [];
}
pack.push(array[i]);
i++;
}
return returnArray;
}
var packArray = packagify(context,packsize);
for(var i = 0; i < packArray.length; i++){
var pack = packArray[i];
this['pack_items'] = pack;
ret = ret + fn(this);
}
delete this['pack_items'];
return ret;
});
Upvotes: 1