ng:repeat - group and limit

15,400 views
Skip to first unread message

marlus araujo

unread,
Mar 4, 2012, 3:59:14 PM3/4/12
to ang...@googlegroups.com
Hello there!

I'm using Twitter Bootstrap for an app because of its styles and grid layout. In order to create a 3x2 grid, I have to do this

<div class="row">
   <div class="span4">item 1</div>
   <div class="span4">item 2</div>
   <div class="span4">item 3</div>
</div>

<div class="row">
   <div class="span4">item 4</div>
   <div class="span4">item 5</div>
   <div class="span4">item 6</div>
</div>

How can I use ng:repeat preserving <div class="row"> for 3 elements counting?

And how can I limit the number of items shown with ng:repeat?

Thanks in advance

Cheers

Marlus,

Eric Jain

unread,
Mar 4, 2012, 8:56:33 PM3/4/12
to AngularJS
On Mar 4, 12:59 pm, marlus araujo <mar...@gmail.com> wrote:
> How can I use ng:repeat preserving <div class="row"> for 3 elements
> counting?
>
> And how can I limit the number of items shown with ng:repeat?

You could have a getRows(itemsPerRow) method in the controller that
returns an array of arrays, and then:

<div class="row" ng:repeat="row in getRows(3)">
<div class="span4" ng:repeat="item in row">{{item}}</div>
</div>

But perhaps there is a better solution that avoids putting view logic
into the controller...

Vojta Jína

unread,
Mar 4, 2012, 9:10:04 PM3/4/12
to ang...@googlegroups.com
I think Eric's solution is fine - was just about to post the same thing :-D

V.

marlus araujo

unread,
Mar 5, 2012, 7:04:49 AM3/5/12
to ang...@googlegroups.com
But perhaps there is a better solution that avoids putting view logic
into the controller...

I agree with you, Eric. But thank you for your response!

Vojta Jína

unread,
Mar 7, 2012, 4:53:41 AM3/7/12
to ang...@googlegroups.com
Where would you put view logic ? I think controller is absolutely fine place. It prepares the data for rendering...

V.

Al...@enplug.com

unread,
Jul 31, 2012, 4:02:21 AM7/31/12
to ang...@googlegroups.com
Just wanted to reply to this because I stumbled upon it while looking for solutions myself... to limit the number of items shown with ng-repeat isn't it best just to use the limitTo filter? I'm assuming this thread was written before the limitTo filter was an option, but I thought I'd chime in.

Philipp Burgmer

unread,
Jul 31, 2012, 7:30:21 AM7/31/12
to ang...@googlegroups.com, Al...@enplug.com
You're right, AngularJS's filter are a great tool for thing like that.
Not sure how to name it ("stacked, nested, grouped", ...), but perhaps we can integrate a filter like this one into angular. What do you think?

Andy Joslin

unread,
Jul 31, 2012, 2:43:27 PM7/31/12
to ang...@googlegroups.com
You could also create a 'startFrom' filter, and use it in conjunction with Angular's 'limitTo'.

Andy Joslin

unread,
Jul 31, 2012, 2:43:47 PM7/31/12
to ang...@googlegroups.com
Forgot the link: http://jsfiddle.net/YUVWP/

ProLoser

unread,
Jul 31, 2012, 4:29:37 PM7/31/12
to ang...@googlegroups.com
I don't get why you can't just splice. Lets you specify a start and an end.

On Tuesday, July 31, 2012 11:43:47 AM UTC-7, Andy Joslin wrote:
Forgot the link: http://jsfiddle.net/YUVWP/

Andy Joslin

unread,
Jul 31, 2012, 6:42:55 PM7/31/12
to ang...@googlegroups.com
Splice modifies the array doesn't it?

Andy Joslin

unread,
Jul 31, 2012, 6:43:10 PM7/31/12
to ang...@googlegroups.com
So I'd have to do angular.copy(array).splice, which seems slower.

Andy Joslin

unread,
Jul 31, 2012, 6:47:05 PM7/31/12
to ang...@googlegroups.com
So apparently, as someone just showed me, Javascript has a slice function (which does work in all browsers). So you could just do

<div class="group1"><span ng-repeat="item in items.slice(0,3)"></div>
<div class="group2"><span ng-repeat="item in items.slice(3,6"></div>

Ricardo Bin

unread,
Jul 31, 2012, 6:47:49 PM7/31/12
to ang...@googlegroups.com
Slice doesnt =)

Ricardo Bin

unread,
Jul 31, 2012, 7:14:53 PM7/31/12
to ang...@googlegroups.com
Yes!

I use this way to limit arrays in angular.

Philipp Burgmer

unread,
Aug 1, 2012, 6:08:07 AM8/1/12
to ang...@googlegroups.com
Limit, StartFrom and Splice are options if you know how many items you have.
I think the group filter, which I posted, has the advantage to be independent of the number of items.
With all the other options, you do a outer repeat manually to create the rows and you have to know how many items will be there.

What do you think?

Dean Sofer

unread,
Aug 1, 2012, 6:27:59 AM8/1/12
to ang...@googlegroups.com
Actually Philipp, you may have a point. Rereading the original question it appears we got a little off topic.

I started to think of ways I could quickly take an array and return a new array of slices of the original, but off the top of my head I don't have a quick solution. 

In that situation, your filter might be kinda handy. You should fork AngularUI and submit a pull request :) although the logic could be cleaned up a little.

Honestly though, I tend to do the aforementioned solely using CSS. 

I find that even the use of a filter (or angular itself) to control this sort of view-specific logic is too restrictive. If you use CSS floats (to auto-wrap) and percentage widths, or simply use the new CSS columns then you can adjust how many columns you have per row on a device/screen-size basis, allowing for responsive design.

Not to mention no unnecessary wrapper DOM elements :)

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular?hl=en.
 
 



--
Dean J Sofer
Dean...@gmail.com

BS Computer Information Systems
California State Polytechnic University, Pomona
Telephone: 714-900-2254
Website: www.DeanSofer.com 

Philipp Burgmer

unread,
Aug 1, 2012, 7:07:30 AM8/1/12
to ang...@googlegroups.com
I agree, the best solution would be to handle this via CSS completely. Unfortunately this is quite complicated and not all browser support it.
So for the next few year (hopefully) we will need a markup workaround like bootstrap uses.

Finally I think I found a better name: inSlicesOf. 
As you proposed Dean, I will fork AngularUI and submit a pull request with the filter.


Am Mittwoch, 1. August 2012 12:27:59 UTC+2 schrieb ProLoser:
Actually Philipp, you may have a point. Rereading the original question it appears we got a little off topic.

I started to think of ways I could quickly take an array and return a new array of slices of the original, but off the top of my head I don't have a quick solution. 

In that situation, your filter might be kinda handy. You should fork AngularUI and submit a pull request :) although the logic could be cleaned up a little.

Honestly though, I tend to do the aforementioned solely using CSS. 

I find that even the use of a filter (or angular itself) to control this sort of view-specific logic is too restrictive. If you use CSS floats (to auto-wrap) and percentage widths, or simply use the new CSS columns then you can adjust how many columns you have per row on a device/screen-size basis, allowing for responsive design.

Not to mention no unnecessary wrapper DOM elements :)

On Wed, Aug 1, 2012 at 3:08 AM, Philipp Burgmer <ma...@deflip.de> wrote:
Limit, StartFrom and Splice are options if you know how many items you have.
I think the group filter, which I posted, has the advantage to be independent of the number of items.
With all the other options, you do a outer repeat manually to create the rows and you have to know how many items will be there.

What do you think?

Am Mittwoch, 1. August 2012 01:14:53 UTC+2 schrieb Ricardo Bin:
Yes!

I use this way to limit arrays in angular.

Em terça-feira, 31 de julho de 2012 19h47min05s UTC-3, Andy Joslin escreveu:
So apparently, as someone just showed me, Javascript has a slice function (which does work in all browsers). So you could just do

<div class="group1"><span ng-repeat="item in items.slice(0,3)"></div>
<div class="group2"><span ng-repeat="item in items.slice(3,6"></div>

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+unsubscribe@googlegroups.com.

chris...@gmail.com

unread,
Aug 1, 2012, 5:16:35 PM8/1/12
to ang...@googlegroups.com
@Andy It is the splice method does inplace changes to array.

I thought I would be able to do this:

