m0ngr31
m0ngr31

Reputation: 830

Angular ng-repeat multi-sort

I have an array of objects that I'm trying to sort in a specific way:

[
  {
    name: 'Blackcurrant',
    created_at: '3/2/2014'
  },{
    name: 'Bilberry',
    created_at: '1/2/2013'
  },{
    name: 'Apple',
    created_at: '11/5/2012'
  },{
    name: 'Boysenberry',
    created_at: '1/1/2014'
  },{
    name: 'Coconut',
    created_at: '3/4/2011'
  },{
    name: 'Breadfruit',
    created_at: '6/6/2013'
  },{
    name: 'Currant',
    created_at: '2/8/2014'
  },{
    name: 'Avocado',
    created_at: '5/13/2014'
  },{
    name: 'Banana',
    created_at: '7/16/2014'
  },{
    name: 'Blueberry',
    created_at: '1/18/2010'
  },{
    name: 'Apricot',
    created_at: '9/17/2014'
  },{
    name: 'Date',
    created_at: '2/22/2012'
  },{
    name: 'Damson',
    created_at: '10/10/2014'
  },{
    name: 'Cantaloupe',
    created_at: '8/13/2014'
  },{
    name: 'Cranberry',
    created_at: '4/25/2011'
  },{
    name: 'Cucumber',
    created_at: '7/6/2014'
  },{
    name: 'Blackberry',
    created_at: '2/10/2014'
  },{
    name: 'Cloudberry',
    created_at: '1/23/2014'
  },{
    name: 'Cherry',
    created_at: '7/11/2013'
  },{
    name: 'Cherimoya',
    created_at: '11/19/2014'
  }
]

I need to be able to have it setup so that when I do an ng-repeat, that Coconut, Banana, Cantaloupe, and Cherry show up in that order at the beginning, and then they are sorted by created_at date after that. Is that possible using a combination of orderBy and having a filter?

Upvotes: 1

Views: 452

Answers (2)

m0ngr31
m0ngr31

Reputation: 830

This is what I ended up doing:

.filter('fruitSort', function() {
  return function(fruits) {
    var favoriteFruit = [];
    var newFruit = [];

    angular.forEach(fruits, function(fruit) {
      if (fruit.name === 'Coconut' || fruit.name === 'Banana' || fruit.name === 'Cantaloupe' || fruit.name === 'Cherry') {
        if (fruit.name === 'Coconut') {
          favoriteFruit[0] = circle;
        } else if (fruit.name === 'Banana') {
          favoriteFruit[1] = circle;
        } else if (fruit.name === 'Cantaloupe') {
          favoriteFruit[2] = circle;
        } else {
          favoriteFruit[3] = circle;
        }
      } else {
        newFruit.push(circle);
      }
    });

    newFruit.sort(function(a,b){return new Date(b.created_at).getTime() - new Date(a.created_at).getTime();});
    var sortedFruit = favoriteFruit.concat(newFruit);

    return sortedFruit;
  };
})

Upvotes: 0

Pixxl
Pixxl

Reputation: 996

You can sort ngRepeat elements by your created_at property by setting up your repeat with an orderBy filter.

<li ng-repeat="food in arrFoods | orderBy:created_at">
    <span>{{food.name}}</span>
</li>

As for ensuring you have "Coconut, Banana, Cantaloupe, and Cherry showing up first, you will need to create your own method of sorting based on a certain value. For my example, I have added the property fave to the elements you want displayed at the top of the array, prior to being ordered by created_by.

{
    name: 'Coconut',
    created_at: '3/4/2011',
    fave: true
}

Then to apply it to your ngRepeat element...

<li data-ng-repeat="food in arrFoods | orderBy:['fave', 'created_by']">

By applying an array of sorting parameters, we give priority to elements that have fave set to true (don't need to bother setting others to false) and then sort by created_by.

>>Working Plunkr Example

-mbp

Upvotes: 1

Related Questions