If you’ve ever worked in an AngularJS environment, you’ll be familiar with the built in ‘orderBy’ filter which is used to organize data based on a predefined or user-selected expression. But what happens if we’re looking to add more complex sorting to make data more readable and engaging? The orderBy filter can take care of this too!
For instance, we make a call to a web service and we receive the following data:
We have received multiple entries with a key-value pair of “name”: “Andy”, as well as some similarities and differences between their ages and favourite colours.
Sorting With Precision
If we were to display this data in a table using Angular’s ng-repeat and we were to orderBy:‘name’, the ‘Andys’ would be grouped together and sorted by ages 32, 25, 55, 25. This is fine, but what if we receive an array of 3000 different people and there are a significant number of ‘Andys’? The data would be a headache to decipher like this. This is where more precise sorting comes in handy.
Check out the following Plunker:
We have all of our data displayed in a table using an ng-repeat. Beneath it are primary-sort, secondary-sort, and third-sort buttons. Each adds a new level of precision. Under Primary Sort, click on ‘Name’. Notice the list is now organized alphabetically? This is applying the standard orderBy:’name’ filter that we are familiar with. Next, click on ‘Age’ under Secondary Sort. Now we maintain our alphabetical sorting, but the age is now sorted in ascending order. Pretty cool! Now at the top of our table, we have two ‘Andys’ with the same age but different different colours. We can get even more precise sorting. Click on the ‘Favourite Colour’ button in the Third Sort box. Now we have our names sorted alphabetically, our ages sorted in ascending order, AND our colours sorted in alphabetical order if lines have the same name and age!
Applying this sorting is fairly straightforward. Typically when ordering by one value, we set up our repeater like this, for example:
When ordering by multiple values, we are passing an array rather than a single $scope variable or a hardcoded value like this:
The ordering of these scope values does make a difference. Primary will take priority over Secondary and Secondary will take priority over Third and so forth. Primary must also be set first before Secondary’s sort can take action. Each of these $scope variables can be defined in the controller however you wish. In our example, we are passing setting these values with a function on button clicks.
Our primary buttons are set up like this in the view:
In our controller, our function is set up like this:
Note: in order to add reverse sorting functionality, we must define this in the controller rather than in the view as we would with a single value. We can simply add reverse sorting by including a condition such as we did above where we check to see if the selected predicate is the same. If it is, we append a ‘-‘ to the beginning of the predicate.
Now a user can click the same sorting function and have access to both ascending and descending sorting, including with secondary and subsequent ordering, without defining reverse as defined in the docs:
Feel free to play around with the example code and experiment with different sorting options here: http://plnkr.co/edit/bLH8bw?p=preview