Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angularjs - orderBy custom comparator

I'm trying to display a list of values based on an order-function that may require comparing more than 1 field, so the standard one-parameter function is not sufficient for me.

I want items with a description to be on the top of the list (no matter what the description is) and among the top half (with description) and the bottom half (without description) I want an alphabetical order by the name.

I have something like this:

<div ng-repeat="item in items | orderBy:memberSort">
  {{item.sortName}} / {{item.description}}
</div>

and the comparator:

$scope.memberSort = function(m1, m2) {
    if (m1.description && !m2.description) {
       return -1;
    }
    if (m2.description && !m1.description) {
       return 1;
    }
    return m1.sortName.localCompare(m2.sortName);
};

how can I use a comparator like this and not just a one-parameter value function? In above code, the parameter m2 is always undefined.

here is a jsfiddle: https://jsfiddle.net/1Lwg4s2r/15/

while this is just 1 current problem, the general question is how to define a comparator function accepting 2 values and not just a single-parameter function that maps a complex object to a value?

like image 707
EasterBunnyBugSmasher Avatar asked Mar 07 '23 16:03

EasterBunnyBugSmasher


1 Answers

You had to specify memberSort comparator as a third argument of orderBy:

angular.module('app', []).controller('myController', function($scope) {
  $scope.items = [    
    { description: '', sortName: 'Bob' },
    { description: '', sortName: 'Steve' },
    { description: '', sortName: 'Mark' },
    { description: 'Member', sortName: 'Kirk' },
    { description: 'Boss', sortName: 'Joe' }
  ];
  $scope.memberSort = function(o1, o2) {
    var m1 = o1.value, m2 = o2.value;
    if (m1.description && !m2.description)
       return -1;    
    if (m2.description && !m1.description)
       return 1;    
    return m1.sortName.localeCompare(m2.sortName);
  };
});
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>

<div ng-app='app' ng-controller="myController">
  <div ng-repeat="item in items | orderBy: 'valueOf()' : false : memberSort">  
    {{item.sortName}} / {{item.description}}
  </div>
</div>
like image 155
Slava Utesinov Avatar answered Mar 14 '23 22:03

Slava Utesinov