1

I am trying to have 4 boxes always show up. The boxes are filled by an image,but if there is no image available I want the boxes to be gray. The images variable holds an unknown amount of images, it could be 2 it could be 30.

<div class="container">
    <div class="picture" ng-repeat="image in images | limitTo: 4"></div>
    // PSEUDO CODE BELOW
    <div class="empty" ng-repeat="i in 4 - images.length"></div>
    // PSEUDO CODE ABOVE
</div>

"4 - images.length" is pseudo code, This is what I want to achieve, thinking if I only have 3 images available the result will be 1 gray box. But this syntax obviously does not work since ng-repeat require a collection.

Which made me try to provide it said collection through a function:

$scope.getNumber = function(num) {
    return new Array(num); 
}

and use in the following way:

<div class="empty" ng-repeat="n in getNumber(4 - cookbook.images.length)"></div>

But with no success.

Nicklas Kevin Frank
  • 6,079
  • 4
  • 38
  • 63

4 Answers4

3
 <div class="picture" ng-repeat="image in images | limitTo: 4">hi</div>
 <div class="empty" ng-repeat="n in [] | range:images.length:4">hey</div>

I've created a custom filter for it:

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

DEMO

mohamedrias
  • 18,326
  • 2
  • 38
  • 47
  • How is this better than one line of code that I have reference in my solution below. He would only have to make a function in the controller that returns the number as an array. one function, one line. This is unnecessarily complicated when there is a more elegant solution. – Steve Apr 10 '15 at 14:10
  • If we're thinking only about this scenario yes. But once you create a filter like this. You can reuse it anywhere in yur application. I believe in code reuse and avoid duplicating code :) – mohamedrias Apr 10 '15 at 14:12
  • Maybe a directive might be better suited then if it gets to that point, right? – Steve Apr 10 '15 at 14:15
2

Possible repeat question

By using this updated syntax you can iterate with a specific index defined

HTML

<div ng-app="myapp">
<div ng-controller="ctrlParent">
    <ul>
        <li ng-repeat="i in getNumber(4) track by $index"><span>{{$index+1}}</span></li>
    </ul>
</div>

Controllers

var app = angular.module('myapp',[]);
app.controller('ctrlParent',function($scope){
$scope.getNumber = function(num) {
    return new Array(num);   
    }
});

Way to ng-repeat defined number of times instead of repeating over array?

Community
  • 1
  • 1
Steve
  • 276
  • 1
  • 10
1

I would probably handle this in whatever populates $scope.images. For example, something like:

$http.get('api/some/images?skip=10&take=4')
 .success(function(response){
    $scope.images = response;
    for(var i = $scope.images.length; i<4; i++){
       $scope.images.push('empty');
    }
 });

Then my template would just handle that:

<div class="container>
   <div ng-repeat="image in images" ng-class="{empty:image=='empty',picture:image!='empty'}"></div>
</div>
Daniel
  • 3,021
  • 5
  • 35
  • 50
1

wouldnt be easier to make operation modulo in controller?

function equal_number_of_images(){
for(var i = 0, add = 4 - $scope.some_files%4; i < add; i++ ){
     $scope.some_files.push('');
}}
Janko
  • 202
  • 2
  • 11