Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Grouping Nested ngRepeat Lists In AngularJS
<!doctype html>
<html ng-app="Demo" ng-controller="DemoController">
<head>
<meta charset="utf-8" />
<title>
Grouping Nested ngRepeat Lists In AngularJS
</title>
</head>
<body>
<h1>
Grouping Nested ngRepeat Lists In AngularJS
</h1>
<p>
Group by:
<a ng-click="groupBy( 'gender' )">Gender</a> -
<a ng-click="groupBy( 'hair' )">Hair</a>
</p>
<!-- BEGIN: Outer ngRepeat. -->
<div ng-repeat="group in groups">
<h2>
{{ group.label }}
</h2>
<ul>
<!-- BEGIN: Inner ngRepeat. -->
<li ng-repeat="friend in group.friends">
{{ friend.name }}
</li>
<!-- END: Inner ngRepeat. -->
</ul>
</div>
<!-- END: Outer ngRepeat. -->
<!-- Load jQuery and AngularJS from the CDN. -->
<script
type="text/javascript"
src="//code.jquery.com/jquery-1.9.1.min.js">
</script>
<script
type="text/javascript"
src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js">
</script>
<!-- Load the app module and its classes. -->
<script type="text/javascript">
// Define our AngularJS application module.
var demo = angular.module( "Demo", [] );
// -------------------------------------------------- //
// -------------------------------------------------- //
// I am the main controller for the application.
demo.controller(
"DemoController",
function( $scope, $timeout ) {
// -- Define Controller Methods. ------------ //
// I sort the given collection on the given property.
function sortOn( collection, name ) {
collection.sort(
function( a, b ) {
if ( a[ name ] <= b[ name ] ) {
return( -1 );
}
return( 1 );
}
);
}
// -- Define Scope Methods. ----------------- //
// I group the friends list on the given property.
$scope.groupBy = function( attribute ) {
// First, reset the groups.
$scope.groups = [];
// Now, sort the collection of friend on the
// grouping-property. This just makes it easier
// to split the collection.
sortOn( $scope.friends, attribute );
// I determine which group we are currently in.
var groupValue = "_INVALID_GROUP_VALUE_";
// As we loop over each friend, add it to the
// current group - we'll create a NEW group every
// time we come across a new attribute value.
for ( var i = 0 ; i < $scope.friends.length ; i++ ) {
var friend = $scope.friends[ i ];
// Should we create a new group?
if ( friend[ attribute ] !== groupValue ) {
var group = {
label: friend[ attribute ],
friends: []
};
groupValue = group.label;
$scope.groups.push( group );
}
// Add the friend to the currently active
// grouping.
group.friends.push( friend );
}
};
// -- Define Scope Variables. --------------- //
// I am the raw collection of friends.
$scope.friends = [
{
name: "Michael",
gender: "Male",
hair: "Brunette"
},
{
name: "George Michael",
gender: "Male",
hair: "Brunette"
},
{
name: "Gob",
gender: "Male",
hair: "Brunette"
},
{
name: "Tobias",
gender: "Male",
hair: "Black"
},
{
name: "Lindsay",
gender: "Female",
hair: "Blonde"
},
{
name: "Maeby",
gender: "Female",
hair: "Black"
}
];
// I am the grouped collection. Each one of these
// will contain a sub-collection of friends.
$scope.groups = [];
}
);
</script>
</body>
</html>
@oskr226

This comment has been minimized.

Copy link

commented Aug 5, 2013

Bennadel Hi, thanks for the code was very helpful. I made some modifications to adapt it to what I needed and I want to share with you. Maybe it can be optimized a bit more.

<%tbody>
<%tr data-ng-repeat="dir in listContenido | filter:filtro | orderBy:predicate:reverse | grouping">
<%td style="width:19px;"><%img src="img/{{dir.type}}.png" alt="tipo" /><%/td>
<%td><%a href="#" class="btn btn-link btn-small" data-ng-click="navfolderClick(dir, $event)">{{dir.name}}<%/a><%/td>
<%td>{{dir.size/1024 | number:1 }}<%/td>
<%/tr>
<%/tbody>

//********************************************
//Script file
//********************************************
var app = angular.module('app', []);

//Grouping service
app.filter('grouping', function () {
return function (listContenido) {
var atributo = 'type'; //Atributo por que cual se pretende agrupar

    var groups = []; //Array para agrupar

    var groupValue = []; //Array de las palabras claves para agrupar
    var longitud = listContenido.length;

    //Si la lista tiene contenido
    if (longitud > 0) {
        for (var i = 0; i < listContenido.length; i++) {
            var contenido = listContenido[i];

            //Verificamos si hay que crear un nuevo grupo
            if (groupValue.indexOf(contenido[atributo]) < 0) { //No esta dentro del array             
                var group = {
                    label: contenido[atributo],
                    lContenidos: []
                };

                groupValue.push(group.label); //Actualizamos la palabra clave para agrupar
                groups.push(group);
            }

            //Agregamos el contenido al grupo actual
            $.each(groups, function () {
                if (this.label == contenido[atributo]) {
                    this.lContenidos.push(contenido);
                }
            });

        }

        listContenido = [];
        //Volvemos a armar el array del contenido
        $.each(groups, function () {
            $.each(this.lContenidos, function () {
                listContenido.push(this);
            });
        });

    }

    return listContenido;
}

});

@oskr226

This comment has been minimized.

Copy link

commented Aug 5, 2013

Sorry, I don't know how to format the code. I hope you understand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.