Thanks for taking the time to read this, I was wondering how I might be able to use ng-repeat to create a grid like box of options. I would like to take an array repeat nth number of items and then move to the next row or column until all items are listed. e.g.
assuming I had an array like [opt1,opt2,opt3,opt4,opt5,opt6,opt7]
I would like to display it like this:
opt1 opt2 opt3
opt4 opt5 opt6
opt7
I find it easier to simply use ng-repeat combined with ng-if and offsetting any indexes using $index. Mind the jade below:
Sorry for my HAML and Bootstrap3:
There is another version, with possibility to use filters:
If all of your items are in one single array, your best bet is to make a grid in CSS. This article should be helpful: http://css-tricks.com/dont-overthink-it-grids/
You can use $index from ng-repeat to apply the correct class for your column (in this case a 4 column grid):
If you have a 2 dimensional array (split into rows and columns) that opens up more possibilities like actually using an HTML table.
Between Performance, Dynamics and Readability
It seems putting the logic in your JavaScript is the best method. I would just bite-the-bullet and look into:
You can then create an angular
filter
to handle this:Filter:
Controller:
View:
With this, you can see you get
n
number of rows -- each containing "3
" columns. When you change the number of desired columns, you'll notice the number of rows changes accordingly (assuming the list-length is always the same ;)).Here's a fiddle.
Note, that you get the ol'
Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
. This is because Angular is recalling thematrical
function upon every iteration. Allegedly, you can use theas results
alias to prevent Angular from reevaluating the collection, but I had no luck. For this, it may be better to filter the grid inside of your controller and use that value for your repeater:$filter('matrical')(items)
-- but please post back if you come across an elegant way of filtering it in theng-repeat
.I would stress, again, you're probably heading down a dark alley by trying to write the logic in your view -- but I encourage you to try it in your view if you haven't already.
Edit
The use of this algorithm should be combined with a Matrical Data-Structure to provide methods of
push
,pop
,splice
, and additional methods -- in tandem with appropriate logic to complement Bi-Directional Data-Binding if desired. In other words, data-binding will not work out of the box (of course) as when a new item is added to your list, a reevaluation of the entire list must take place to keep the matrix's structural integrity.Suggestion: Use the
$filter('matrical')($scope.list)
syntax in combination with$scope.$watch
and recompile/calculate item-positions for the matrix.Cheers!
This is more a styling/markup problem than an AngularJS one. If you really want to, you can do:
http://jsfiddle.net/JG3A5/