Search code examples
backbone.jshandlebars.jshandlebarshelper

handlebars get index for loop


I have an helper written in backbone and handlebars and I need to get index of the for loop inside.

This is my helper

 Handlebars.registerHelper('for', function(from, to, incr, block) {
        var accum = '';
        for(var i = from; i < to; i += incr)
            accum += block.fn(i);
        return accum;
    });

And this is my template:

{{#each rows}}
    <div class="row">
        {{#for 0 10 1}}
            <div class="edit-column" data-id="{{@index}}">
            </div>
        {{/for}}
    </div>
{{/each}}

I woudl like that {{@index}} print the index of the for loop, now it prints the counter of {{#each rows}} loop

How can I get index of the for loop?


Solution

  • You're looking to inject private variables into your templates :

    Block helpers can also inject private variables into their child templates. This can be useful to add extra information that is not in the original context data.

    For example, when iterating over a list, you may provide the current index as a private variable.

    You just have to provide a data entry in the options you pass to your block function (and ensure the coherence of the child data object with Handlebars.createFrame)

    A modified helper exposing an @index key:

    Handlebars.registerHelper('for', function(from, to, incr, block) {
        var data;
    
        if (block.data) {
            data = Handlebars.createFrame(block.data);
        }
    
        var accum = '';
        for(var i = from; i < to; i += incr) {
            if (data) {
              data.index = i;
            }
            accum += block.fn(i, {data: data});
        }
        return accum;
    });
    

    and a demo

    Handlebars.registerHelper('for', function(from, to, incr, block) {
        var data;
    
        if (block.data) {
            data = Handlebars.createFrame(block.data);
        }
    
    
        var accum = '';
        for(var i = from; i < to; i += incr) {
            if (data) {
              data.index = i;
            }
            accum += block.fn(i, {data: data});
        }
        return accum;
    });
    
    var tpl = Handlebars.compile($('#rows').html());
    $('body').append(tpl({
        rows: [1, 2]
    }));
    .edit-column {padding-left: 10px}
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"></script>
    
    <script type='text/template' id='rows'>
    {{#each rows}}
        <div class="row">{{@index}}
            {{#for 0 3 1}}
                <div class="edit-column">{{@../index}}:{{@index}}</div>
            {{/for}}
        </div>
    {{/each}}
    </script>