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  | groupBy:'orderlineId'" >
				<h2 ng-show="item.groupfield_CHANGED">{{item.orderlineId}}</h2>
				<ul>
					<li>{{item.name}}</li>
				</ul>
			</div>
            
			<form role="form" ng-submit="AddItem()">
				<input type="text" data-ng-model="item.groupfield" placeholder="Group">
				<input type="text" data-ng-model="item.whatever" placeholder="Item">
				<input class="btn" type="submit" value="Add Item">
			</form>
		</div>

</div>

JavaScript

var app=angular.module('myApp',[]);

    app.controller('TestGroupingCtlr',function($scope) {

			$scope.MyList = [
				{name: 'test1', orderlineId: '52'},
				{name: 'test2', orderlineId: '82'},
				{name: 'test3', orderlineId: '82'}
			];

			$scope.AddItem = function() {

				// add to our js object array
				$scope.MyList.push({
				groupfield:$scope.item.groupfield,
						whatever:$scope.item.whatever
				});
			};


		})


    /*
	 * 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] = false;
			}

			filtered.push(item);
			prev_item = item;

		});

		return filtered;
		};
	})