Created
May 1, 2014 22:33
-
-
Save spitimage/df87a07d85f416ec47d0 to your computer and use it in GitHub Desktop.
Lightweight AngularJS sortable grid
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
angular.module('moduleName') | |
.controller('GridCtrl', function ($scope) { | |
// Data for the sorted table demo | |
$scope.data = [ | |
{field1: 'a', field2: 'z'}, | |
{field1: 'b', field2: 'y'}, | |
{field1: 'c', field2: 'x'}, | |
{field1: 'd', field2: 'w'} | |
]; | |
$scope.sortCb = function(field, dir){ | |
$scope.$apply(function(){ | |
$scope.data.sort(function(a, b){ | |
if(a[field] < b[field]){ | |
return -dir | |
} | |
if(a[field] > b[field]){ | |
return dir | |
} | |
return 0; | |
}) | |
}) | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
angular.module('moduleName') | |
.directive('sortedtable', function () { | |
return { | |
restrict: 'E', | |
scope: { | |
sort: '=' | |
}, | |
controller: function ($scope) { | |
var children = []; | |
// Add child column subscribers | |
this.addChild = function(cb){ | |
children.push(cb); | |
}; | |
this.sort = function(field, dir){ | |
// Invoke the sort callback if it exists | |
if($scope.sort){ | |
$scope.sort(field, dir); | |
} | |
// Notify all children columns that a sort has been applied to this field | |
children.forEach(function(cb){ | |
cb(field); | |
}) | |
} | |
} | |
}; | |
}) | |
.directive('sortedcolumn', function () { | |
return { | |
restrict: 'A', | |
require: '^sortedtable', | |
scope: {}, | |
link: function postLink(scope, element, attrs, controller) { | |
var origText = element.text(); | |
var origField = attrs.sortedcolumn; | |
var direction = 1; | |
// On clicks, render the carat in the column and call the controller | |
element.on('click', function(){ | |
if(direction > 0){ | |
element.text(origText + ' \u25B2'); | |
} else { | |
element.text(origText + ' \u25BC'); | |
} | |
direction = -direction; | |
controller.sort(origField, direction); | |
}); | |
// Register this column controller with the parent table controller | |
controller.addChild(function(field){ | |
// Render original text if this column isn't the target | |
if(field != origField){ | |
element.text(origText); | |
} | |
}); | |
} | |
}; | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
describe('Directive: sortedtable', function () { | |
beforeEach(module('moduleName')); | |
var scope, element; | |
var table = '<sortedtable sort="sortCb"><table><thead><tr>' + | |
'<th sortedcolumn="field1">Field1</th><th sortedcolumn="field2">Field2</th>' + | |
'</tr></thead></table></sortedtable>'; | |
beforeEach(inject(function ($rootScope, $compile) { | |
scope = $rootScope.$new(); | |
scope.sortCb = jasmine.createSpy('sort'); | |
element = angular.element(table); | |
$compile(element)(scope); | |
})); | |
it('Sort callback should be called with first field', function () { | |
var th = angular.element(element.find('th')[0]); | |
th.triggerHandler('click'); | |
expect(scope.sortCb).toHaveBeenCalledWith('field1', -1); | |
}); | |
it('Sort callback should be called with second field', function () { | |
var th = angular.element(element.find('th')[1]); | |
th.triggerHandler('click'); | |
expect(scope.sortCb).toHaveBeenCalledWith('field2', -1); | |
}); | |
it('Change sort direction after second click', function () { | |
var th = angular.element(element.find('th')[0]); | |
th.triggerHandler('click'); | |
th.triggerHandler('click'); | |
expect(scope.sortCb).toHaveBeenCalledWith('field1', 1); | |
}); | |
it('Display unicode up carat in header text after click', function () { | |
var th = angular.element(element.find('th')[0]); | |
th.triggerHandler('click'); | |
expect(th.text()).toBe('Field1 \u25B2'); | |
}); | |
it('Display unicode down carat in header text after second click', function () { | |
var th = angular.element(element.find('th')[0]); | |
th.triggerHandler('click'); | |
th.triggerHandler('click'); | |
expect(th.text()).toBe('Field1 \u25BC'); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div ng-controller="GridCtrl"> | |
<h3>Sorted Table Demo:</h3> | |
<sortedtable sort="sortCb"> | |
<table class="table table-bordered table-striped"> | |
<thead> | |
<tr> | |
<th width="50%" sortedcolumn="field1">Field1</th> | |
<th width="50%" sortedcolumn="field2">Field2</th> | |
</tr> | |
</thead> | |
<tbody> | |
<tr ng-repeat="item in data"> | |
<td>{{ item.field1 }}</td> | |
<td>{{ item.field2 }}</td> | |
</tr> | |
</tbody> | |
</table> | |
</sortedtable> | |
</div> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment