0

I have a list of objects in a table-view i would like to sort properly.

Amongst other things, my objects contain a name-field. This name field can also contain numbers, so for example: Chairman Seat 1 Seat 2 Seat 3 Seat 11 Seat 12 Seat 23 Secretary

This is however sorted like this: Chairman Seat 1 Seat 11 Seat 12 Seat 2 Seat 23 Seat 3 Secretary

This doesn't seem like a natural way of sorting my list when sorting by name.

Now i'm using the ng-repeat like this: seat in seats | orderBy:orderField:orderReverse track by seat.id Where orderfield is some variable that is set when clicking the table header and orderReverse is too for reversing.

I've tried making a custom filter to makes sure it behaves properly but i failed. It seems that Javascript just won't order it normally unless i break up the string. But i'd rather not because the data is often updated by polling. Another way would be to force leading zero's but since users are entering this stuff manually i'm not sure if i should.

Also, its not only names with numbers in them, so i can't just completely cut them off

So, any suggestions on how to make this list show normally?

Edit: cleared up some info about the problem.

8
  • You should write your own sorting function. Commented Sep 10, 2014 at 13:35
  • Search for "natural sort". Commented Sep 10, 2014 at 13:42
  • @dfsq i could do that but how would i know the difference between with number and without. And how would i give them the proper order? Commented Sep 10, 2014 at 14:23
  • @blackhole, i've tried that before submitting but that doesn't really seem to work if you want to sort by multiple columns correctly. I'll investigate further and post a jsfiddle if i can't work it out. Commented Sep 10, 2014 at 14:24
  • And why did my question get -1? It had enough info to create an answer didn't it? Commented Sep 10, 2014 at 21:44

1 Answer 1

5

You can use a custom sort function with orderBy (it can take custom sorting function too)

define a sort function in your controller:

$scope.sorter = function (a){
   return parseInt(a.replace( /^\D+/g, '')); // gets number from a string
}

and then in your template

seat in seats | orderBy:sorter track by seat.id

Edit as per the modified problem statement:

Do manual sorting in controller instead of with ng-repeart using naturalSort

$scope.seats = [{"id": "Seat 12"},{"id": "Seat 3"},{"id": "Seat 1"},{"id": "Seat 2"},{"id": "Secretary"}];
$scope.seats.sort(function(a,b) {
    return naturalSort(a.id, b.id);
})

or check this angular module http://blog.overzealous.com/post/55829457993/natural-sorting-within-angular-js and the fiddle demonstrating it - http://jsfiddle.net/wE7H2/3/

Sign up to request clarification or add additional context in comments.

8 Comments

I've cleared it up a bit: it also contains normal strings, so i need to keep them around too.
Then I will point you to overset.com/2008/09/01/javascript-natural-sort-algorithm and suggest you to do manual sorting in controller instead of with ng-repeart
Updated the answer! You can remove the old answer if the later works for you!
I've found this blog.overzealous.com/post/55829457993/…. Probably this should work for you!! Jsfiddle demostrating it - jsfiddle.net/wE7H2/3
I've tried your solution and ended up with a slight adjustment. Mainly because i have multiple columns to filter by and refresh my code with promises. I also didn't use this naturalsort library but a similar one found here: bennadel.com/blog/… . But thanks for pointing me in the right direction.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.