For my Angular project, I need to order an array using the $filter('orderBy')
function. Specifically, I want to specify three predicate callbacks and have the sort order be ASC, DESC, ASC.
I am well aware that there are various methods to achieve multi-column sorting in Angular, but my focus is on utilizing the orderBy filter for this task.
The examples I will provide are not actual data but rather a simplified model to aid in explanation.
One common approach is to use simple property names like so:
$scope.arr = $filter('orderBy')($scope.arr, ['+year', '-month', '+payment']);
However, my specific orderBy code setup involves functions as follows:
$scope.arr = $filter('orderBy')($scope.arr, [
function(row) {
//complex logic here...for demonstration purposes returning the raw property
return row.year;
},
function(row) {
//complex logic here...for demonstration purposes returning the raw property
return row.month;
},
function(row) {
//complex logic here...for demonstration purposes returning the raw property
return row.payment;
}
], true);
}
Despite using an array of functions for ordering, I am struggling to implement ASC, DESC, ASC sorting order. While flipping the whole array with the third argument works (
$filter('orderBy')($scope.arr,[...], true)
), it's not the solution I desire.
I attempted structuring the array differently, but it did not yield the desired outcome:
['+', function(row){return row.year;}, '-', function(row){return row.month}, '+', function(row){return row.payment;}]
I find myself at a loss. Is there a way to utilize the predicate function callbacks while achieving per-property specified direction sorting?
angular.module('app', []).controller('MyController', function($scope, $filter) {
var id = 0;
var arr = [];
//generate some dummy data
for (var year = 2000; year < 2010; year++) {
for (var month = 3; month > 0; month--) {
for (var payment = 100; payment < 300; payment = payment + 50) {
var row = {
id: id++,
year: year,
month: '0' + month,
payment: payment
};
arr.push(row);
}
}
}
$scope.arr = arr;
$scope.order = function() {
$scope.arr = $filter('orderBy')($scope.arr, [
function(row) {
return row.year;
},
function(row) {
return row.month;
},
function(row) {
return row.payment;
}
], true);
}
//sort the array right away
$scope.order();
});
th {
padding: 10px 20px;
border: 1px solid black;
background-color: lightgrey;
text-align: center;
}
td {
padding: 10px 20px;
border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="MyController">
<table>
<tr>
<th>ID</th>
<th>Year</th>
<th>Month</th>
<th>Payment</th>
</tr>
<tr ng-repeat="row in arr">
<td>{{row.id}}</td>
<td>{{row.year}}</td>
<td>{{row.month}}</td>
<td>{{row.payment}}</td>
</tr>
</table>
</div>
</div>