Search code examples
twitter-bootstrapember.jshandlebars.js

ember - How to correctly add bootstrap rows/cols based on number of records in model?


I have a route groups.index that showcases all the groups in my app. In the route I use the this.store.findAll('group'); to fetch all the groups and in the groups.index template I use the each to go through each group. I want to make it so that each group is contained within a bootstrap col-md-3 class, so that I can make 4 "panels" for each row showcasing the groups.

I made a helper class for handlebars that determines whether the index is at 0, or a multiple of 5, to determine where to start a row. I then use the same function to determine whether the index is a multiple of 4 to determine where to add the closing tag for a row. However I get a build error since I am not closing the divs within each {{#if}} block. Is there a way to make this work? Or is there a simpler way that I am missing?

groups.index template

{{#each model as |group index|}}

{{#if (isMultiple index 5)}}
<div class='row'>
{{/if}}

<div class='col-md-3'>
{{#link-to 'groups.show' group.id}}{{group.name}}{{/link-to}}
</div>

{{#if (isMultiple index 4)}} 
</div>
{{/if}}


{{/each}}

helper function

export function isMultiple(params) {
  if (params[0] == 0) {
    return true;
  }
  const index = params[0] + 1;
  const multiple = params[1];
  return (index % multiple == 0);
}

export default Ember.Helper.helper(isMultiple);

Solution

  • Create computed property depends on the model property. and chunk model by 4 and iterate it in hbs.

    For preparing the model,

    import Ember from 'ember';
    import _array from 'lodash/array';
    export default Ember.Controller.extend({
        chunkSpan: 4,
        resultModel: Ember.computed('model', function() {
            return _array.chunk(this.get('model').toArray(), this.get('chunkSpan'));
        }),
    });
    

    To install lodash, check this answer

    To iterate it in hbs,

    {{#each resultModel as |item|}}
            <div class='row'>
                {{#each item as |group|}}
                        <div class='col-md-3'>
                            {{#link-to 'groups.show' group.id}}{{group.name}}{{/link-to}}
                    </div>
            {{/each}}
        </div>
    {{/each}}
    

    This is one way of approach. there may be other simple approaches to this.