I am trying to write a directive to deal with changing an icon class for table headers. What I would like is (what I believe anyway) the standard way of dealing with sorting by table headers. The directive would add a link element and upon a user's click sort by desc and change the icon to desc, upon click again sort by asc and once again the the icon. Here is what I have so far, but I am now at a loss for how to deal with the icon class as well as resetting other elements on the same table but outside of the directive's scope. Any help would be great!
angular.directive("tableHeaders", function() {
return {
restrict: 'E',
scope: {},
template:'<i class="glyphicon glyphicon-filter"></i>',
link: function(scope, element, attrs) {
attrs.class = 'glyphicon glyphicon-sort-by-alphabet-alt';
}
}
});
Here is what I have for the html side:
<th>First Name<a ng-click="newOrderBy('_firstName')"><table-headers></table-headers></a></th>
<th>Last Name<a ng-click="newOrderBy('_lastName')"><table-headers></table-headers></a></th>
<tr ng-repeat="item in items | orderBy:orderBy:reverse>
<td>{{item._firstName}}</td>
<td>{{item._lastName}}</td>
</tr>
The order by is currently handled in the controller:
$scope.newOrderBy = function(order) {
$scope.orderBy = order;
$scope.reverse = !$scope.reverse;
};
What you need to do is for each element using your directive providing both an order and the current order (the one from your controller).
BTW I think your directive will be a better match as an attribute and not a tag. You can check the following code :
angular.module('myApp', []).directive("sort", function() {
return {
restrict: 'A',
transclude: true,
template :
'<a ng-click="onClick()">'+
'<span ng-transclude></span>'+
'<i class="glyphicon" ng-class="{\'glyphicon-sort-by-alphabet\' : order === by && !reverse, \'glyphicon-sort-by-alphabet-alt\' : order===by && reverse}"></i>'+
'</a>',
scope: {
order: '=',
by: '=',
reverse : '='
},
link: function(scope, element, attrs) {
scope.onClick = function () {
if( scope.order === scope.by ) {
scope.reverse = !scope.reverse
} else {
scope.by = scope.order ;
scope.reverse = false;
}
}
}
}
});
And the plunker that goes with it : http://plnkr.co/edit/P4cAm2AUGG36nejSjOpY?p=preview
The directive is used as such :
<thead>
<tr>
<th sort by="order" reverse="reverse" order="'name'">Name</th>
<th>Phone</th>
<th sort by="order" reverse="reverse" order="'age'">Age</th>
</tr>
</thead>
Unless you are intent on writing your own directive, you might consider looking at what is available. ngmodules.org shows some directives that are already set up for table headers.
Here are a couple options with some sample code to give you a feel for both. They both look to be developed and very customizable.
angular.module('main', ['ngTable'])
.controller('DemoCtrl', function($scope, $filter, ngTableParams) {
var data = [{name: "Moroni", age: 50}, ... ]
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
sorting: {
name: 'asc' // initial sorting
}
}, {
total: data.length, // length of data
getData: function($defer, params) {
// use build-in angular filter
var orderedData = params.sorting() ?
$filter('orderBy')(data, params.orderBy()) :
data;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
});
angular.module('app', ['ngAnimate', 'ui.grid'])
.controller('MainCtrl', function ($scope) {
$scope.gridOptions1 = {
enableSorting: true,
columnDefs: [
{ field: 'name' },
{ field: 'gender' },
{ field: 'company', enableSorting: false }
],
onRegisterApi: function (gridApi) {
$scope.grid1Api = gridApi;
}
};
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With