Sorting Rows By Table Header In AngularJS

Overview
 
In this article, we will see how we sort the data by table header. In my earlier article, we saw how to sort data by ascending and descending order. This is an extension of that article. So, please refer to my previous article here:
 
 
Introduction
 
We will see how to sort data in a bidirectional manner, in AngularJS. What we want here is that when we click on column header, we can sort  the data in ascending and descending order. Initially, we have a drop-down for sorting the data. Here, we will click on the column header to sort that data in ascending or descending order.
 
Let's see the example. We go back to our model that we used in our previous part, Sorting Data in AngularJS. 
  1. var mypartone = angular  
  2. .module("mymodule", [])  
  3. .controller("myController"function ($scope) {  
  4. var employees = [  
  5. { name: "Akshay", dateOfBirth: new Date("July 21,1960"), Address: "Mumbai", Salary: "1234.34" },  
  6. { name: "Milind", dateOfBirth: new Date("July 20,1960"), Address: "Nashik", Salary: "12.34" },  
  7. { name: "Raghvan", dateOfBirth: new Date("July 19,1960"), Address: "Pune", Salary: "1235.34" },  
  8. { name: "Hari", dateOfBirth: new Date("July 18,1960"), Address: "Mumbai", Salary: "5589.34" }  
  9.   
  10.   
  11. ];  
  12. $scope.employees = employees;  
  13. $scope.SortColumn = "name";  
  14. });  
As you can see from the model, we have employee array and we are attaching that to our $scope. In that $scope object, we are passing sortColumns. It will pop a drop-down list to sort the data but we want a clickable column name for the same.
 
Now, in that model, we are attaching reverseSort that will be a Boolean property.
  1. $scope.reverseSort=false;  
Now, we will add a function that sorts a value of our column name.
  1. $scope.SortData = function (column) {  
  2. $scope.reverseSort = ($scope.SortColumn==column) ? !$scope.reverseSort :false  
  3.   
  4. }  
Now, look at the function carefully. Here, we have attached sortdata to our scope object and in that, we applied the if else condition.
 
($scope.SortColumn==column) ? If this is true, then it will sort the column or else
? !$scope.reverseSort :false it will set to false to set as false we had used !(NOT) operator.
  1. $scope.SortData = function (column) {  
  2. $scope.reverseSort = ($scope.SortColumn == column) ? !$scope.reverseSort : false;  
  3. $scope.SortDate = column;  
  4.   
  5. }  
Now, I am going to attach another function here, getSortClass. In this function, we will loop another if condition. So, if that value is true, it will sort the data in ascending or descending order.
  1. $scope.getSortClass = function (column)  
  2. {  
  3. if ($scope.SortColumn == column) {  
  4. return $scope.reverseSort ? 'arrow-down' : 'arrow-up'  
  5. }  
  6. }  
Here, I am passing if statement. If $scope.SortColumn is true, then it will return that reverse sort; else, it will return a CSS class which is up arrow and down arrow.
 
To add a CSS class, just write these lines in CSS.
  1. .arrow-up {  
  2. width:0;  
  3. height:0;  
  4. border-left:5px solid transparent;  
  5. border-right:5px solid transparent ;  
  6. border-bottom:10px solid black;  
  7. }  
  8.   
  9. .arrow-down {  
  10. width:0;  
  11. height:0;  
  12. border-left:5px solid transparent;  
  13. border-right:5px solid transparent;  
  14. border-top:10px solid black;  
  15. }  
Now, if you need to return an empty string, sorting is available for only one column and for the rest of the columns, it should return empty string.
 
Return ‘’;
 
