84

I’m new to Handlebars.js and just started using it. Most of the examples are based on iterating over an object. I wanted to know how to use handlebars in basic for loop.

Example.

for(i=0 ; i<100 ; i++) {
   create li's with i as the value
}

How can this be achieved?

5 Answers 5

195

There's nothing in Handlebars for this but you can add your own helpers easily enough.

If you just wanted to do something n times then:

Handlebars.registerHelper('times', function(n, block) {
    var accum = '';
    for(var i = 0; i < n; ++i)
        accum += block.fn(i);
    return accum;
});

and

{{#times 10}}
    <span>{{this}}</span>
{{/times}}

If you wanted a whole for(;;) loop, then something like this:

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

{{#for 0 10 2}}
    <span>{{this}}</span>
{{/for}}

Demo: http://jsfiddle.net/ambiguous/WNbrL/

Sign up to request clarification or add additional context in comments.

12 Comments

+1 for the helpers. As a side note, nesting the for helper won't work in scenarios where you need to refer back to the initial data. i.e data: { rows : 12, cols: 3}.
When printing {{../this}} inside a nested {{#times}} block I've noticed that sometimes it will be [Object object] instead of the actual numer (one time per nested loop).
@dude Do you have a runnable example of that? I haven't touched Handlebars for a couple years.
Inside the loop, I cannot retrieve data from handlebar, do you guys have any ideas about it?
@Longblog Sorry, haven't used Handlebars in years so I'm not sure. You could compute the index yourself given this and the loop's from and incr or perhaps call the block.fn with an object containing whatever you need.
|
26

Top answer here is good, if you want to use last / first / index though you could use the following

Handlebars.registerHelper('times', function(n, block) {
    var accum = '';
    for(var i = 0; i < n; ++i) {
        block.data.index = i;
        block.data.first = i === 0;
        block.data.last = i === (n - 1);
        accum += block.fn(this);
    }
    return accum;
});

and

{{#times 10}}
    <span> {{@first}} {{@index}} {{@last}}</span>
{{/times}}

1 Comment

This helper seems to not allow to use @../index or @../last when coming to nested uses of the Helper. Is this right or maybe I did something wrong?
9

If you like CoffeeScript

Handlebars.registerHelper "times", (n, block) ->
  (block.fn(i) for i in [0...n]).join("")

and

{{#times 10}}
  <span>{{this}}</span>
{{/times}}

Comments

8

This snippet will take care of else block in case n comes as dynamic value, and provide @index optional context variable, it will keep the outer context of the execution as well.

/*
* Repeat given markup with given times
* provides @index for the repeated iteraction
*/
Handlebars.registerHelper("repeat", function (times, opts) {
    var out = "";
    var i;
    var data = {};

    if ( times ) {
        for ( i = 0; i < times; i += 1 ) {
            data.index = i;
            out += opts.fn(this, {
                data: data
            });
        }
    } else {

        out = opts.inverse(this);
    }

    return out;
});

1 Comment

I like this approach better because you have the @index variable at hand. Also you can easily add other variables depending on specific needs.
7

Couple of years late, but there’s now each available in Handlebars which allows you to iterate pretty easily over an array of items and provides a variable called @index.

https://handlebarsjs.com/guide/builtin-helpers.html#each

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.