1

Assume the following object

var items [
    { type: 'big', .... },
    { type: 'small', .... },
    { type: 'big', .... },
    { type: 'small', .... },
    { type: 'big', .... },
];

Which I use inside a ng-repeat as follows:

<div ng-repeat="item in items">
   <span ng-if="item.type === 'big'>{{$index}}</div>
   <p> ..... </p>
</div>

The problem with this code is that I only want to number the items with type === 'big' and I don't wan't gapes in the numbering. The output now is:

<div>
   <span>0</div>
   <p>......</p>
</div>
<div>
   <p>......</p>
</div>
<div>
   <span>2</div> // I want a 1 here
   <p>......</p>
</div>
<div>
   <p>......</p>
</div>
<div>
   <span>4</div> // and a 2 here!
   <p>......</p>
</div>

What would be the angular way to perform this kind of numbering ?

3 Answers 3

3

The solution I am proposing isn't an Angular solution at all. But instead I am going to use CSS to solve your solely displaying issue:

CSS counters are implemented in all major browsers and therefore a usable possibility (canIUse.com)

You reset an css counter for the sorrounding element and increment it for every shown element:

<div class="list">
    <div ng-repeat="item in items">
       <p ng-class="item.type"> ..... </p>
    </div>
</div>

and trhe corresponding CSS:

.list{
    counter-reset: big-counter;
}

.list .big:before {
    content: counter(big-counter);
    counter-increment: big-counter;
}

I made this Plunker to show the result.


Update

To use characters instead of numbers you change the css counter line to the following:

content: counter(big-counter,lower-latin);

or

content: counter(big-counter, upper-latin);

Updated Plunker (by Jeanluca Scaljeri)

Sign up to request clarification or add additional context in comments.

5 Comments

This is actually a very nice one, however, in my application I need eventually characters instead of numbers :( Thnx!
@JeanlucaScaljeri How should your output look like if you do have characters in it, can you show us an example? Maybe we can tweak the CSS solution somehow...
Well, instead of numbering I place a, b, c, etc in front of it. The answer given by @ustinpinili works fine, because I just add 96 and use fromCharCode
@JeanlucaScaljeri This is till possible with CSS counters, I'll update my answer accordingly.
awesome, thats exactly what I need! (I've updated your plunker here)
3

You could call a scoped function in your ng-if statement that will check if the item.type === "big" and also keeps track of the number of times item.type !== "big" and subtract that number from the index of the repeated element.

Inside your Angular controller:

$scope.skipped = 0;
$scope.isBig = function(type) {
  if (type === "big") {
    return true;
  else {
    $scope.skipped++;
    return false;
  }
}

HTML:

<div ng-repeat="item in items">
   <span ng-if="isBig(item.type)">{{$index - skipped}}</div>
   <p> ..... </p>
</div>

Comments

-1

This isn't angular, it's math

<span ng-if="item.type === 'big'>{{$index/2}}</div>

Just divide the index by 2!

Sure, you could do some funny stuff in the controller, but this is probably the fastest and easiest.

3 Comments

If the answer works, don't downvote it unless you comment on it to explain your issue. They call that "basic civility".
you'r right about the answer producing the correct output, but if the data changes it won't work anymore.
@JeanlucaScaljeri yes, you are right, but any change would affect underlying logic too. Ah well, whatever.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.