AngularJS Group-By Filter
Filter to define when a field in an array of data changes from the previous value. Allows multiple filters and can be used in conjunction with OrderBy.
A future change will be to allow an array of fields to group by to be passed so that the multiple group-by filters don't have to re-iterate through the array for each one.
HTML
<div ng-app="myApp">
<div ng-controller='TestGroupingCtlr'>
<div ng-repeat="item in MyList | filter: {status: 'Closed'} | groupBy:'groupfield' " >
<h2 ng-show="item.groupfield_CHANGED">{{item.groupfield}}</h2>
<ul>
<li>{{item.whatever}} - Status: {{item.status}}</li>
</ul>
</div>
</div>
</div>
JavaScript
var app=angular.module('myApp',[]);
app.controller('TestGroupingCtlr',function($scope) {
$scope.MyList = [
{groupfield: 'Day Before', whatever: 'Server X down', status: 'Open'},
{groupfield: 'Yesterday', whatever: 'Access issues', status: 'Open'},
{groupfield: 'Yesterday', whatever: 'Server Z is down', status: 'Closed'},
{groupfield: 'Today', whatever: 'Network problem', status: 'Closed'},
{groupfield: 'Today', whatever: 'Network is down', status: 'Closed'}
];
})
/*
* groupBy
*
* Define when a group break occurs in a list of items
*
* @param {array} the list of items
* @param {String} then name of the field in the item from the list to group by
* @returns {array} the list of items with an added field name named with "_new"
* appended to the group by field name
*
* @example <div ng-repeat="item in MyList | groupBy:'groupfield'" >
* <h2 ng-if="item.groupfield_CHANGED">{{item.groupfield}}</h2>
*
* Typically you'll want to include Angular's orderBy filter first
*/
app.filter('groupBy', function(){
return function(list, group_by) {
var filtered = [];
var prev_item = null;
var group_changed = false;
// this is a new field which is added to each item where we append "_CHANGED"
// to indicate a field change in the list
var new_field = group_by + '_CHANGED';
// loop through each item in the list
angular.forEach(list, function(item) {
group_changed = false;
// if not the first item
if (prev_item !== null) {
// check if the group by field changed
if (prev_item[group_by] !== item[group_by]) {
group_changed = true;
}
// otherwise we have the first item in the list which is new
} else {
group_changed = true;
}
// if the group changed, then add a new field to the item
// to indicate this
if (group_changed) {
item[new_field] = true;
} else {
item[new_field] =...