So, our final Model code is :
  1. /// <reference path="angular.min.js" />  
  2. //Create a module  
  3. var mypartone = angular  
  4.                     .module("mymodule", [])  
  5.                     .controller("myController"function ($scope) {  
  6.                         var employees = [  
  7.                             { name: "Akshay", dateOfBirth: new Date("July 21,1960"), Address: "Mumbai", Salary: "1234.34" },  
  8.                             { name: "Milind", dateOfBirth: new Date("July 20,1960"), Address: "Nashik", Salary: "12.34" },  
  9.                              { name: "Raghvan", dateOfBirth: new Date("July 19,1960"), Address: "Pune", Salary: "1235.34" },  
  10.                               { name: "Hari", dateOfBirth: new Date("July 18,1960"), Address: "Mumbai", Salary: "5589.34" }  
  11.                                  
  12.   
  13.   
  14.                         ];  
  15.                         $scope.employees = employees;  
  16.                         $scope.SortColumn = "name";  
  17.                         $scope.reverseSort = false;  
  18.   
  19.   
  20.                         $scope.SortData = function (column) {  
  21.                             $scope.reverseSort = ($scope.SortColumn == column) ? !$scope.reverseSort : false;  
  22.                             $scope.SortDate = column;  
  23.   
  24.                         }  
  25.   
  26.                         $scope.getSortClass = function (column)  
  27.                         {  
  28.                             if ($scope.SortColumn == column) {  
  29.                                 return $scope.reverseSort ? 'arrow-down' : 'arrow-up'  
  30.   
  31.                             }  
  32.                             return '';  
  33.   
  34.                         }  
  35.                             
  36.                     });  
Now, we will get back to our View. 
 
Currently, our output is:
 
 
 
We need an up arrow and a down arrow to sort our data. We need to sort our data by name. So, in our th section, we need to pass ng-click directive and SortClass,  and bind them by name, as 
  1. <th ng-click="sortData('name')">  
Now, we need the up arrow and the down arrow. To display these, we will include a div section and pass ng-class in which we will call getSortClass, as:
  1. Name<div ng-class="getSortClass('name')" ></div>  
Similarly, do it for the other columns too.
  1. <th ng-click="sortData('name')">  
  2. Name<div ng-class="getSortClass('name')" ></div>  
  3. </th>  
  4. <th ng-click="sortData('dateOfBirth')" >Date of Birth <div ng-class="getSortClass('dateOfBirth')" ></div>  
  5.   
  6. </th>  
  7. <th ng-click="sortData('Address')">Address <div ng-class="getSortClass('Address')" ></div>  
  8.   
  9. </th>  
  10. <th ng-click="sortData('Salary')">Salary <div ng-class="getSortClass('Salary')" ></div>  
  11.   
  12. </th>  
  13. <th ng-click="sortData('Salary')">Salary <div ng-class="getSortClass('Salary')" ></div>  
  14.   
  15. </th>  
Also, we need to pass in reverseSort in ng-repeat, to sort the data. 
  1. <tr ng-repeat="employee in employees|orderBy:SortColumn:reverseSort">  
So, our View code is ::
  1. <table>  
  2. <thead>  
  3. <tr>  
  4. <th ng-click="SortData('name')">  
  5. Name<div ng-class="getSortClass('name')" ></div>  
  6. </th>  
  7. <th ng-click="SortData('dateOfBirth')" >Date of Birth  
  8. <div ng-class="getSortClass('dateOfBirth')" ></div>  
  9.   
  10. </th>  
  11. <th ng-click="SortData('Address')">Address  
  12. <div ng-class="getSortClass('Address')" ></div>  
  13.   
  14. </th>  
  15. <th ng-click="SortData('Salary')">Salary  
  16. <div ng-class="getSortClass('Salary')" ></div>  
  17.   
  18. </th>  
  19. </tr>  
  20. </thead>  
  21. <tbody>  
  22. <tr ng-repeat="employee in employees|orderBy:SortColumn:reverseSort">  
  23. <td>{{employee.name | uppercase }}</td>  
  24. <td>{{employee.dateOfBirth | date : "dd/MM/yyyy" }}</td>  
  25. <td>{{employee.Address | lowercase }}</td>  
  26. <td>{{employee.Salary | number :2 }}</td>  
  27. <%-- <td>{{employee.Salary| currency }}</td>--%>  
  28. </tr>  
  29.   
  30. </tbody>  
  31. </table>  
Now, just reload the page.
 
 
 
When we click on Name section, the data is sorted.
 
 
 
Conclusion
 
So, this was about sorting the data by Table Header, in AngularJS. Hope this article was helpful !!
 
Also refer to my previous articles on AngularJS.


Similar Articles