Blazemonger
Blazemonger

Reputation: 92893

How to detect my position in an ng-repeat loop?

I want to output a list of <li> elements using ng-repeat="obj in links", where links is an array of objects with href and text properties:

$scope.links = [
    { href: '/asdf', text: 'asdf'},
    { href: '/qwer', text: 'qwer'},
    /* etc. */
    { href: '/zxcv', text: 'zxcv'}
];

But I want the ng-repeat loop to change what it does when it reaches a certain object in that array. Specifically, I want the loop to create hyperlinks for every object until obj.href==location.path() -- and after that, I just want to write out the text inside a <span>.


Currently, I'm solving this by creating both links and spans each time in the loop:

<ul>
    <li ng-repeat="obj in links" ng-class="{active: location.path()==obj.href}">
        <a ng-href="{{obj.href}}">{{obj.text}}</a>
        <span>{{obj.text}}</span>
    </li>
</ul>

plunkr

I then use CSS to hide all hyperlinks after the active class and hide all spans before it. But I don't want to just hide the links after the condition matches -- I want them to be completely removed from the DOM.

Upvotes: 1

Views: 444

Answers (2)

sylwester
sylwester

Reputation: 16498

please see that example http://jsbin.com/cifef/1/edit

for your solution you need to replace $scope.location.href by location.path()

$scope.isLast = false;
  $scope.getValue = function(obj)
  {

    if( obj.href==$location.path() || $scope.isLast )
      {
        $scope.isLast = true;
        obj.isLast = true;

      }


  };

HTML:

<ul>
    <li ng-repeat="obj in links" ng-class="{active: location.href==obj.href}" ng-init="getValue(obj)">

        <a ng-href="{{obj.href}}" ng-hide="obj.isLast">{{obj.text}}</a>
        <span ng-show="obj.isLast">{{obj.text}}</span>
    </li>
</ul>

Upvotes: 0

Cyril Duchon-Doris
Cyril Duchon-Doris

Reputation: 13949

So there are two things you must do.

  1. Find the index of the active element
  2. Only show links up to the active index, and after that only show spans

What about this:

In your controller

$scope.lastIndex = 0;
$scope.$watch('links', function(newVal, oldVal){
    for(var i=0; i< newVal.length; i++){
        if (newVal[i].href == location.path()){
            $scope.lastIndex = i
            break;
        }
    }
}

In your HTML :

<ul>
    <li ng-repeat="obj in links">
        <a ng-if="$index <= {{lastIndex}}" ng-href="{{obj.href}}">{{obj.text}}</a>
        <span ng-if="$index > {{lastIndex}}">{{obj.text}}</span>
    </li>
</ul>

Upvotes: 3

Related Questions