Skip to content

Instantly share code, notes, and snippets.

@jimmont jimmont/sortable.js
Created Apr 16, 2015

Embed
What would you like to do?
sort it out in angular
/**
* @ngdoc directive
* @name sortable
* @restrict A
*
* @description
* setup an object on the scope for handling a list: sorting, filtering, etc
* NOTE that track by statements must go at the end of the expression, after the orderBy statement
*
* @example
<table sortable ng-init="columns=3; data=[{name:'Bill',color:'Brown',id:1}, {name:'Bob',color:'Green',id:3}, {name:'Bertha',color:'Blue',id:5}, {name:'Bob',color:'Yellow',id:9}]">'
<thead>
<tr><th colspan="{{ columns }}">
<input type=text ng-model="sortable.filter" placeholder="filter">
<input min={{sortable.min}} max={{sortable.max}} type=number title="max ({{sortable.min}}-{{sortable.max}})" ng-model="sortable.limit" >
</th></tr>
<tr>
<th ng-click="sortable.sortBy(key);" ng-repeat="(key, value) in data[0] track by $index">{{ key }}</th>'
</tr>
<thead>
<tbody>
<tr ng-repeat="item in data | filter: sortable.filter | limitTo: sortable.limit | orderBy: [sortable.field, 'id'] : sortable.reverse track by $index">'
<td ng-repeat="(key, value) in item" class="{{key}}">{{ value }}</td>'
</tr>
</tbody>
</table>
*
*/
.directive('sortable', function(){
return {
restrict: 'A'
,controller: function($scope){
/**
* @ngdoc object
* @name sortable
* @description
* an object with properties conveniently places on the current scope (for manipulating a collection)
* add new properties or use existing ones for filtering, limiting, ordering
*
* @param { function } sortBy for handling toggling the sortable.field string through 3 options 'key', '-key', '' which are sorting by key, reversing it, turning it back off
* @param { string } filter for filtering
* @param { integer } min limiting
* @param { integer } max limiting
* @param { boolean } reverse for flipping the sorting
* @param { string } field for ordering, any value, sortBy toggles it through the 3 options '', 'key', '-key'
*
*/
$scope.sortable = {
filter: ''
,limit: 100
,min: 10
,max: 10000
,reverse: false
,field: ''
,sortBy: function sortBySetup(key){
var _key;
if(!key) return;
switch( this.field ){
case '-'+key:
// cycle back off
_key = '';
break;
case key:
// reverse by key
_key = '-'+key;
break;
default:
// order by key
_key = key;
}
this.field = _key;
}
};
}
}
})
;
/* unit test */
describe('sortable', function(){
var scope, element, i = 0, sortable;
beforeEach( inject(function($injector, $rootScope, $compile){
scope = $rootScope.$new();
scope.list = [1,2,3,4,5];
element = $compile('<table sortable data="list"></table>')(scope);
scope.$digest();
}) );
it('should create an object on the scope', function(){
//sortable = element.find('table').scope().sortable;
sortable = element.scope().sortable;
expect( sortable.limit ).toBe( 100 );
expect( sortable.min ).toBe( 10 );
expect( sortable.reverse ).toBe( false );
// cycle thru possibilities
sortable.sortBy('key');
expect( sortable.field ).toBe( 'key' );
sortable.sortBy('key');
expect( sortable.field ).toBe( '-key' );
sortable.sortBy();
// unchanged by empty
expect( sortable.field ).toBe( '-key' );
sortable.sortBy('key');
expect( sortable.field ).toBe( '' );
});
})
;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.