<div ng-repeat="item in items | filter:'$index > start && $index < limit'>
</div>

I think a single filter should be able to do both start and limit instead of having 2 separate ones. limitTo would have no idea what the startFrom did. This should be a enhancement to the limitTo filter rather than creating a new one.

Chris.

gsm

unread,
Aug 4, 2012, 3:53:12 PM8/4/12
to ang...@googlegroups.com
Maybe you could try a css solution like this (if you're not too bothered with old browsers):

.row .span4:nth-child(3n+1) {
  clear:both;
  margin-left:0;
}

cheers,
Dominique


Op zondag 4 maart 2012 21:59:14 UTC+1 schreef marlus araujo het volgende:

Pawel Kozlowski

unread,
Aug 4, 2012, 4:02:39 PM8/4/12
to ang...@googlegroups.com
hi!

CSS solution will leave nodes in the DOM....

Cheers,
Pawel
> --
> You received this message because you are subscribed to the Google Groups
> "AngularJS" group.
> To post to this group, send email to ang...@googlegroups.com.
> To unsubscribe from this group, send email to
> angular+u...@googlegroups.com.

Dominique Callewaert

unread,
Aug 4, 2012, 4:06:12 PM8/4/12
to ang...@googlegroups.com
Hi Pawel

is there somewhere where I can find info on this?
I'm very new to Angular and working on something where I used that css solution right now...

D
--
Dominique Callewaert - WetNet

Jetse Steenweg 400 B11 - 1081 Koekelberg
02 4281911

Tiago Duarte

unread,
Feb 28, 2013, 9:02:41 AM2/28/13
to ang...@googlegroups.com, g...@wetnet.com
you can do limitTo:5 ex.: <li ng-repeat="name in names | limitTo:5">{{name}}</li>

here is a fiddle: http://jsfiddle.net/Nu7rZ/

Tiago Duarte

unread,
Feb 28, 2013, 9:03:58 AM2/28/13
to ang...@googlegroups.com
here is a fiddle with the solution using limitTo:xxx in a ng-repeat http://jsfiddle.net/Nu7rZ/ ;) as always simple!!

Hugo Dias

unread,
Jun 3, 2013, 10:01:52 AM6/3/13
to ang...@googlegroups.com, Al...@enplug.com
Great solution Philipp, thank you.

Rafael Dipold

unread,
Jun 19, 2013, 9:47:32 AM6/19/13
to ang...@googlegroups.com, Al...@enplug.com
Hi guys,

The Phillip filter is nice but his function is called N times during the iteration.

I am reaching to this error:

Error: 10 $digest() iterations reached. Aborting! 

So, I make some changes in your original filter to (http://jsbin.com/isagac/1/edit):

angular.module('app', [])
.filter('inSlicesOf', 
['$rootScope',  
function($rootScope) {
makeSlices = function(items, count) { 
if (!count)            
count = 1;
if (!angular.isArray(items) && !angular.isString(items)) return items;
var array = [];
for (var i = 0; i < items.length; i++) {
var chunkIndex = parseInt(i / count, 10);
var isFirst = (i % count === 0);
if (isFirst)
array[chunkIndex] = [];
array[chunkIndex].push(items[i]);
}

if (angular.equals($rootScope.arrayinSliceOf, array))
return $rootScope.arrayinSliceOf;
else
$rootScope.arrayinSliceOf = array;
return array;
};
return makeSlices; 
}]
);

Pulkit Singhal

unread,
Mar 20, 2014, 2:38:50 PM3/20/14
to ang...@googlegroups.com, Al...@enplug.com
Rafael's code is spot on! Here's an ionic-framework copy/paste adaptation of his work for folks to play around with: http://codepen.io/pulkitsinghal/pen/JjmED/


On Wednesday, June 19, 2013 8:47:32 AM UTC-5, Rafael Dipold wrote:
Hi guys,

The Phillip filter is nice but his function is called N times during the iteration.

Moshe Levi

unread,
Mar 22, 2014, 10:11:16 AM3/22/14
to ang...@googlegroups.com, Al...@enplug.com
Can you please elaborate on the issue with Philip's solution and your suggested fix?

Thanks,
Reply all
Reply to author
Forward
0 new messages