4

I'm using Angular and ng-repeat as well as Semantic UI Grid layout.

I'm trying to display 5 columns in a row. When the fifth item is reached create a new row. The below creates a new row and column for each item in the data. I can see there is an index property with ng-repeat but not sure how to basically say if mod 5 == 0 output a new row element else just output a new column.

<div class="ui grid">
    <div class="row" ng-repeat="item in data.results">
        <div class="column">
            <div class="ui segment">
                {{item.original_title}}
            </div>
        </div>
    </div>
</div>

Thanks for the help

2
  • In my opinion the cleanest way would be to write a small, new directive for this. Commented Nov 17, 2013 at 20:54
  • And how would that look ;) Commented Nov 17, 2013 at 22:05

3 Answers 3

4

The cleanest and most maintainable way would be in my opinion to write a directive. In your HTML you simply have:

<grid source="data.results" break="5" />

And in your JS you break your data into the correct structure within the controller and output it using the template:

    angular.module('yourApp', [])
    .directive('grid', function() {
      return {
          restrict: 'E',
          scope: {
            break: '=break',
            source: '=source'
          },
          controller: function($scope) {
            var total = Math.ceil($scope.source.length / $scope.break);
            $scope.data = new Array(total);
            for (var i = 0; i < total; ++i) {
              $scope.data[i] = $scope.source.slice(i * $scope.break, (i + 1) * $scope.break);
            }
          },
          template:
            '<div class="ui grid">' +
            '  <div class="row" ng-repeat="row in data">' +
            '    <div class="column" ng-repeat="item in row">' +
            '      <div class="ui segment">' +
            '        {{item.original_title}}' +
            '      </div>' +
            '    </div>' +
            '  </div>' +
            '</div>',
          replace: true
      };
  });
Sign up to request clarification or add additional context in comments.

Comments

3

Here's one way to approach this that uses a range filter.

We calculate how many rows you'll need (data.results.length/5) and then iterate over that number of rows using ng-repeat with the range filter.

Then within each row we slice out the columns needed for that row and create those columns with another ng-repeat.

<div class="row" ng-repeat="n in [] | range:(data.results.length/5)+1">
    <span ng-repeat='item in data.results.slice($index*5,($index*5+5))'>
        <div class="column">
           <div class="ui segment">
              {{item.original_title}}
           </div>
        </div>
    </span>
</div>

and the associated range filter (from: http://www.yearofmoo.com/2012/10/more-angularjs-magic-to-supercharge-your-webapp.html#more-about-loops):

app.filter('range', function () {
  return function (input, total) {
    total = parseInt(total);
    for (var i = 0; i < total; i++) {
        input.push(i);
    }
    return input;
};

Here's a fiddle of this: http://jsfiddle.net/BMrNs/1/

Comments

2

Try using ng-switch in combination with Array.slice() It's not the most efficient method but if you don't have any way to meddle with data representation, this is the best I can think of.

<div class="ui grid">
    <div ng-repeat="item in data.results">
        <div ng-switch on="$index % 5">
            <div ng-switch-when="0" class="row">
                <div ng-repeat="e in data.results.slice($index, $index + 5)">
                      <div class="column">
                          <div class="ui segment">
                              {{e.original_title}}
                          </div>
                      </div>
                </div>
            </div>
        </div>
    </div>
</div>

3 Comments

The row markup is just a div with a class 'row' as you can see in the question which is where the ng-repeat sits so not sure what I would loop on
Sorry misunderstood the question. I'll edit my answer. The idea stays though.
The column div then goes inside the row div, if that makes sense, so 5 columns in a row, then a new row with columns etc

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.