Tim
Tim

Reputation: 2440

Iterating over an array in packages

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

Answers (1)

Tim
Tim

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

Related Questions