391

How to sort by using multiple fields at same time in angular? fist by group and then by sub-group for Example

$scope.divisions = [{'group':1,'sub':1}, {'group':2,'sub':10}, {'group':1,'sub':2},{'group':1,'sub':20},{'group':2,'sub':1},
    {'group':2,'sub':11}];

I wanted to display this as

group : Sub-group

1 - 1

1 - 2

1 - 20

2 - 1

2 - 10

2 - 11

<select ng-model="divs" ng-options="(d.group+' - '+d.sub) for d in divisions | orderBy:'group' | orderBy:'sub'" />
Community
  • 1
  • 1
gmeka
  • 4,269
  • 3
  • 25
  • 25

8 Answers8

681

Please see this:

http://jsfiddle.net/JSWorld/Hp4W7/32/

<div ng-repeat="division in divisions | orderBy:['group','sub']">{{division.group}}-{{division.sub}}</div>
Chubby Boy
  • 30,942
  • 19
  • 47
  • 47
  • 144
    `orderBy:['-group','sub']` for sorting by `group` in reverse order. – Dmytro Aug 28 '14 at 18:19
  • 1
    Does the group field have priority for being first in the orderBy List? – luchosrock Dec 01 '14 at 13:59
  • 5
    @luchosrock, yes it does, as expected. Playing with the provided jsfiddle easily confirms sort priority is from left to right for the provided sort fields. – Patrick Refondini Jan 21 '15 at 13:59
  • Do you know if it's possible to give priority to one of the fields? For example in this [jsFiddle](http://jsfiddle.net/abyrne85/apfw1Lm5/2/) I would like the items with a value for 'sub' to appear at the top of the list, then the rest of the values can be arranged by group. – abyrne85 Jun 11 '15 at 15:15
  • 2
    Note that the optional reverseOrder parameter does not support an array like the expression param does, but you can omit it and instead provide sort order on each array item so that they are reversed (or not) separately. Example: orderBy: ['group', '-sub'] will sort by group in normal fashion, then by sub in reverse order. It is possible to get some complex combinations this way. – Daniel Nalbach Jul 14 '15 at 21:45
  • 1
    We simulated priority in our shop by giving the array items a boolean property, then using that as the first option. Example: orderBy: ['-featured', 'title'], which caused the featured true items to be at the top (alphabetically), then the rest of the items listed alphabetically. – Daniel Nalbach Jul 14 '15 at 21:56
  • I have trouble sorting by two properties. When I sortby name and then age, it does not sort by age. Here is my plunker https://plnkr.co/edit/gqZaKbb7TwnvGGewydPv?p=preview – vinesh Sep 24 '16 at 21:41
  • If you want to sort by multiple fields chosen from a select directive, be sure to convert the value from a string to an array. Example: for selected option – kvarkel Jul 22 '19 at 21:10
50

If you wants to sort on mulitple fields inside controller use this

$filter('orderBy')($scope.property_list, ['firstProp', 'secondProp']);

See also https://docs.angularjs.org/api/ng/filter/orderBy

Matt
  • 74,352
  • 26
  • 153
  • 180
21
<select ng-model="divs" ng-options="(d.group+' - '+d.sub) for d in divisions | orderBy:['group','sub']" />

User array instead of multiple orderBY

Thambuleena
  • 253
  • 2
  • 7
7

There are 2 ways of doing AngularJs filters, one in the HTML using {{}} and one in actual JS files...

You can solve you problem by using :

{{ Expression | orderBy : expression : reverse}}

if you use it in the HTML or use something like:

$filter('orderBy')(yourArray, yourExpression, reverse)

The reverse is optional at the end, it accepts a boolean and if it's true, it will reverse the Array for you, very handy way to reverse your Array...

Alireza
  • 100,211
  • 27
  • 269
  • 172
7

Sorting can be done by using 'orderBy' filter in angular.

Two ways: 1. From view 2. From controller

  1. From view

Syntax:

{{array | orderBy : expression : reverse}} 

For example:

 <div ng-repeat="user in users | orderBy : ['name', 'age'] : true">{{user.name}}</div>
  1. From controller

Syntax:

$filter.orderBy(array, expression, reverse);

For example:

$scope.filteredArray = $filter.orderBy($scope.users, ['name', 'age'], true);
Tessy Thomas
  • 1,475
  • 12
  • 19
