KyleT
KyleT

Reputation: 867

Conditional Content with ng-repeat in AngularJS

I'm trying to build a list of people with dividers for each letter (similar to a phone's address book).

people = ['Angela','Annie','Bob','Chris'];

Result:

A
Angela
Annie
B
Bob
C 
Chris

I want to do something similar to this pseudocode using Angular:

<div id="container" ng-init="lastCharacter = ''">
   @foreach(person in people)
      @if(firstCharacter(person.name) != lastCharacter)
         <div class="divider-item">{{firstCharacter(person.name)}}</div>
         {{lastCharacter = firstCharacter(person.name)}}
      @endif
      <div class="person-item">{{person.name}}</div>
   @endforeach
</div>

What is the easiest way to achieve this? I couldn't come up with an elegant solution using ng-repeat.

Upvotes: 2

Views: 423

Answers (2)

Kamrul
Kamrul

Reputation: 7301

try (use sorted list)

<div id="container" ng-repeat="person in people">
         <div class="divider-item" 
              ng-if="$index == 0 || ($index > 0 && firstCharacter(person.name) != firstCharacter(people[$index-1].name))">{{firstCharacter(person.name)}}</div>

         <div class="person-item">{{person.name}}</div>
</div>

hope, you have firstCharacter function defined in scope. Or you can simpley use person.name.charAt(0).

edit: as this will contain id container for all person. so best would be using an inner div inside container and run ng-repeat on there

<div id="container" >
    <div ng-repeat="person in people">
         <div class="divider-item" 
              ng-if="$index == 0 || ($index > 0 && firstCharacter(person.name) != firstCharacter(people[$index-1].name))">{{firstCharacter(person.name)}}</div>

         <div class="person-item">{{person.name}}</div>
    </div>
</div>

Upvotes: 1

Ufuk Hacıoğulları
Ufuk Hacıoğulları

Reputation: 38468

You should create a custom filter and move the grouping logic inside that:

app.filter('groupByFirstLetter',function(){
  return function(input){
    var result = [];

    for(var i = 0;i < input.length; i++){
      var currentLetter = input[i][0]

      var current = _.find(result, function(value){
        return value.key == currentLetter;
      });

      if(!current){
        current = {key: currentLetter, items: []}
        result.push(current);
      }

      current.items.push(input[i]);
    }


    return result;
  };
});

Then the view gets simple:

    <div ng-repeat="personGroup in people | groupByFirstLetter">
      <div class="divider-item">{{personGroup.key}}</div>
      <div class="person-item" ng-repeat="person in personGroup.items">
        {{person}}
      </div>
    </div>

Here's a little working example in plunker : http://plnkr.co/edit/W2qnTw0PVgcQWS6VbyM0?p=preview It's working but it throws some exceptions, you will get the idea.

Upvotes: 1

Related Questions