Question

I have a list such as this

Aperson

Cperson

APerson2

BPerson

and I want it to appear as so

A

Aperson Aperson2

B

Bperson

C

Cperson

I found a post here explaining it: http://pmosd.blogspot.com/2013/07/headers-in-angularjs-ng-repeats.html

but as an Angular noob, I'm not sure where to place the function and filter in the js file and how to properly code it into my html. I tried following the post that I linked, but my unordered list with the contact names would not show up in the browser. Here are my current JS and HTML files. I have tried placing the filter and function in various places, but this is from my most recent attempt.

Directory.js:

'use strict';

var myApp = angular.module('myappname');

myApp.controller('DirectoryCtrl', function ($scope) {
    $scope.contacts = [{
        'fname': 'Randy',
        'lname': 'Johnson',
        'location': 'Seattle, WA'
    }, {
        'fname': 'Andy',
        'lname': 'Pettite',
        'location': 'Bronx, NY'
    }, {
        'fname': 'Jon',
        'lname': 'Lester',
        'location': 'Boston, MA'
    }];

});


myApp.filter("headerChunk", function () {
    return function (orig, same, getChunkID) {
        if (!(orig instanceof Array)) return orig;
        if (orig.length == 0) return orig;

        var result = [];

        var cur = [];

        var i = 0
        for (i = 0; i < orig.length; i++) {
            if (i == 0 || same(orig[i], orig[i - 1])) {
                cur.push(orig[i]);
            } else {
                result.push({
                    id: getChunkID(orig[i - 1]),
                    items: cur
                });

                cur = [orig[i]];
            }
        }

        result.push({
            id: getChunkID(orig[orig.length - 1]),
            items: cur
        });

        for (i = 0; i < result.length; i++) {
            result[i].$$hashKey = i;
        }

        return result;
    }
});

$scope.filteredData = $filter("headerChunk")(
    $scope.filteredData,

    // The first argument is a function 'same' that is responsible for determining
    // whether two objects of the collection belong in the same category. We desire
    // two persons to go in the same category is their names start with the same first
    // letter:
    function (p1, p2) {
        return (p1.name.charAt(0) == p2.name.charAt(0));
    },

    // The second function 'getChunkID' is responsible for "naming" the resulting chunk.
    // We wish for the chunks to be identified by the letter that their constituents'
    // names start with:
    function (p) {
        return p.name.charAt(0);
    }
);

directory.html:

<div ng-repeat="group in contacts | orderBy:name | headerChunk:sameFunc:idFunc">
<ul>
    <li ng-repeat="item in group.items">
      {{item.lname}}, {{item.fname}}<br>
      {{item.location}}
        <hr>
    </li>
</ul>

Not sure what to do anymore.

Was it helpful?

Solution

Did you read the comments? the first person did it with underscore.js, so do it with underscore.js or lodash.js.

// include the script
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>


<div ng-repeat="(k,v) in sortedcontacts">
<span>{{k}}</span>
<ul>
    <li ng-repeat="item in v">
      {{item.lname}}, {{item.fname}}<br>
      {{item.location}}
        <hr>
    </li>
</ul>
</div>



'use strict';

var myApp = angular.module('myappname');

myApp.controller('DirectoryCtrl', function ($scope) {
$scope.contacts = [
    {'fname': 'Randy',
     'lname':'Johnson',
     'location': 'Seattle, WA'},
    {'fname': 'Andy',
     'lname':'Pettite',
     'location': 'Bronx, NY'},
    {'fname': 'Jon',
     'lname':'Lester',
     'location': 'Boston, MA'}
]; 

$scope.sortedcontacts = _.groupBy($scope.contacts, function(item) {return item.fname[0]; });
});

// you don't need those filter codes
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top