Figuring out how to properly insert line break with {{#each}}


#1

I’m using meteor 1.8. I have a collection, and i should display only 5 elements per row,

i have code like this:

Template.tasks.helpershelpers({
    tasks: function(counter){
        return Tasks.find({}, {limit: Template.instance().max.get()});
});

So from helper limited number of tasks returned, then i display the button to load more.

html

{{#if Template.subscriptionsReady}}


    <div class="tasks">
            <div class="row">

            {{#each tasks}}
                <h5>{{this.data}}</h5> <!--and so on-->
            {{/each}}
        </div>
    </div>

        {{#if needsData}}
              <button type="button" class="btn btn-primary" id="needs-data">Load More</button>
        {{/if}}

    {{else}}
        {{>waitforme}}
    {{/if}}

I have a question, how can i display only 5 elements in each loop, and then conditionally insert break? so each 5 elements would be wrapped into :slight_smile:

<div class="tasks">
            <div clas s="row">
            <!--5 elements -->
            </div>
           <div clas s="row">
            <!--5 elements -->
            </div>
            <!--etc-->
</div>

so pseudocode:



            <div class="row">

for(i = 0; i < tasks.count(); i++)
{
    

    if(i + 1 % 5 == 0){
         </div>
            <div class="row">
    }
}

Something like this. I tried creating a helper to check for current index:

breakme: function(counter){
        if(counter == 0){
            return true;
        }
        else if(counter % 5 == 0)
            return true;

        return false;
    }

and in my template:

<div class="tasks">
            
            {{#each tasks}}
              {{#if breakme @index}}
                 <div class="row">
              {{/if}}
                <h5>{{this.data}}</h5> <!--and so on-->
              {{#if breakme @index}}
                 </div>
              {{/if}}
            {{/each}}
              
    </div>

#2

Unfortunately because the HTML is compiled you can’t do that - instead, have a helper which returns an array of cursors, or an array of arrays

tasks() {
const tasks = [];
let counter = 0;
Tasks.find().forEach(t => {
 if (!tasks[counter]) {
    tasks.push([]);
  }
  tasks[counter].push(t);
  if (tasks[counter].length === 5) {
    counter++;
  }
});
return tasks;
}

then in your template

{{#each taskList in tasks}}
<div class="row">
 {{#each task in taskList}}
   ...
 {{/each}}
</div>
{{/each}}

#3

Hi, not sure whether you only need a visual thing or there is some more logic you want to put in place. If you only want a visual thing you can use in general flex positioning, % width and css…

.your-cssclass { width: 20% }
.your-cssclass:nth-child(5), .your-cssclass:nth-child(10),
.your-cssclass:nth-child(15)... { ... do something with every 5th element }