Created
May 7, 2012 20:18
-
-
Save dalcib/2630138 to your computer and use it in GitHub Desktop.
Angular 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
////////////////////////////////////// | |
/// Grid Directive to Angular 1.0.0rc7 | |
////////////////////////////////////// | |
// To use: | |
// <script> | |
// var app = angular.module('myapp', ['ngGrid']); | |
// var Ctrl = function($scope) { $scope.todo = [...] } | |
// </script> | |
// <div ng-app="myapp"> | |
// <div ng-controller="Ctrl"> | |
// <table ng-grid > | |
// <tr ng-repeat="todo in todos"> | |
// <td >{{todo.name}}</td> | |
// <td >{{todo.estimate | number}}</td> | |
// <td width="50">{{todo.done }}</td> | |
// <td title="Create At">{{todo.created_at | date}}</td> | |
// </tr> | |
// </table> | |
// </div> | |
// </div> | |
//// ngGrid Module | |
(function(angular) { | |
angular.module('ngSkip', []).filter('skip', function() { | |
return function(array, skipAt) { | |
return array.slice(skipAt); | |
}; | |
}); | |
angular.module('ngGrid', ['ngSkip']).directive('ngGrid', function() { | |
var direc = { | |
compile: function compile(tElement, tAttrs) { | |
//HEADER | |
var header = angular.element('<thead><tr></tr></thead>'), | |
headerRow = header.children('tr'), | |
count = 0, | |
tr = tElement.children('tbody').children('tr'), | |
expa = tr.attr('ng-repeat'); | |
tr.attr('ng-repeat', expa + '| skip:ngGridSortPagination.skipAt | orderBy:ngGridSortPagination.predicate:ngGridSortPagination.reverse | limitTo:ngGridSortPagination.limit'); | |
angular.forEach(tr.children('td'), function(elm) { | |
var column = angular.element(elm), | |
expc = column.html(), | |
exp = expc.replace(/[{}\s]/g, ""), | |
name = exp.split(/\.(.+)?/)[1].split(/\|/)[0], | |
filter = exp.split(/\.(.+)?/)[1].split(/\|/)[1], | |
filterAttrib = (!filter) ? "" : ' filter="' + filter + '"', | |
title = column.attr('title') || name, | |
width = column.attr('width') || 100; | |
headerRow.append('<th class="ui-state-default" name="' + name + '"' + filterAttrib + '" style="cursor: pointer;width: ' + width + 'px; font-weight:bold"><span style="display:inline-block"> </span>' + title + '</th>'); | |
column.addClass('ui-widget-content'); | |
column.attr('title', null); | |
count += 1; | |
}); | |
tElement.addClass('ui-widget'); | |
tElement.prepend(header); | |
//PAGINATION | |
var footer = '<tfoot class="ui-state-default"><tr><td align="center" colspan="' + count + '">' + '<span style="cursor: pointer; display:inline-block; margin-left:10px;; vertical-align:middle" class="ui-icon ui-icon-seek-first ui-state-disabled"></span>' + '<span style="cursor: pointer; display:inline-block; margin-left:10px;; vertical-align:middle" class="ui-icon ui-icon-seek-prev ui-state-disabled"></span>' + '<span style="display:inline-block; margin-left:10px;" class="ui-state-disabled">|</span>' + '<span >Page<input id="ui-pg-input" ng:model="ngGridSortPagination.page" class="ui-pg-input" type="text" size="2" maxlength="4" value="0"> of <span >{{ngGridSortPagination.lastPage}}</span></span>' + '<span style="display:inline-block" class="ui-state-disabled" style="margin-left:5px;">|</span>' + '<span style="cursor: pointer; display:inline-block; vertical-align:middle; margin-left:10px;" class="ui-icon ui-icon-seek-next"></span>' + '<span style="cursor: pointer; display:inline-block; vertical-align:middle; margin-left:10px;" class="ui-icon ui-icon-seek-end"></span>' + '<span style="display:inline-block; margin-left:10px;" ><select ng:model="ngGridSortPagination.limit" class="ui-pg-selbox">' + '<option value="10" selected="selected">10</option><option value="20">20</option><option value="30">30</option></select></span>' + '</td></tr></tfoot>'; | |
tElement.append(footer); | |
tElement.find('.ui-state-default, .ui-widget-content').css('padding', ' 0.2em 0.4em'); | |
tElement.find('.ui-state-default, .ui-widget-content').css('font-size', '70%'); | |
return function(scope, linkElement) { | |
scope.ngGridSortPagination = {}; | |
var grid = scope.ngGridSortPagination; | |
//PAGINATION | |
var pager = linkElement.children('tfoot').children('tr').children('td'), | |
rhs = expa.match(/^\s*(.+)\s+in\s+(.*)\s*$/)[2], | |
collection = scope.$eval(rhs), | |
count = collection.length; | |
scope.$watch(rhs, function() { | |
count = scope.$eval(rhs).length; | |
grid.lastPage = Math.round(count / grid.limit) + 1; | |
}); | |
grid.limit = 10; | |
grid.lastPage = Math.round(count / grid.limit) + 1; | |
grid.page = 1; | |
grid.skipAt = ((grid.page - 1) * grid.limit); | |
pager.children('.ui-icon-seek-first').bind('click', function() { | |
grid.page = 1; | |
grid.skipAt = 1; | |
angular.element(this).addClass('ui-state-disabled'); | |
pager.children('.ui-icon-seek-prev').addClass('ui-state-disabled'); | |
pager.children('.ui-icon-seek-next, .ui-icon-seek-end').removeClass('ui-state-disabled'); | |
grid.skipAt = ((grid.page - 1) * grid.limit); | |
scope.$digest(); | |
//console.log('fisrt'); | |
}); | |
pager.children('.ui-icon-seek-prev').bind('click', function() { | |
pager.children('.ui-icon-seek-next, .ui-icon-seek-end').removeClass('ui-state-disabled'); | |
if (grid.page > 1) { | |
grid.page -= 1; | |
grid.skipAt = ((grid.page - 1) * grid.limit); | |
scope.$digest(); | |
} | |
if (grid.page === 1) { | |
angular.element(this).addClass('ui-state-disabled'); | |
pager.children('.ui-icon-seek-first').addClass('ui-state-disabled'); | |
} | |
//console.log('prev') | |
}); | |
pager.children('.ui-icon-seek-next').bind('click', function() { | |
pager.children('.ui-icon-seek-first, .ui-icon-seek-prev').removeClass('ui-state-disabled'); | |
if (grid.page < grid.lastPage) { | |
grid.page += 1; | |
grid.skipAt = ((grid.page - 1) * grid.limit); | |
scope.$digest(); | |
} | |
if (grid.page === grid.lastPage) { | |
angular.element(this).addClass('ui-state-disabled'); | |
pager.children('.ui-icon-seek-end').addClass('ui-state-disabled'); | |
} | |
//console.log('next') | |
}); | |
pager.children('.ui-icon-seek-end').bind('click', function() { | |
grid.page = grid.lastPage; | |
pager.children('.ui-icon-seek-prev, .ui-icon-seek-first').removeClass('ui-state-disabled'); | |
angular.element(this).addClass('ui-state-disabled'); | |
pager.children('.ui-icon-seek-next').addClass('ui-state-disabled'); | |
grid.skipAt = ((grid.page - 1) * grid.limit); | |
scope.$digest(); | |
//console.log('end') | |
}); | |
pager.children('span').children('.ui-pg-selbox').bind('change', function(ev) { | |
grid.lastPage = Math.round(count / ev.target.value) + 1; | |
grid.page = 1; | |
grid.skipAt = ((grid.page - 1) * ev.target.value); | |
scope.$digest(); | |
}); | |
//ORDER | |
var listenerOrder = function(ev) { | |
var sort = angular.element(this).children('span'); | |
grid.predicate = angular.element(this).attr('name'); | |
grid.reverse = false; | |
if (!sort.hasClass('ui-icon-triangle-1-n') && !sort.hasClass('ui-icon-triangle-1-s')) { | |
headerRow.children('th').children('span').removeClass('ui-icon ui-icon-triangle-1-n ui-icon-triangle-1-s'); | |
sort.addClass('ui-icon ui-icon-triangle-1-n'); | |
grid.reverse = false; | |
} else { | |
if (sort.hasClass('ui-icon-triangle-1-n')) { | |
grid.reverse = true; | |
} else { | |
grid.reverse = false; | |
} | |
sort.toggleClass('ui-icon-triangle-1-n'); | |
sort.toggleClass('ui-icon-triangle-1-s'); | |
} | |
console.log('orderBy :' + grid.predicate + ' order: ' + grid.reverse); | |
scope.$digest(); | |
}; | |
angular.forEach(linkElement.children('thead').children('tr').children('th'), function(elm) { | |
elm.addEventListener('click', listenerOrder); | |
}); | |
} | |
} | |
}; | |
return direc; | |
}); | |
})(window.angular); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You should change the order of the filters: first should be orderBy, then skip and finally limitTo, because otherwise sorting doesn't work properly. You can see the wrong behaviour in your fiddle here: http://jsfiddle.net/dalcib/J3fjc/ . Just change the sort order to name and navigate through pages: value "asdfasdf" keeps showing through pages 1-4.
Here is my fork of your gist with mentioned problem fixed: https://gist.github.com/3737358