var app = angular.module('plunker', []);

app.controller('MainCtrl', ["$scope","sortableColumnsService",function($scope,sortableColumnsService) {
  $scope.list = [
    {name:"dani din",age:57,role:"admin"},
    {name:"moshe levi",age:21,role:"user"},
    {name:"ziv cohen",age:28, role:"user"},
    {name:"dafna shkuri",age:45, role:"user"},
    {name:"rani ko", age:24,role:"admin"}
    ];

    //The directive mediator which we send to the directive (via markup)      
    $scope.sharedLogic = {};
}]);

<!DOCTYPE html>
<html ng-app="plunker">
 
  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <!--Bootstrap 3.1.1 CSS from CDN-->
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
    <!--Font-Awsome CSS from CDN-->
    <link href="//netdna.bootstrapcdn.com/font-awesome/3.1.1/css/font-awesome.css" rel="stylesheet">
    <!--My CSS file-->
    <link rel="stylesheet" href="style.css" />
 
  </head>

  <body ng-controller="MainCtrl">
    <!--This is the "heading" row which enable sortign as a directive-->
    <sortable-columns-headers-row shared-logic="sharedLogic" items-to-sort="list"></sortable-columns-headers-row>
    
    <!--The rows of the table being repeted using ngRepeat-->
    <div ng-repeat="item in list">
      <div class="row tableRow" ng-class="{'isOpen':item.open}" ng-click="item.open = !item.open">
        <div class='col-xs-3'>{{item.name}}</div>
        <div class='col-xs-2'>{{item.age}}</div>
        <div class='col-xs-2'>{{item.role}}</div>
      </div>
    
      <!--The collapsable container of each row -->
      <div class="row" ng-class="{'collapse':!item.open}">
        <div class="col-xs-12 rowCntent">
          This is additional collapsable data: <br />
          <strong>Name: </strong> {{item.name}} <br />
          <strong>Age: </strong> {{item.age}} <br />
          <strong>Role: </strong> {{item.role}} <br />
        </div>
      </div>
    </div>
    
    <!--Scripts-->
    <!--AngularJS-->
    <script data-require="angular.js@1.2.x" src="https://code.angularjs.org/1.2.16/angular.js" data-semver="1.2.16"></script>
    <!--Underscore-->
    <script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
    <!--My App -->
    <script src="app.js"></script>
    <!--Sortable colunbs header directive -->
    <script src="sortable-columns-headers.directive.js"></script>
    <!--Sortable colunbs header service -->
    <script src="sortable-columns-headers.service.js"></script> 
    
  </body>
</html>
/* Put your css in here */

.tableRow:hover{
  cursor:pointer;
  background-color:gray;
}


.tableRow.isOpen{
  background-color:gray;
}

.rowCntent{
  background-color:yellow;
  padding:10px;
  margin-left:10px;

}

.columnDisabled{
  color:gray;
}
<div class="row">
    <div ng-repeat="column in sortableColumnsService.columns" class="{{column.class}}" ng-class="{'columnDisabled':!sortableColumnsService.enableSorting}">
        <div ng-if="column.sortable" ng-click="columnClicked(column)" style="cursor:pointer;">
            <strong>{{column.text}} <i  ng-if="column.sortable"
                                       ng-class="
                                       {
                                        'icon-sort':column.predicate !== sortableColumnsService.thisColumnToSort.predicate,
                                        'icon-sort-down':column.predicate == sortableColumnsService.thisColumnToSort.predicate && !column.reverse,
                                        'icon-sort-up': column.predicate == sortableColumnsService.thisColumnToSort.predicate && column.reverse
                                       }"></i></strong>
        </div>
        <div ng-if="column.sortable == false"> <!-- Show only text with no sorting icons -->
            <strong>{{column.text}}</strong>
        </div>

    </div>
</div>

/**
 *The directive which holds the sorting logic of the itemsToSort array (uses underscore "sortBy")
 **/
app.directive('sortableColumnsHeadersRow', ["sortableColumnsService",function (sortableColumnsService) {
        return {
            restrict:'E',
            replace:true,
            templateUrl:"sortable-columns-headers.tpl.html",
            scope:{
                itemsToSort:"=",
                sharedLogic:"="
            },
            link:function(scope,elm,attr){
                scope.sortableColumnsService = sortableColumnsService;
              
                scope.columnClicked = function(column){
                    if(scope.sortableColumnsService.enableSorting){
                        if(scope.sortableColumnsService.thisColumnToSort.predicate === column.predicate){
                            scope.sortableColumnsService.thisColumnToSort.reverse = !scope.sortableColumnsService.thisColumnToSort.reverse;
                        }else{
                            scope.sortableColumnsService.thisColumnToSort = column;
                        }
                        scope.sortBy(scope.sortableColumnsService.thisColumnToSort);
                    }
                };

                /**
                 * This function sorts the items according to the column selected 
                 **/
                scope.sortBy = function(column){
                    scope.itemsToSort = _.sortBy(scope.itemsToSort,function(obj){
                        switch (column.dataType){
                            case "number":
                                return Number(obj[column.predicate]);
                            case "date":
                                return new Date(obj[column.predicate]);
                            default:
                                return obj[column.predicate].toString();
                        }
                    });

                    if(column.reverse){
                        scope.itemsToSort = scope.itemsToSort.reverse();
                    }
                };

                /**
                 * This function available to the controller via the sharedLogic object
                 * and it manually sorts the items acording the selected column
                 **/
                scope.sharedLogic.sort = function(){ 
                    scope.sortBy(scope.sortableColumnsService.thisColumnToSort);
                };

                /**
                 * This function available to the controller via the sharedLogic object
                 * Tt enabling or disabeling the sorting
                 **/
                scope.sharedLogic.isEnableSorting = function(val){
                    scope.sortableColumnsService.enableSorting = val;
                };

                //Initiation of the directive
                scope.sortableColumnsService.thisColumnToSort = scope.sortableColumnsService.columns[0];
                scope.sortBy(scope.sortableColumnsService.thisColumnToSort);
            }
            
        }

    }]);
/**
 *The service which holds properties regarding the columns headers
 * It should be changed according to the items which are being passed to the directive
 **/
app.service("sortableColumnsService",[function(){
  return {
    enableSorting:true, // Set it to false for disabel sorting
    columns:[
              {
                  text:"Name",
                  class:"col-xs-3",
                  predicate:"name",
                  sortable:true,
                  reverse:true
              },
              {
                  text:"Age",
                  class:"col-xs-2",
                  sortable:true,
                  predicate:"age",
                  reverse:false,
                  dataType:"number"
  
              },
              {
                  text:"Role",
                  class:"col-xs-2",
                  sortable:true,
                  predicate:"role",
                  reverse:false
              }
        ]
  }
}])