0

I have a select iterating over a collection looking like this:

ctrl.countriesList = {
    'DK': {countryName: 'Denmark', preferredLanguage: 'DA'}
    'US': {countryName: 'USA', preferredLanguage: 'EN'}
}

and iteration over the object:

ng-options="country as country.countryName for country in $ctrl.countriesList"

so my dropdown is now correctly displaying the countryName property in the dropdown for each country, but it is still sorting by the ISO code value (DK, US) which in my case will often be inconsistent with the countrynames, so the sorting of countryNames in the dropdown is not alphabetical

How can I make the dropdown sort by countryName alphabetically? Thanks in advance!

Kozgal
  • 9
  • 5
  • Isn't it a duplicate of: http://stackoverflow.com/questions/12310782/sorting-dropdown-alphabetically-in-angularjs ? – Georgy Jan 30 '17 at 09:32
  • 1
    Possible duplicate of [Sorting dropdown alphabetically in AngularJS](http://stackoverflow.com/questions/12310782/sorting-dropdown-alphabetically-in-angularjs) – Manikandan Velayutham Jan 30 '17 at 09:38
  • thanks for the answers, but those are not duplicates of this, as they are trying to sort an array whereas I am trying to sort on an object. Thanks for the replies anyway :) – Kozgal Jan 30 '17 at 12:26

4 Answers4

0

You cannot use orderBy filter as you are using an Object Datasource and orderBy filter works for Array Data source

See this question

If you want to use orderBy filter make the changes to your data source as mentioned in other answers

If you want to go with objects, I would suggest you add a function which would return the sorted values.

In controller :

$scope.ctrl = {//---> Source
            countriesList : {
        'DK': {countryName: 'Denmark', preferredLanguage: 'DA'},
        'US': {countryName: 'USA', preferredLanguage: 'EN'},
        'BEL':{countryName: 'Belgium', preferredLanguage: 'NL'}
      }
}



 $scope.getSortedCountryList = function(){ //--> Sort Function
$scope.sorted = {};
Object.keys($scope.ctrl.countriesList)
        .sort(function(a,b){
          if($scope.ctrl.countriesList[a].countryName < $scope.ctrl.countriesList[b].countryName) return -1;
          if($scope.ctrl.countriesList[a].countryName > $scope.ctrl.countriesList[b].countryName) return 1;
          return 0;
         })
         .forEach(function(v, i) {
           $scope.sorted[v] = $scope.ctrl.countriesList[v];
         });
return $scope.sorted;
}

In HTML select

ng-options="country as country.countryName for country in getSortedCountryList()"

FIDDLE

Community
  • 1
  • 1
Nishant123
  • 1,968
  • 2
  • 26
  • 44
  • Okay so I guess it's not possible to sort on an object structure as mine. I will see if I can sort the structure using something like your suggestion or alternately change the entire data structure to an array. Will mark your answer as accepted - thanks! – Kozgal Jan 30 '17 at 12:28
  • I ended up using your sort function! Thanks a lot! – Kozgal Jan 30 '17 at 12:50
  • Found a way to slightly improve on your sorting by writing the .sort as such: .sort(function(a,b){ return countriesList[a].countryName.localeCompare(countriesList[b].countryName); }) just wanted to share this for good measure – Kozgal Jan 30 '17 at 15:56
  • Thanks for sharing :) – Nishant123 Jan 31 '17 at 04:54
-1

First of all rewrite your dataset to a more 'simple' / 'JSON' like approach. Since the orderByisn't (and also won't) implemented for Objects (link)

 $scope.countriesList = [
      {countryName: 'Denmark', preferredLanguage: 'DA'},
      {countryName: 'Belgium', preferredLanguage: 'NL'},
      {countryName: 'USA', preferredLanguage: 'EN'}
  ]

On view level :

<select ng-options="country.countryName for country in countriesList | orderBy:'countryName':false" ng-model="selected"></select>

SEE PLUNKR

daan.desmedt
  • 3,752
  • 1
  • 19
  • 33
  • If I do this I will loose the ISO code for example "DK" for denmark - I need this to be the key unfortunately – Kozgal Jan 30 '17 at 12:51
-1

use orderBy service in your select tag

<select  ng-options="country as country.countryName for country in ctrl.countriesList | orderBy:'countryName':false" ng-model="country">

also update the json

 $scope.ctrl.countriesList = [
  {countryName: 'Denmark', preferredLanguage: 'DA'},
  {countryName: 'USA', preferredLanguage: 'EN'}
  ]

Plunkr

jitendra varshney
  • 3,484
  • 1
  • 21
  • 31
  • This will only work when the dataModel is updated , not to use Objects. Please read the question correct. – daan.desmedt Jan 30 '17 at 09:50
  • user did not mentioned that – jitendra varshney Jan 30 '17 at 09:51
  • He states this literal in his question. He even shows the dataObject in his initial question. Your answer is incorrect. – daan.desmedt Jan 30 '17 at 09:52
  • i am not understanding buddy what are you saying? – jitendra varshney Jan 30 '17 at 09:55
  • Your answer is uncomplete. If the user changes his code according your answer it still won't work for him, his data object (`ctrl.countriesList`) is a `object based model`. Your answer implies on a key/value representation format. – daan.desmedt Jan 30 '17 at 09:57
  • you are thinking i have stolen your answer ?hahaha thats funny by the way i did not downvote you – jitendra varshney Jan 30 '17 at 10:06
  • Why OP needs to be change him JSON format? We should be answer to what you want from OP. Not to use. – Ramesh Rajendran Jan 30 '17 at 10:08
  • it also happened with me in morning , me and someone else answered same way but i do not think he/she copied my answer cause many people can think in same way it is natural – jitendra varshney Jan 30 '17 at 10:09
  • He should at best practive do change his data type, https://github.com/angular/angular.js/issues/1286 - If he wants to work into guidelines of AngularJS. Otherwise he should create a custom filter , which creates overhead ... Why reinvent the wheel if it's already provided for use... – daan.desmedt Jan 30 '17 at 10:10
  • but user is not responding, may key value pair is unnecessary thats why i have posted it @Ramesh – jitendra varshney Jan 30 '17 at 10:11
-1

You can also sort your array directly in Javascript.

$scope.countriesList = [
      {countryName: 'Denmark', preferredLanguage: 'DA'},
      {countryName: 'Belgium', preferredLanguage: 'NL'},
      {countryName: 'USA', preferredLanguage: 'EN'}
  ]
.sort(function(a, b){
  return a.countryName < b.countryName;
});
Charly berthet
  • 1,178
  • 5
  • 15
  • 31