Angularjs Sorting by Property

AngularJS sorting by property

AngularJS' orderBy filter does just support arrays - no objects. So you have to write an own small filter, which does the sorting for you.

Or change the format of data you handle with (if you have influence on that). An array containing objects is sortable by native orderBy filter.

Here is my orderObjectBy filter for AngularJS:

app.filter('orderObjectBy', function(){
return function(input, attribute) {
if (!angular.isObject(input)) return input;

var array = [];
for(var objectKey in input) {
array.push(input[objectKey]);
}

array.sort(function(a, b){
a = parseInt(a[attribute]);
b = parseInt(b[attribute]);
return a - b;
});
return array;
}
});

Usage in your view:

<div class="item" ng-repeat="item in items | orderObjectBy:'position'">
//...
</div>

The object needs in this example a position attribute, but you have the flexibility to use any attribute in objects (containing an integer), just by definition in view.

Example JSON:

{
"123": {"name": "Test B", "position": "2"},
"456": {"name": "Test A", "position": "1"}
}

Here is a fiddle which shows you the usage:
http://jsfiddle.net/4tkj8/1/

AngularJS orderBy - Sort by string property of an object?

orderBy needs the property names of the objects it is supposed to sort. So the options inside your select should define these property names like this:

<md-select name="sortBy" placeholder="Sort By" ng-model="sortBy">
<md-option value="addedOn">Newest First</md-option>
<md-option value="priority">High Priority First</md-option>
</md-select>

If orderBy encounters a string inside these properties it will sort the array alphabetically. So this already conveniently works for you since High comes before Low.

From the Angular Documentation:

The default, built-in comparator should be sufficient for most usecases. In short, it compares numbers numerically, strings alphabetically (and case-insensitively), for objects falls back to using their index in the original collection, and sorts values of different types by type.

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

AngularJS sorting by attribute and custom filter

Issue was with my sortFunction. I didn't realize that parseInt will only extract the number from a mixed value if the number is first.

 parseInt("25") === 25; //true
parseInt("25+") === 25; //true
parseInt("<25") === 25; //false - actually returns NaN

I updated the sortFunction to

 return parseInt(item.itemLevel.replace('<',''));

and the multi-level orderBy in the view is what I thought it should be now:

 ng-repeat="item in items | orderBy:['itemStatus',sortFunction]

Thanks for the comments!

Sort list by property name AngularJS

You can try this code:

JS:

   $scope.streetsObject = {
'street35':[
{'address154': 'name14'},
{'address244': 'name2'}
],
'street2':[
{'address15': 'name1'},
{'address234': 'name2'}
]
}

HTML:

<div ng-repeat="street in streetsObject | orderBy">
<span ng-repeat"name in street">
</span>
</div>

The code supposes that you are using angular 1.3.0+.

AngularJS Orderby with Space in Property Name

The orderBy predicate should be a function that is passed the collection, accesses the property by bracket notation and returns the value.

The setPredicate function in your case should set the value of the property that the predicate uses.

Try something like this:

JS:

// Default orderBy
$scope.orderBy = $scope.columns[0];

$scope.setOrderBy = function (column) {
$scope.orderBy = column;
}

$scope.predicate = function(rows) {
return rows[$scope.orderBy];
}

HTML:

<th ng-repeat="column in columns" ng-click="setOrderBy(column)">{{ column }}</th>

And:

<tr ng-repeat="row in rows | orderBy:predicate:reverse">

Demo: http://plnkr.co/edit/2Mlc2lBf0wRVicfcfYZO?p=preview

How to orderby in AngularJS using Nested property

These type of data manipulations I like to keep them in the proper angular objects and for that reason I would create my custom filter, something like:

var sampleSource=  [{"Sale":{"id":"8","customer_id":"1","amount":"15","created":"2014-05-17"}}, {"Sale":{"id":"5","customer_id":"6","amount":"15","created":"2015-05-17"}}];

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

myApp.filter('myFilter', function() {
return function(items) {
items.sort(function(a,b){
if (parseInt(a.Sale.id) > parseInt(b.Sale.id))
return 1;
if (parseInt(a.Sale.id) < parseInt(b.Sale.id))
return -1;
return 0; })
});

Important: I recommend the custom filter because as personal preference I do not like to overload my controllers or other objects with tasks(code) that I can separate on other objects which gives me more independence and cleaner code(one of the things I love about angular) but besides this personal preference I would say that this is not the only way but if you share my reasons behind it I hope it helps.

AngularJs ng-repeat orderBy not working for nested object properties

There are two reasons orderBy isn't working here:

  • orderBy only works on arrays, but you are applying it to a plain object.
  • To order by an expression, you need to give orderBy a string value with the expression. You are giving it order.allListPosition, which would equate to $scope.order.allListPosition (which doesn't exist).

To solve the first issue, add an array of your data objects:

$scope.dataArray = Object.keys($scope.data)
.map(function(key) {
return $scope.data[key];
});

To solve the second issue (and incorporate the dataArray from above):

<div ng-repeat="item in dataArray | orderBy:'order.allListPosition'">

http://plnkr.co/edit/BXgYPTElSM3sjvLg30CL?p=preview



Related Topics



Leave a reply



Submit