0

I'm currently working on my first Ionic app and with it my first exposure to Angular. My current hurdle is injecting group headers ("A", "B", "C", and so on) into a longish list (~600) of alphabetically sorted names. I've looked into solutions with filters, nested ngRepeats (which, specifically, didn't seem to play nice with Ionic's collection-repeat), but would like to accomplish this without the need for filtering or third-party dependencies like lodash or underscores.

My current target solution is to use a directive to prepend the header to the first element of each group of names.

The app is consuming content from Contentful's API and in the service I'm manually adding a group identifier based on the name's first letter. An example data set might be:

[
  {"id":"1","name":"Carrie","group":"C"},
  {"id":"2","name":"Gabe","group":"G"},
  {"id":"3","name":"Gerry","group":"G"},
  {"id":"4","name":"Hector","group":"H"},
  {"id":"5","name":"Hilbert","group":"H"}
]

Here's the template:

<ion-content>
  <ion-list>
    <div collection-repeat="person in People" group-header>
      <ion-item class="item-icon-right" type="item-text-wrap" href="#/app/people/{{ person.id }}" group="{{ person.group }}">
        <h2>{{ person.name }}</h2>
        <i class="icon ion-chevron-right icon-accessory"></i>
      </ion-item>
    </div>
  </ion-list>
</ion-content>

Here's the directive:

.directive('groupHeader', function () {
  return {
    compile: function (element) {
      element.prepend('<div class="item item-divider" is-divider>{{ person.group }}</div>');
    }
  }
})

And currently, as expected, the prepend occurs for each repeated item:

<div collection-repeat="name in Names" group-header>
  <div class="item item-divider ng-binding">C</div>
  <ion-item class="item-icon-right item item-complex" type="item-text-wrap" href="#/app/names/1" group="C">
    <a class="item-content" ng-href="#/app/names/1" href="#/app/names/1">
      <h2 class="ng-binding">Carrie</h2>
      <i class="icon ion-chevron-right icon-accessory"></i>
    </a>
  </ion-item>
</div>

<div collection-repeat="name in Names" group-header>
  <div class="item item-divider ng-binding">G</div>
  <ion-item class="item-icon-right item item-complex" type="item-text-wrap" href="#/app/names/2" group="G">
    <a class="item-content" ng-href="#/app/names/2" href="#/app/names/2">
      <h2 class="ng-binding">Gabe</h2>
      <i class="icon ion-chevron-right icon-accessory"></i>
    </a>
  </ion-item>
</div>

I'd like to know if there are any recommendations for updating the directive so that it only prepends on the first instance of name in a given group. I'm happy to be pointed to resources, rather than a longhand solution--but either will be much appreciated.

Thanks!

Chris
  • 27
  • 1
  • 6

1 Answers1

0

I was able to accomplish what I was after with an ng-switch in the template:

<ion-content>
  <ion-list>
    <div collection-repeat="person in People">
      <ng-switch on="$first || person.group != People[$index-1].group">
        <ion-item type="item-text-wrap" ng-switch-when="true">
          {{ person.group }}
        </ion-item>
      </ng-switch>
      <ion-item class="item-icon-right" type="item-text-wrap" href="#/app/people/{{ person.id }}" group="{{ person.group }}">
        <h2>{{ person.name }}</h2>
        <i class="icon ion-chevron-right icon-accessory"></i>
      </ion-item>
    </div>
  </ion-list>
</ion-content>

Thanks to: https://stackoverflow.com/a/14076254/3426040.

Community
  • 1
  • 1
Chris
  • 27
  • 1
  • 6