I\'m trying to create a grid using bootstrap 3 and angularjs.
The grid I\'m trying to create is this, repeated using ng-repeat.
This should work
<div ng-repeat="item in items">
<div ng-class="{row : ($index % 3 == 0)}">
...
</div>
</div>
An Angular2 version of @CodeExpress's pure angular solution.
alphabet: string[] = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
<div *ngIf='alphabet && alphabet.length'>
<div *ngFor='#letter of alphabet; #i = index' >
<div class="row" *ngIf='i % 4 == 0'>
<div class="col-md-3" *ngFor='#n of [i,i+1,i+2,i+3]'>
{{alphabet[n]}}
</div>
</div>
</div>
</div>
The accepted answer is the obvious solution however presentation logic should remain in view and not in controllers or models. Also I wasn't able to get the OP's solution to work.
Here are two ways to do create grid system when you have a flat list(array) of items. Say our item list is a alphabet:
Plunker here
$scope.alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
This is a pure angular solution.
<div class="row" ng-repeat="letter in alphabet track by $index" ng-if="$index % 4 == 0">
<div class="col-xs-3 letter-box"
ng-repeat="i in [$index, $index + 1, $index + 2, $index + 3]"
ng-if="alphabet[i] != null">
<div>Letter {{i + 1}} is: <b> {{alphabet[i]}}</b></div>
</div>
</div>
The outer loop execute after every 4 iterations and creates a row. For each run of the outer loop the inner loop iterates 4 times and creates columns. Since the inner loop runs 4 times regardless of whether we have elements in array or not, the ng-if
makes sure that no extraneous cols are created if the array ends before inner loop completes.
This is much simpler solution but requires angular-filter library.
<div class="row" ng-repeat="letters in alphabet | chunkBy:4">
<div class="col-xs-3 letter-box" ng-repeat="letter in letters" >
<div>Letter {{$index + 1}} is: <b> {{letter}}</b></div>
</div>
</div>
The outer loop creates groups of 4 letters, corresponding to our 'row'
[['A', 'B', 'C', 'D'], ['E', 'F', 'G', 'H'], ... ]
The inner loop iterates over the group and creates columns.
Note: Method 2 might require evaluation of filter for each iteration of outer loop, hence method 2 may not scale very well for huge data sets.
One might say that the below solution does not follow the grid rules of having row
divs, but another solution would be to drop the row
class ( or use it outside of the ng-repeat
) and use the clearfix
class instead:
<div class="col-md-12">
<div ng-repeat="item in items">
<div ng-class="{'clearfix': $index%3 === 0}"></div>
<div class="col-md-4">{{item}}</div>
</div>
</div>
As far as I can see, this looks almost the same as with row
class, but please comment on possible flaws (except the one I mentioned above).
A bit late answer but i used this and i belive it is better for some cases. You can use Angular Filter package and its ChunkBy filter for this. Although this package would be a heavy lifting for this single task, there is other useful filters in it for different tasks. The code i used is like this:
<div class="row mar-t2" ng-repeat="items in posts | chunkBy:3">
<div class="col-md-4" ng-repeat="post in items">
<img ng-src="{{post.featured_url}}" class="img-responsive" />
<a ng-click="modalPop(post.id)"><h1 class="s04-bas2">{{post.title.rendered}}</h1></a>
<div class="s04-spotbox2" ng-bind-html="post.excerpt.rendered"></div>
</div>
</div>