Home Ask Login Register

Developers Planet

Your answer is one click away!

lilbiscuit February 2016

How to create a horizontal grid using ng-repeat and fixed number of rows

I have a simple array of text objects that I want to display in a grid. This is using the Ionic framework.

The grid must be:

  1. Fixed height
  2. Exactly 3 rows
  3. Horizontal scroll (infinite columns)
  4. 2 visible columns with screen width < 768px (phones), 4 visible columns 768px and above (tablets)

I have the media query for the column widths and am using for the horizontal scrolling functionality.

How can I use ng-repeat (maybe with ngif ??) to create the grid, starting in the first column and filling that column with 3 rows before moving to the next column etc etc)

JS

var items = [
{text: "This is item1"},
{text: "This is item2"},
{text: "This is item3"},
.
.
.
]

CSS:

.myGridRow {
  height: 40%;
 }
 .myGridCol {
   width: 50%;
 }
 @media only screen and (min-width : 768px) {
   .myGridCol {
     width: 25%;
   }
 }

HTML

<ion-scroll direction="x">
 <div class="row myGridRow"> <!-- The single container for the whole grid -->

  <div ng-repeat="item in items"> <!-- only do this 3 times before starting a new row -->
   <div class="row"><div class="col myGridCol">{{item.text}}</div></div>
  </div>

</div>
</ion-scroll>

Desired Output

I am stuck here trying to determine how to move to the next column after each 3 rows, or if this is even the right way to do this.

Answers


gnerkus February 2016

ng-repeat is constrained to iterate over a collection and will not work with an integer as input. However, you can create a placeholder collection for the number of repetitions required:

$scope.items = [/* The base collection */];
$scope.iterCount = 3; // The number of iterations before a new row is created
$scope.itemCount = Math.floor($scope.items.length / $scope.iterCount);

// Get a collection of items equally spaced from each other. For
// example: getSpacedItems([1, 2, 3, 4], 0, 2) == [1, 3]
$scope.getSpacedItems = function(collection, start, space) {
  var subColl = [];
  for(var i = start; i < collection.length; i += space) {
    result.push(collection[i]);
  }

  return result;
};    

These values can be applied to the view in this manner:

<div>
  <div class="row" ng-repeat="n in [0, 1, 2] track by $index">
    <div class="col myGridCol" ng-repeat="item in getSpacedItems(items, $index, iterCount)">{{item.text}}</div>
  </div>
</div>


sphinks February 2016

I suppose the correct solution here - transform array with data on the controller side. So you "rotate" your 2D array and rows become columns, columns become rows. Then you perform just regular output. It is not the task for view side.

Post Status

Asked in February 2016
Viewed 3,536 times
Voted 13
Answered 2 times

Search




Leave an answer


Quote of the day: live life