1

I wrote this handy piece to sort by multiple columns / properties of an object. With each successive column click, the code stores the last column clicked and adds it to a growing list of clicked column string names, placing them in an array called sortArray. The built-in Angular "orderBy" filter simply reads the sortArray list and orders the columns by the order of column names stored there. So the last clicked column name becomes the primary ordered filter, the previous one clicked the next in precedence, etc. The reverse order affects all columns order at once and toggles ascending/descending for the complete array list set:

<script>
    app.controller('myCtrl', function ($scope) {
        $scope.sortArray = ['name'];
        $scope.sortReverse1 = false;
        $scope.searchProperty1 = '';
        $scope.addSort = function (x) {
            if ($scope.sortArray.indexOf(x) === -1) {
                $scope.sortArray.splice(0,0,x);//add to front
            }
            else {
                $scope.sortArray.splice($scope.sortArray.indexOf(x), 1, x);//remove
                $scope.sortArray.splice(0, 0, x);//add to front again
            }
        };
        $scope.sushi = [
        { name: 'Cali Roll', fish: 'Crab', tastiness: 2 },
        { name: 'Philly', fish: 'Tuna', tastiness: 2 },
        { name: 'Tiger', fish: 'Eel', tastiness: 7 },
        { name: 'Rainbow', fish: 'Variety', tastiness: 6 },
        { name: 'Salmon', fish: 'Misc', tastiness: 2 }
        ];
    });
</script>
<table style="border: 2px solid #000;">
<thead>
    <tr>
        <td><a href="#" ng-click="addSort('name');sortReverse1=!sortReverse1">NAME<span ng-show="sortReverse1==false">&#9660;</span><span ng-show="sortReverse1==true">&#9650;</span></a></td>
        <td><a href="#" ng-click="addSort('fish');sortReverse1=!sortReverse1">FISH<span ng-show="sortReverse1==false">&#9660;</span><span ng-show="sortReverse1==true">&#9650;</span></a></td>
        <td><a href="#" ng-click="addSort('tastiness');sortReverse1=!sortReverse1">TASTINESS<span ng-show="sortReverse1==false">&#9660;</span><span ng-show="sortReverse1==true">&#9650;</span></a></td>
    </tr>
</thead>
<tbody>
    <tr ng-repeat="s in sushi | orderBy:sortArray:sortReverse1 | filter:searchProperty1">
        <td>{{ s.name }}</td>
        <td>{{ s.fish }}</td>
        <td>{{ s.tastiness }}</td>
    </tr>
</tbody>
</table>
Stokely
  • 12,444
  • 2
  • 35
  • 23
0

Created Pipe for sorting. Accepts both string and array of strings, sorting by multiple values. Works for Angular (not AngularJS). Supports both sort for string and numbers.

@Pipe({name: 'orderBy'})
export class OrderBy implements PipeTransform {
    transform(array: any[], filter: any): any[] {
        if(typeof filter === 'string') {
            return this.sortAray(array, filter)
        } else {
            for (var i = filter.length -1; i >= 0; i--) {
                array = this.sortAray(array, filter[i]);
            }

            return array;
        }
    }

    private sortAray(array, field) {
        return array.sort((a, b) => {
            if(typeof a[field] !== 'string') {
                a[field] !== b[field] ? a[field] < b[field] ? -1 : 1 : 0
            } else {
                a[field].toLowerCase() !== b[field].toLowerCase() ? a[field].toLowerCase() < b[field].toLowerCase() ? -1 : 1 : 0
            }
        });
    }
}
Andris
  • 3,895
  • 2
  • 24
  • 27
-8

Make sure that the sorting is not to complicated for the end user. I always thought sorting on group and sub group is a little bit complicated to understand. If its a technical end user it might be OK.

Jens Alenius
  • 1,931
  • 2
  • 16
  • 20
  • 1
    This is not even a relevant "comment". For sure not an answer to the question – Afshin Moazami Aug 31 '17 at 14:13
  • Is it so wrong to ask yourself if the current approach is the best when your doing GUI development? The end user experience feels relevant to me – Jens Alenius Sep 04 '17 at 14:08
  • There are plenty of scenarios where sorting by multiple properties makes it easier for the user to understand the organization. You're essentially grouping things into categories. – Owen Johnson May 24 '18 at 20:52