Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS ng-repeat orderBy orders numbers incorrectly

I'm having an issue with using the ng-repeat orderBy when there are numbers in text.

Sample Data:

[
   {booth: 'p1'},
   {booth: 'p2'},
   {booth: 'p3'},
   {booth: 'p4/5'},
   {booth: 'p6/7'},
   {booth: 'p8'},
   {booth: 'p9'},
   {booth: 'p10'},
   {booth: 'p11'},
   {booth: 'p12'},
   {booth: 'p13'}
]

When using the ng-repeat with the orderBy: 'booth' is list it out as such: p1, p10, p11, p13, p2, ect

I understand this is expected behavior but does anyone know how I can get it to list out the booths in the order that I expect?

Which would be: p1, p2, p3, p4/5, ect

I have also tried seeing if the issue was because the numbers weren't integers but returned the same issue.

Thank you in advance for any help.

like image 656
creatifyme Avatar asked Jun 17 '13 20:06

creatifyme


1 Answers

JavaScript's built-in string comparison won't work for your purposes. I think what is needed is a natural sort, to sort the strings the way a human would. I found a solid implementation here from the blog here. It is pretty comprehensive and fairly complex so I won't try to explain the source code here (check the blog for explanation).

You can then create a custom filter for the natural sort and use in your HTML like:

HTML

<div ng-app="myApp">
    <div ng-controller="ctrlMain">
        <div ng-repeat="item in data | naturalSort">{{item.booth}}</div>
    </div>
</div>

Javascript - I've left out the implementation of the sort since it's long and not created by me, but check the demo at the bottom to see it in action.

app.filter('naturalSort',function(){
    function naturalSort (a, b) {
        // Please see the demo for this code, it is somewhat long.
    }
    return function(arrInput) {
        var arr = arrInput.sort(function(a, b) {
            return naturalSort(a.booth,b.booth);
        });
        return arr;
    }
});

The sort implementation in the demo below covers various possibilities (date, hex values, whitespace) that could be used in many situations (though it may be a little overkill for your example).

Here is a demo

like image 173
Dan Avatar answered Nov 30 '22 02:11

Dan