replace misused filter with ng-table

This commit is contained in:
Gwenhael Le Moine 2014-08-09 18:41:31 +02:00
parent dc9a456e1e
commit b5f50b8ca1
30 changed files with 1916 additions and 34 deletions

View file

@ -24,7 +24,6 @@
"commit": "4cc49a7df36e367457d0fdfbd44148848eeb8466"
},
"_source": "git://github.com/chieffancypants/angular-loading-bar.git",
"_target": "~0.5.0",
"_originalSource": "angular-loading-bar",
"_direct": true
"_target": "*",
"_originalSource": "angular-loading-bar"
}

View file

@ -26,7 +26,6 @@
"commit": "99475e0365ea0955071026b9b210f116fe15fdae"
},
"_source": "git://github.com/urish/angular-moment.git",
"_target": "~0.8.0",
"_originalSource": "angular-moment",
"_direct": true
"_target": "*",
"_originalSource": "angular-moment"
}

View file

@ -42,7 +42,6 @@
"commit": "c068162161154a4b85110ea1e7dd3d7897ce2b72"
},
"_source": "git://github.com/twbs/bootstrap.git",
"_target": "~3.2.0",
"_originalSource": "bootstrap",
"_direct": true
"_target": "*",
"_originalSource": "bootstrap"
}

View file

@ -0,0 +1,29 @@
{
"name": "ng-table",
"version": "0.3.3",
"main": [
"ng-table.js",
"ng-table.css"
],
"ignore": [
"examples",
"src"
],
"dependencies": {
"angular": "~1"
},
"devDependencies": {
"angular-mocks": "~1"
},
"homepage": "https://github.com/esvit/ng-table",
"_release": "0.3.3",
"_resolution": {
"type": "version",
"tag": "v0.3.3",
"commit": "bd9ec42172389257fcd312330013302b2696ac2a"
},
"_source": "git://github.com/esvit/ng-table.git",
"_target": "~0.3.3",
"_originalSource": "ng-table",
"_direct": true
}

View file

@ -0,0 +1,4 @@
{
"directory": "bower_components",
"json": "bower.json"
}

View file

@ -0,0 +1,13 @@
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

View file

@ -0,0 +1,5 @@
.temp
.idea
node_modules
bower_components
out

View file

@ -0,0 +1,21 @@
{
"camelcase" : true,
"indent": 4,
"strict": true,
"undef": true,
"unused": true,
"quotmark": "single",
"maxlen": 120,
"trailing": true,
"curly": true,
"devel": true,
"browser":true,
"jquery":true,
"predef": [
"angular",
"define",
"require"
]
}

View file

@ -0,0 +1,19 @@
language: node_js
node_js:
- 0.10
before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
- npm install -g karma
- npm install -g grunt-cli
- npm install -g bower
- npm install
- bower install
- grunt
script:
- karma start --no-auto-watch --single-run --browsers Firefox
after_success:
cat out/coverage/*/lcov.info | ./node_modules/coveralls/bin/coveralls.js

View file

@ -0,0 +1,20 @@
CONTRIBUTING
============
Here's a quick guide:
1. Fork the repo.
2. `npm install`
3. `bower install`
4. Run the tests: `karma start`
5. Make changes in source folder `src`.
6. Minify source files: `grunt`
7. Make the test pass.
8. Push to your fork and submit a pull request.

View file

@ -0,0 +1,138 @@
var mountFolder = function (connect, dir) {
return connect.static(require('path').resolve(dir));
};
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
grunt.registerTask('serve', ['connect:serve', 'watch']);
grunt.registerTask('dev', [
'clean',
'ngTemplateCache',
'concat',
'less',
'copy'
]);
grunt.registerTask('default', [
'dev',
'uglify',
'cssmin'
]);
grunt.initConfig({
cmpnt: grunt.file.readJSON('bower.json'),
banner: '/*! ngTable v<%= cmpnt.version %> by Vitalii Savchuk(esvit666@gmail.com) - ' +
'https://github.com/esvit/ng-table - New BSD License */\n',
clean: {
working: {
src: ['ng-table.*', './.temp/views', './.temp/']
}
},
copy: {
styles: {
files: [
{
src: './src/styles/ng-table.less',
dest: './ng-table.less'
}
]
}
},
uglify: {
js: {
src: ['ng-table.js'],
dest: 'ng-table.min.js',
options: {
banner: '<%= banner %>',
sourceMap: function (fileName) {
return fileName.replace(/\.min\.js$/, '.map');
}
}
}
},
concat: {
js: {
src: [
'src/scripts/01-*.js',
'src/scripts/02-*.js',
'src/scripts/03-*.js',
'src/scripts/04-*.js',
'src/scripts/05-*.js',
'src/scripts/06-*.js',
'./.temp/scripts/views.js',
'src/scripts/07-*.js'
],
dest: 'ng-table.js'
}
},
less: {
css: {
files: {
'ng-table.css': 'src/styles/ng-table.less'
}
}
},
cssmin: {
css: {
files: {
'ng-table.min.css': 'ng-table.css'
},
options: {
banner: '<%= banner %>'
}
}
},
watch: {
css: {
files: 'src/styles/*.less',
tasks: ['less'],
options: {
livereload: true
}
},
js: {
files: 'src/scripts/*.js',
tasks: ['concat'],
options: {
livereload: true
}
},
html: {
files: 'src/ng-table/*.html',
tasks: ['ngTemplateCache', 'concat'],
options: {
livereload: true
}
}
},
connect: {
options: {
port: 8000,
hostname: 'localhost'
},
serve: {
options: {
middleware: function (connect) {
return [
mountFolder(connect, '.')
];
}
}
}
},
ngTemplateCache: {
views: {
files: {
'./.temp/scripts/views.js': 'src/ng-table/**/*.html'
},
options: {
trim: 'src/',
module: 'ngTable'
}
}
}
});
};

View file

@ -0,0 +1,9 @@
Copyright (c) 2013, esvit.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the esvit nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,101 @@
Table + AngularJS
=================
[![Build Status](https://travis-ci.org/esvit/ng-table.png)](https://travis-ci.org/esvit/ng-table) [![Coverage Status](https://coveralls.io/repos/esvit/ng-table/badge.png)](https://coveralls.io/r/esvit/ng-table)
Code licensed under New BSD License.
This directive allow to liven your tables. It support sorting, filtering and pagination.
Header row with titles and filters automatic generated on compilation step.
## Compatibility
For work in IE < 9 need jQuery, just add:
```html
<!--[if lt IE 9]>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<![endif]-->
```
## Plugins
* [Export to CSV](https://github.com/esvit/ng-table-export)
## Updates
### v0.3.2 (master)
- add pagination directive ngTablePagination [(see usage)](https://github.com/esvit/ng-table/blob/master/examples/demo28.html)
- rename filter.name to filter.$$name according to issue #196
- add debugMode setting
- add defaultSort setting
- add filterDelay setting
- add multisorting (click on header with Ctrl-key)
- add css classes (ng-table-pager, ng-table-pagination, ng-table-counts)
### v0.3.1
- add support of `header-class` attribute
- add fixes for compatibility with early versions of AngularJS
- add `data` field to ngTableParams
- Allow expressions in the sortable & filter attribute (Issue #93)
### v0.3.0
- I abandoned from CoffeeScript in favor of a javascript, fully agree with http://blog.ponyfoo.com/2013/09/28/we-dont-want-your-coffee & (rus) http://habrahabr.ru/post/195944/
- added examples of table with grouping
- fully rewrited interface of ngTableParams
### v0.2.2
In functions that return data for the filters were removed `.promise`
```javascript
$scope.names = function(column) {
...
def.resolve(names);
// return def.promise; - old code
return def;
};
```
## Installing via Bower
```
bower install ng-table
```
## Development
We use Karma to ensure the quality of the code. The easiest way to run these checks is to use grunt:
```sh
npm install -g grunt-cli
npm install && bower install
grunt
```
The karma task will try to open Firefox and Chrome as browser in which to run the tests. Make sure this is available or change the configuration in `karma.conf.js`
## Examples (from simple to complex)
* [Pagination](http://bazalt-cms.com/ng-table/example/1)
* [Sorting](http://bazalt-cms.com/ng-table/example/3)
* [Filtering](http://bazalt-cms.com/ng-table/example/4)
* [Cell template](http://bazalt-cms.com/ng-table/example/8)
* [Row template](http://bazalt-cms.com/ng-table/example/9)
* [Params in url](http://bazalt-cms.com/ng-table/example/5)
* [Ajax](http://bazalt-cms.com/ng-table/example/6)
* [Table with hidden pagination](http://bazalt-cms.com/ng-table/example/7)
* [Custom template(pagination)](http://bazalt-cms.com/ng-table/example/2)
* [Custom filters](http://bazalt-cms.com/ng-table/example/11)
* [Table with checkboxes](http://bazalt-cms.com/ng-table/example/10)
* [Table with grouping](http://bazalt-cms.com/ng-table/example/12)
* [Table with grouping with callback](http://bazalt-cms.com/ng-table/example/13)
* [Table with external control of data](http://bazalt-cms.com/ng-table/example/14)
* [Export to CSV](http://bazalt-cms.com/ng-table/example/15)
## Configuring ng-table
For a list of configuration options available, see [Configuring your table with ngTableParams](https://github.com/esvit/ng-table/wiki/Configuring-your-table-with-ngTableParams)
#### PS
Let me know if you are using **ng-table**. It will motivate me to work harder.
And if you like **ng-table**, just email me and add your website [here](http://bazalt-cms.com/ng-table/who-is-using)
Hope you like it, Thanks! :)
---
This project is part of [Bazalt CMS](http://bazalt-cms.com/).

View file

@ -0,0 +1,18 @@
{
"name": "ng-table",
"version": "0.3.2",
"main": [
"ng-table.js",
"ng-table.css"
],
"ignore": [
"examples",
"src"
],
"dependencies": {
"angular": "~1"
},
"devDependencies": {
"angular-mocks": "~1"
}
}

View file

@ -0,0 +1,38 @@
// Karma configuration file
// See http://karma-runner.github.io/0.10/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
// libraries
'bower_components/angular/angular.js',
'bower_components/angular-mocks/angular-mocks.js',
// directive
'ng-table.js',
// tests
'test/*.js'
//'test/tableParamsSpec.js'
//'test/tableControllerSpec.js'
],
// generate js files from html templates
preprocessors: {
'*.js': 'coverage'
},
reporters: ['progress', 'coverage'],
autoWatch: true,
browsers: ['Chrome'],
coverageReporter: {
type: 'lcov',
dir: 'out/coverage'
}
});
};

View file

@ -0,0 +1,136 @@
.ng-table th {
text-align: center;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.ng-table th.sortable {
cursor: pointer;
}
.ng-table th.sortable div {
padding-right: 18px;
position: relative;
}
.ng-table th.sortable div:after,
.ng-table th.sortable div:before {
content: "";
border-width: 0 4px 4px;
border-style: solid;
border-color: #000 transparent;
visibility: visible;
right: 8px;
top: 50%;
position: absolute;
opacity: .3;
margin-top: -4px;
}
.ng-table th.sortable div:before {
margin-top: 2px;
border-bottom: none;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px solid #000;
}
.ng-table th.sortable div:hover:after,
.ng-table th.sortable div:hover:before {
opacity: 1;
visibility: visible;
}
.ng-table th.sortable.sort-desc,
.ng-table th.sortable.sort-asc {
background-color: rgba(141, 192, 219, 0.25);
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
}
.ng-table th.sortable.sort-desc div:after,
.ng-table th.sortable.sort-asc div:after {
margin-top: -2px;
}
.ng-table th.sortable.sort-desc div:before,
.ng-table th.sortable.sort-asc div:before {
visibility: hidden;
}
.ng-table th.sortable.sort-asc div:after,
.ng-table th.sortable.sort-asc div:hover:after {
visibility: visible;
filter: alpha(opacity=60);
-khtml-opacity: 0.6;
-moz-opacity: 0.6;
opacity: 0.6;
}
.ng-table th.sortable.sort-desc div:after {
border-bottom: none;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px solid #000;
visibility: visible;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
filter: alpha(opacity=60);
-khtml-opacity: 0.6;
-moz-opacity: 0.6;
opacity: 0.6;
}
.ng-table th.filter .input-filter {
margin: 0;
display: block;
width: 100%;
min-height: 30px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.ng-table + .pagination {
margin-top: 0;
}
@media only screen and (max-width: 800px) {
.ng-table-responsive {
border-bottom: 1px solid #999999;
}
.ng-table-responsive tr {
border-top: 1px solid #999999;
border-left: 1px solid #999999;
border-right: 1px solid #999999;
}
.ng-table-responsive td:before {
position: absolute;
padding: 8px;
left: 0;
top: 0;
width: 50%;
white-space: nowrap;
text-align: left;
font-weight: bold;
}
.ng-table-responsive thead tr th {
text-align: left;
}
.ng-table-responsive thead tr.ng-table-filters th {
padding: 0;
}
.ng-table-responsive thead tr.ng-table-filters th form > div {
padding: 8px;
}
.ng-table-responsive td {
border: none;
border-bottom: 1px solid #eeeeee;
position: relative;
padding-left: 50%;
white-space: normal;
text-align: left;
}
.ng-table-responsive td:before {
content: attr(data-title-text);
}
.ng-table-responsive,
.ng-table-responsive thead,
.ng-table-responsive tbody,
.ng-table-responsive th,
.ng-table-responsive td,
.ng-table-responsive tr {
display: block;
}
}

View file

@ -0,0 +1,718 @@
(function(angular, factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
define(['angular'], function(angular) {
return factory(angular);
});
} else {
return factory(angular);
}
}(angular || null, function(angular) {
'use strict';
/**
* ngTable: Table + Angular JS
*
* @author Vitalii Savchuk <esvit666@gmail.com>
* @url https://github.com/esvit/ng-table/
* @license New BSD License <http://creativecommons.org/licenses/BSD/>
*/
/**
* @ngdoc module
* @name ngTable
* @description ngTable: Table + Angular JS
* @example
<doc:example>
<doc:source>
<script>
var app = angular.module('myApp', ['ngTable']);
app.controller('MyCtrl', function($scope) {
$scope.users = [
{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}
];
});
</script>
<table ng-table class="table">
<tr ng-repeat="user in users">
<td data-title="'Name'">{{user.name}}</td>
<td data-title="'Age'">{{user.age}}</td>
</tr>
</table>
</doc:source>
</doc:example>
*/
var app = angular.module('ngTable', []);
/**
* ngTable: Table + Angular JS
*
* @author Vitalii Savchuk <esvit666@gmail.com>
* @url https://github.com/esvit/ng-table/
* @license New BSD License <http://creativecommons.org/licenses/BSD/>
*/
/**
* @ngdoc service
* @name ngTable.factory:ngTableParams
* @description Parameters manager for ngTable
*/
app.factory('ngTableParams', ['$q', '$log', function ($q, $log) {
var isNumber = function (n) {
return !isNaN(parseFloat(n)) && isFinite(n);
};
var ngTableParams = function (baseParameters, baseSettings) {
var self = this,
log = function () {
if (settings.debugMode && $log.debug) {
$log.debug.apply(this, arguments);
}
};
this.data = [];
/**
* @ngdoc method
* @name ngTable.factory:ngTableParams#parameters
* @methodOf ngTable.factory:ngTableParams
* @description Set new parameters or get current parameters
*
* @param {string} newParameters New parameters
* @param {string} parseParamsFromUrl Flag if parse parameters like in url
* @returns {Object} Current parameters or `this`
*/
this.parameters = function (newParameters, parseParamsFromUrl) {
parseParamsFromUrl = parseParamsFromUrl || false;
if (angular.isDefined(newParameters)) {
for (var key in newParameters) {
var value = newParameters[key];
if (parseParamsFromUrl && key.indexOf('[') >= 0) {
var keys = key.split(/\[(.*)\]/).reverse()
var lastKey = '';
for (var i = 0, len = keys.length; i < len; i++) {
var name = keys[i];
if (name !== '') {
var v = value;
value = {};
value[lastKey = name] = (isNumber(v) ? parseFloat(v) : v);
}
}
if (lastKey === 'sorting') {
params[lastKey] = {};
}
params[lastKey] = angular.extend(params[lastKey] || {}, value[lastKey]);
} else {
params[key] = (isNumber(newParameters[key]) ? parseFloat(newParameters[key]) : newParameters[key]);
}
}
log('ngTable: set parameters', params);
return this;
}
return params;
};
/**
* @ngdoc method
* @name ngTable.factory:ngTableParams#settings
* @methodOf ngTable.factory:ngTableParams
* @description Set new settings for table
*
* @param {string} newSettings New settings or undefined
* @returns {Object} Current settings or `this`
*/
this.settings = function (newSettings) {
if (angular.isDefined(newSettings)) {
if (angular.isArray(newSettings.data)) {
//auto-set the total from passed in data
newSettings.total = newSettings.data.length;
}
settings = angular.extend(settings, newSettings);
log('ngTable: set settings', settings);
return this;
}
return settings;
};
/**
* @ngdoc method
* @name ngTable.factory:ngTableParams#page
* @methodOf ngTable.factory:ngTableParams
* @description If parameter page not set return current page else set current page
*
* @param {string} page Page number
* @returns {Object|Number} Current page or `this`
*/
this.page = function (page) {
return angular.isDefined(page) ? this.parameters({'page': page}) : params.page;
};
/**
* @ngdoc method
* @name ngTable.factory:ngTableParams#total
* @methodOf ngTable.factory:ngTableParams
* @description If parameter total not set return current quantity else set quantity
*
* @param {string} total Total quantity of items
* @returns {Object|Number} Current page or `this`
*/
this.total = function (total) {
return angular.isDefined(total) ? this.settings({'total': total}) : settings.total;
};
/**
* @ngdoc method
* @name ngTable.factory:ngTableParams#count
* @methodOf ngTable.factory:ngTableParams
* @description If parameter count not set return current count per page else set count per page
*
* @param {string} count Count per number
* @returns {Object|Number} Count per page or `this`
*/
this.count = function (count) {
// reset to first page because can be blank page
return angular.isDefined(count) ? this.parameters({'count': count, 'page': 1}) : params.count;
};
/**
* @ngdoc method
* @name ngTable.factory:ngTableParams#filter
* @methodOf ngTable.factory:ngTableParams
* @description If parameter page not set return current filter else set current filter
*
* @param {string} filter New filter
* @returns {Object} Current filter or `this`
*/
this.filter = function (filter) {
return angular.isDefined(filter) ? this.parameters({'filter': filter}) : params.filter;
};
/**
* @ngdoc method
* @name ngTable.factory:ngTableParams#sorting
* @methodOf ngTable.factory:ngTableParams
* @description If 'sorting' parameter is not set, return current sorting. Otherwise set current sorting.
*
* @param {string} sorting New sorting
* @returns {Object} Current sorting or `this`
*/
this.sorting = function (sorting) {
if (arguments.length == 2) {
var sortArray = {};
sortArray[sorting] = arguments[1];
this.parameters({'sorting': sortArray});
return this;
}
return angular.isDefined(sorting) ? this.parameters({'sorting': sorting}) : params.sorting;
};
/**
* @ngdoc method
* @name ngTable.factory:ngTableParams#isSortBy
* @methodOf ngTable.factory:ngTableParams
* @description Checks sort field
*
* @param {string} field Field name
* @param {string} direction Direction of sorting 'asc' or 'desc'
* @returns {Array} Return true if field sorted by direction
*/
this.isSortBy = function (field, direction) {
return angular.isDefined(params.sorting[field]) && params.sorting[field] == direction;
};
/**
* @ngdoc method
* @name ngTable.factory:ngTableParams#orderBy
* @methodOf ngTable.factory:ngTableParams
* @description Return object of sorting parameters for angular filter
*
* @returns {Array} Array like: [ '-name', '+age' ]
*/
this.orderBy = function () {
var sorting = [];
for (var column in params.sorting) {
sorting.push((params.sorting[column] === "asc" ? "+" : "-") + column);
}
return sorting;
};
/**
* @ngdoc method
* @name ngTable.factory:ngTableParams#getData
* @methodOf ngTable.factory:ngTableParams
* @description Called when updated some of parameters for get new data
*
* @param {Object} $defer promise object
* @param {Object} params New parameters
*/
this.getData = function ($defer, params) {
if (angular.isArray(this.data) && angular.isObject(params)) {
$defer.resolve(this.data.slice((params.page() - 1) * params.count(), params.page() * params.count()));
} else {
$defer.resolve([]);
}
};
/**
* @ngdoc method
* @name ngTable.factory:ngTableParams#getGroups
* @methodOf ngTable.factory:ngTableParams
* @description Return groups for table grouping
*/
this.getGroups = function ($defer, column) {
var defer = $q.defer();
defer.promise.then(function (data) {
var groups = {};
angular.forEach(data, function (item) {
var groupName = angular.isFunction(column) ? column(item) : item[column];
groups[groupName] = groups[groupName] || {
data: []
};
groups[groupName]['value'] = groupName;
groups[groupName].data.push(item);
});
var result = [];
for (var i in groups) {
result.push(groups[i]);
}
log('ngTable: refresh groups', result);
$defer.resolve(result);
});
this.getData(defer, self);
};
/**
* @ngdoc method
* @name ngTable.factory:ngTableParams#generatePagesArray
* @methodOf ngTable.factory:ngTableParams
* @description Generate array of pages
*
* @param {boolean} currentPage which page must be active
* @param {boolean} totalItems Total quantity of items
* @param {boolean} pageSize Quantity of items on page
* @returns {Array} Array of pages
*/
this.generatePagesArray = function (currentPage, totalItems, pageSize) {
var maxBlocks, maxPage, maxPivotPages, minPage, numPages, pages;
maxBlocks = 11;
pages = [];
numPages = Math.ceil(totalItems / pageSize);
if (numPages > 1) {
pages.push({
type: 'prev',
number: Math.max(1, currentPage - 1),
active: currentPage > 1
});
pages.push({
type: 'first',
number: 1,
active: currentPage > 1
});
maxPivotPages = Math.round((maxBlocks - 5) / 2);
minPage = Math.max(2, currentPage - maxPivotPages);
maxPage = Math.min(numPages - 1, currentPage + maxPivotPages * 2 - (currentPage - minPage));
minPage = Math.max(2, minPage - (maxPivotPages * 2 - (maxPage - minPage)));
var i = minPage;
while (i <= maxPage) {
if ((i === minPage && i !== 2) || (i === maxPage && i !== numPages - 1)) {
pages.push({
type: 'more',
active: false
});
} else {
pages.push({
type: 'page',
number: i,
active: currentPage !== i
});
}
i++;
}
pages.push({
type: 'last',
number: numPages,
active: currentPage !== numPages
});
pages.push({
type: 'next',
number: Math.min(numPages, currentPage + 1),
active: currentPage < numPages
});
}
return pages;
};
/**
* @ngdoc method
* @name ngTable.factory:ngTableParams#url
* @methodOf ngTable.factory:ngTableParams
* @description Return groups for table grouping
*
* @param {boolean} asString flag indicates return array of string or object
* @returns {Array} If asString = true will be return array of url string parameters else key-value object
*/
this.url = function (asString) {
asString = asString || false;
var pairs = (asString ? [] : {});
for (var key in params) {
if (params.hasOwnProperty(key)) {
var item = params[key],
name = encodeURIComponent(key);
if (typeof item === "object") {
for (var subkey in item) {
if (!angular.isUndefined(item[subkey]) && item[subkey] !== "") {
var pname = name + "[" + encodeURIComponent(subkey) + "]";
if (asString) {
pairs.push(pname + "=" + item[subkey]);
} else {
pairs[pname] = item[subkey];
}
}
}
} else if (!angular.isFunction(item) && !angular.isUndefined(item) && item !== "") {
if (asString) {
pairs.push(name + "=" + encodeURIComponent(item));
} else {
pairs[name] = encodeURIComponent(item);
}
}
}
}
return pairs;
};
/**
* @ngdoc method
* @name ngTable.factory:ngTableParams#reload
* @methodOf ngTable.factory:ngTableParams
* @description Reload table data
*/
this.reload = function () {
var $defer = $q.defer(),
self = this;
settings.$loading = true;
if (settings.groupBy) {
settings.getGroups($defer, settings.groupBy, this);
} else {
settings.getData($defer, this);
}
log('ngTable: reload data');
$defer.promise.then(function (data) {
settings.$loading = false;
log('ngTable: current scope', settings.$scope);
if (settings.groupBy) {
self.data = settings.$scope.$groups = data;
} else {
self.data = settings.$scope.$data = data;
}
settings.$scope.pages = self.generatePagesArray(self.page(), self.total(), self.count());
settings.$scope.$emit('ngTableAfterReloadData');
});
};
this.reloadPages = function () {
var self = this;
settings.$scope.pages = self.generatePagesArray(self.page(), self.total(), self.count());
};
var params = this.$params = {
page: 1,
count: 1,
filter: {},
sorting: {},
group: {},
groupBy: null
};
var settings = {
$scope: null, // set by ngTable controller
$loading: false,
data: null, //allows data to be set when table is initialized
total: 0,
defaultSort: 'desc',
filterDelay: 750,
counts: [10, 25, 50, 100],
getGroups: this.getGroups,
getData: this.getData
};
this.settings(baseSettings);
this.parameters(baseParameters, true);
return this;
};
return ngTableParams;
}]);
/**
* ngTable: Table + Angular JS
*
* @author Vitalii Savchuk <esvit666@gmail.com>
* @url https://github.com/esvit/ng-table/
* @license New BSD License <http://creativecommons.org/licenses/BSD/>
*/
/**
* @ngdoc object
* @name ngTable.directive:ngTable.ngTableController
*
* @description
* Each {@link ngTable.directive:ngTable ngTable} directive creates an instance of `ngTableController`
*/
var ngTableController = ['$scope', 'ngTableParams', '$timeout', function ($scope, ngTableParams, $timeout) {
$scope.$loading = false;
if (!$scope.params) {
$scope.params = new ngTableParams();
}
$scope.params.settings().$scope = $scope;
var delayFilter = (function () {
var timer = 0;
return function (callback, ms) {
$timeout.cancel(timer);
timer = $timeout(callback, ms);
};
})();
$scope.$watch('params.$params', function (newParams, oldParams) {
$scope.params.settings().$scope = $scope;
if (!angular.equals(newParams.filter, oldParams.filter)) {
delayFilter(function () {
$scope.params.$params.page = 1;
$scope.params.reload();
}, $scope.params.settings().filterDelay);
} else {
$scope.params.reload();
}
}, true);
$scope.sortBy = function (column, event) {
var parsedSortable = $scope.parse(column.sortable);
if (!parsedSortable) {
return;
}
var defaultSort = $scope.params.settings().defaultSort;
var inverseSort = (defaultSort === 'asc' ? 'desc' : 'asc');
var sorting = $scope.params.sorting() && $scope.params.sorting()[parsedSortable] && ($scope.params.sorting()[parsedSortable] === defaultSort);
var sortingParams = (event.ctrlKey || event.metaKey) ? $scope.params.sorting() : {};
sortingParams[parsedSortable] = (sorting ? inverseSort : defaultSort);
$scope.params.parameters({
sorting: sortingParams
});
};
}];
/**
* ngTable: Table + Angular JS
*
* @author Vitalii Savchuk <esvit666@gmail.com>
* @url https://github.com/esvit/ng-table/
* @license New BSD License <http://creativecommons.org/licenses/BSD/>
*/
/**
* @ngdoc directive
* @name ngTable.directive:ngTable
* @restrict A
*
* @description
* Directive that instantiates {@link ngTable.directive:ngTable.ngTableController ngTableController}.
*/
app.directive('ngTable', ['$compile', '$q', '$parse',
function ($compile, $q, $parse) {
'use strict';
return {
restrict: 'A',
priority: 1001,
scope: true,
controller: ngTableController,
compile: function (element) {
var columns = [], i = 0, row = null;
// custom header
var thead = element.find('thead');
// IE 8 fix :not(.ng-table-group) selector
angular.forEach(angular.element(element.find('tr')), function (tr) {
tr = angular.element(tr);
if (!tr.hasClass('ng-table-group') && !row) {
row = tr;
}
});
if (!row) {
return;
}
angular.forEach(row.find('td'), function (item) {
var el = angular.element(item);
if (el.attr('ignore-cell') && 'true' === el.attr('ignore-cell')) {
return;
}
var parsedAttribute = function (attr, defaultValue) {
return function (scope) {
return $parse(el.attr('x-data-' + attr) || el.attr('data-' + attr) || el.attr(attr))(scope, {
$columns: columns
}) || defaultValue;
};
};
var parsedTitle = parsedAttribute('title', ' '),
headerTemplateURL = parsedAttribute('header', false),
filter = parsedAttribute('filter', false)(),
filterTemplateURL = false,
filterName = false;
if (filter && filter.$$name) {
filterName = filter.$$name;
delete filter.$$name;
}
if (filter && filter.templateURL) {
filterTemplateURL = filter.templateURL;
delete filter.templateURL;
}
el.attr('data-title-text', parsedTitle()); // this used in responsive table
columns.push({
id: i++,
title: parsedTitle,
sortable: parsedAttribute('sortable', false),
'class': el.attr('x-data-header-class') || el.attr('data-header-class') || el.attr('header-class'),
filter: filter,
filterTemplateURL: filterTemplateURL,
filterName: filterName,
headerTemplateURL: headerTemplateURL,
filterData: (el.attr("filter-data") ? el.attr("filter-data") : null),
show: (el.attr("ng-show") ? function (scope) {
return $parse(el.attr("ng-show"))(scope);
} : function () {
return true;
})
});
});
return function (scope, element, attrs) {
scope.$loading = false;
scope.$columns = columns;
scope.$watch(attrs.ngTable, (function (params) {
if (angular.isUndefined(params)) {
return;
}
scope.paramsModel = $parse(attrs.ngTable);
scope.params = params;
}), true);
scope.parse = function (text) {
return angular.isDefined(text) ? text(scope) : '';
};
if (attrs.showFilter) {
scope.$parent.$watch(attrs.showFilter, function (value) {
scope.show_filter = value;
});
}
angular.forEach(columns, function (column) {
var def;
if (!column.filterData) {
return;
}
def = $parse(column.filterData)(scope, {
$column: column
});
if (!(angular.isObject(def) && angular.isObject(def.promise))) {
throw new Error('Function ' + column.filterData + ' must be instance of $q.defer()');
}
delete column.filterData;
return def.promise.then(function (data) {
if (!angular.isArray(data)) {
data = [];
}
data.unshift({
title: '-',
id: ''
});
column.data = data;
});
});
if (!element.hasClass('ng-table')) {
scope.templates = {
header: (attrs.templateHeader ? attrs.templateHeader : 'ng-table/header.html'),
pagination: (attrs.templatePagination ? attrs.templatePagination : 'ng-table/pager.html')
};
var headerTemplate = thead.length > 0 ? thead : angular.element(document.createElement('thead')).attr('ng-include', 'templates.header');
var paginationTemplate = angular.element(document.createElement('div')).attr({
'ng-table-pagination': 'params',
'template-url': 'templates.pagination'
});
element.find('thead').remove();
element.addClass('ng-table')
.prepend(headerTemplate)
.after(paginationTemplate);
$compile(headerTemplate)(scope);
$compile(paginationTemplate)(scope);
}
};
}
}
}
]);
/**
* ngTable: Table + Angular JS
*
* @author Vitalii Savchuk <esvit666@gmail.com>
* @url https://github.com/esvit/ng-table/
* @license New BSD License <http://creativecommons.org/licenses/BSD/>
*/
/**
* @ngdoc directive
* @name ngTable.directive:ngTablePagination
* @restrict A
*/
app.directive('ngTablePagination', ['$compile',
function ($compile) {
'use strict';
return {
restrict: 'A',
scope: {
'params': '=ngTablePagination',
'templateUrl': '='
},
replace: false,
link: function (scope, element, attrs) {
scope.params.settings().$scope.$on('ngTableAfterReloadData', function () {
scope.pages = scope.params.generatePagesArray(scope.params.page(), scope.params.total(), scope.params.count());
}, true);
scope.$watch('templateUrl', function(templateUrl) {
if (angular.isUndefined(templateUrl)) {
return;
}
var template = angular.element(document.createElement('div'))
template.attr({
'ng-include': 'templateUrl'
});
element.append(template);
$compile(template)(scope);
});
}
};
}
]);
angular.module('ngTable').run(['$templateCache', function ($templateCache) {
$templateCache.put('ng-table/filters/select-multiple.html', '<select ng-options="data.id as data.title for data in column.data" multiple ng-multiple="true" ng-model="params.filter()[name]" ng-show="filter==\'select-multiple\'" class="filter filter-select-multiple form-control" name="{{column.filterName}}"> </select>');
$templateCache.put('ng-table/filters/select.html', '<select ng-options="data.id as data.title for data in column.data" ng-model="params.filter()[name]" ng-show="filter==\'select\'" class="filter filter-select form-control" name="{{column.filterName}}"> </select>');
$templateCache.put('ng-table/filters/text.html', '<input type="text" name="{{column.filterName}}" ng-model="params.filter()[name]" ng-if="filter==\'text\'" class="input-filter form-control"/>');
$templateCache.put('ng-table/header.html', '<tr> <th ng-repeat="column in $columns" ng-class="{ \'sortable\': parse(column.sortable), \'sort-asc\': params.sorting()[parse(column.sortable)]==\'asc\', \'sort-desc\': params.sorting()[parse(column.sortable)]==\'desc\' }" ng-click="sortBy(column, $event)" ng-show="column.show(this)" ng-init="template=column.headerTemplateURL(this)" class="header {{column.class}}"> <div ng-if="!template" ng-show="!template" ng-bind="parse(column.title)"></div> <div ng-if="template" ng-show="template"><div ng-include="template"></div></div> </th> </tr> <tr ng-show="show_filter" class="ng-table-filters"> <th ng-repeat="column in $columns" ng-show="column.show(this)" class="filter"> <div ng-repeat="(name, filter) in column.filter"> <div ng-if="column.filterTemplateURL" ng-show="column.filterTemplateURL"> <div ng-include="column.filterTemplateURL"></div> </div> <div ng-if="!column.filterTemplateURL" ng-show="!column.filterTemplateURL"> <div ng-include="\'ng-table/filters/\' + filter + \'.html\'"></div> </div> </div> </th> </tr>');
$templateCache.put('ng-table/pager.html', '<div class="ng-cloak ng-table-pager"> <div ng-if="params.settings().counts.length" class="ng-table-counts btn-group pull-right"> <button ng-repeat="count in params.settings().counts" type="button" ng-class="{\'active\':params.count()==count}" ng-click="params.count(count)" class="btn btn-default"> <span ng-bind="count"></span> </button> </div> <ul class="pagination ng-table-pagination"> <li ng-class="{\'disabled\': !page.active}" ng-repeat="page in pages" ng-switch="page.type"> <a ng-switch-when="prev" ng-click="params.page(page.number)" href="">&laquo;</a> <a ng-switch-when="first" ng-click="params.page(page.number)" href=""><span ng-bind="page.number"></span></a> <a ng-switch-when="page" ng-click="params.page(page.number)" href=""><span ng-bind="page.number"></span></a> <a ng-switch-when="more" ng-click="params.page(page.number)" href="">&#8230;</a> <a ng-switch-when="last" ng-click="params.page(page.number)" href=""><span ng-bind="page.number"></span></a> <a ng-switch-when="next" ng-click="params.page(page.number)" href="">&raquo;</a> </li> </ul> </div> ');
}]);
return app;
}));

View file

@ -0,0 +1,151 @@
@table-border-color: #999;
@cell-border-color: #eee;
.ng-table {
th {
text-align: center;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
&.sortable {
cursor: pointer;
div {
padding-right: 18px;
position: relative;
&:after, &:before {
content: "";
border-width: 0 4px 4px;
border-style: solid;
border-color: #000 transparent;
visibility: visible;
right: 8px;
top: 50%;
position: absolute;
opacity: .3;
margin-top: -4px;
}
&:before {
margin-top: 2px;
border-bottom: none;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px solid #000;
}
}
div:hover:after, div:hover:before {
opacity: 1;
visibility: visible;
}
&.sort-desc, &.sort-asc {
background-color: rgba(141, 192, 219, 0.25);
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
div:after {
margin-top: -2px;
}
div:before {
visibility: hidden;
}
}
&.sort-asc div:after, &.sort-asc div:hover:after {
visibility: visible;
filter: alpha(opacity=60);
-khtml-opacity: 0.6;
-moz-opacity: 0.6;
opacity: 0.6;
}
&.sort-desc div:after {
border-bottom: none;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px solid #000;
visibility: visible;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
filter: alpha(opacity=60);
-khtml-opacity: 0.6;
-moz-opacity: 0.6;
opacity: 0.6;
}
}
&.filter {
.input-filter {
margin: 0;
display: block;
width: 100%;
min-height: 30px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
}
}
& + .pagination {
margin-top: 0;
}
}
@media only screen and (max-width: 800px) {
.ng-table-responsive {
border-bottom: 1px solid @table-border-color;
tr {
border-top: 1px solid @table-border-color;
border-left: 1px solid @table-border-color;
border-right: 1px solid @table-border-color;
}
td:before {
position: absolute;
padding: 8px;
left: 0;
top: 0;
width: 50%;
white-space: nowrap;
text-align: left;
font-weight: bold;
}
thead {
tr {
th {
text-align: left;
}
&.ng-table-filters {
th {
padding: 0;
form > div {
padding: 8px;
}
}
}
}
}
td {
border: none;
border-bottom: 1px solid @cell-border-color;
position: relative;
padding-left: 50%;
white-space: normal;
text-align: left;
&:before {
content: attr(data-title-text);
}
}
&, thead, tbody, th, td, tr {
display: block;
}
}
.ng-table-pager {}
.ng-table-pagination {}
.ng-table-counts {}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,3 @@
/*! ngTable v0.3.2 by Vitalii Savchuk(esvit666@gmail.com) - https://github.com/esvit/ng-table - New BSD License */
.ng-table th{text-align:center;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ng-table th.sortable{cursor:pointer}.ng-table th.sortable div{padding-right:18px;position:relative}.ng-table th.sortable div:after,.ng-table th.sortable div:before{content:"";border-width:0 4px 4px;border-style:solid;border-color:#000 transparent;visibility:visible;right:8px;top:50%;position:absolute;opacity:.3;margin-top:-4px}.ng-table th.sortable div:before{margin-top:2px;border-bottom:0;border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid #000}.ng-table th.sortable div:hover:after,.ng-table th.sortable div:hover:before{opacity:1;visibility:visible}.ng-table th.sortable.sort-desc,.ng-table th.sortable.sort-asc{background-color:rgba(141,192,219,.25);text-shadow:0 1px 1px rgba(255,255,255,.75)}.ng-table th.sortable.sort-desc div:after,.ng-table th.sortable.sort-asc div:after{margin-top:-2px}.ng-table th.sortable.sort-desc div:before,.ng-table th.sortable.sort-asc div:before{visibility:hidden}.ng-table th.sortable.sort-asc div:after,.ng-table th.sortable.sort-asc div:hover:after{visibility:visible;filter:alpha(opacity=60);-khtml-opacity:.6;-moz-opacity:.6;opacity:.6}.ng-table th.sortable.sort-desc div:after{border-bottom:0;border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid #000;visibility:visible;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:alpha(opacity=60);-khtml-opacity:.6;-moz-opacity:.6;opacity:.6}.ng-table th.filter .input-filter{margin:0;display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.ng-table+.pagination{margin-top:0}@media only screen and (max-width:800px){.ng-table-responsive{border-bottom:1px solid #999}.ng-table-responsive tr{border-top:1px solid #999;border-left:1px solid #999;border-right:1px solid #999}.ng-table-responsive td:before{position:absolute;padding:8px;left:0;top:0;width:50%;white-space:nowrap;text-align:left;font-weight:700}.ng-table-responsive thead tr th{text-align:left}.ng-table-responsive thead tr.ng-table-filters th{padding:0}.ng-table-responsive thead tr.ng-table-filters th form>div{padding:8px}.ng-table-responsive td{border:0;border-bottom:1px solid #eee;position:relative;padding-left:50%;white-space:normal;text-align:left}.ng-table-responsive td:before{content:attr(data-title-text)}.ng-table-responsive,.ng-table-responsive thead,.ng-table-responsive tbody,.ng-table-responsive th,.ng-table-responsive td,.ng-table-responsive tr{display:block}}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,39 @@
{
"name": "ng-table",
"version": "0.3.1",
"author": "Vitalii Savchuk <esvit666@gmail.com>",
"license": "BSD",
"repository": {
"type": "git",
"url": "git://github.com/esvit/ng-table.git"
},
"devDependencies": {
"coffee-script": "~1.6.2",
"grunt-regarde": "~0.1.1",
"grunt-contrib-jade": "~0.5.0",
"grunt-hustler": "0.11.2",
"grunt-contrib-copy": "~0.4.1",
"grunt-contrib-coffee": "~0.7.0",
"grunt-contrib-clean": "~0.4.0",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-requirejs": "~0.4.0",
"grunt-contrib-uglify": "~0.2.1",
"grunt-contrib-connect": "~0.5.0",
"grunt": "~0.4.2",
"grunt-contrib-less": "~0.5.2",
"grunt-contrib-cssmin": "~0.6.1",
"load-grunt-tasks": "~0.2.0",
"grunt-contrib-watch": "~0.5.3",
"karma": "~0.10",
"karma-jasmine": "*",
"karma-chrome-launcher": "*",
"karma-firefox-launcher": "*",
"karma-ng-html2js-preprocessor": "*",
"coveralls": "",
"karma-coverage": "~0.1.0",
"grunt-coffee-build": "~1.4.12"
},
"scripts": {
"test": "karma start --single-run --no-auto-watch"
}
}

View file

@ -0,0 +1,35 @@
describe('ngTableParams', function () {
var scope, ctrl, params, data = [
{name: "Moroni", age: 50, role: 'Administrator'},
{name: "Tiancum", age: 43, role: 'Administrator'},
{name: "Jacob", age: 27, role: 'Administrator'},
{name: "Nephi", age: 29, role: 'Moderator'},
{name: "Enos", age: 34, role: 'User'},
{name: "Tiancum", age: 43, role: 'User'},
{name: "Jacob", age: 27, role: 'User'},
{name: "Nephi", age: 29, role: 'Moderator'},
{name: "Enos", age: 34, role: 'User'},
{name: "Tiancum", age: 43, role: 'Moderator'},
{name: "Jacob", age: 27, role: 'User'},
{name: "Nephi", age: 29, role: 'User'},
{name: "Enos", age: 34, role: 'Moderator'},
{name: "Tiancum", age: 43, role: 'User'},
{name: "Jacob", age: 27, role: 'User'},
{name: "Nephi", age: 29, role: 'User'},
{name: "Enos", age: 34, role: 'User'}
];
beforeEach(module('ngTable'));
/*beforeEach(inject(function ($controller, $rootScope, ngTableParams) {
scope = $rootScope.$new();
params = scope.params = new ngTableParams();
ctrl = $controller(ngTableController, {
$scope: scope
});
}));
it('ngTableController should have parameters', inject(function (ngTableParams) {
var params = new ngTableParams();
expect(ngTableParams).toBeDefined();
}));*/
});

View file

@ -0,0 +1,273 @@
describe('ngTableParams', function () {
var scope, ctrl, data = [
{name: "Moroni", age: 50, role: 'Administrator'},
{name: "Tiancum", age: 43, role: 'Administrator'},
{name: "Jacob", age: 27, role: 'Administrator'},
{name: "Nephi", age: 29, role: 'Moderator'},
{name: "Enos", age: 34, role: 'User'},
{name: "Tiancum", age: 43, role: 'User'},
{name: "Jacob", age: 27, role: 'User'},
{name: "Nephi", age: 29, role: 'Moderator'},
{name: "Enos", age: 34, role: 'User'},
{name: "Tiancum", age: 43, role: 'Moderator'},
{name: "Jacob", age: 27, role: 'User'},
{name: "Nephi", age: 29, role: 'User'},
{name: "Enos", age: 34, role: 'Moderator'},
{name: "Tiancum", age: 43, role: 'User'},
{name: "Jacob", age: 27, role: 'User'},
{name: "Nephi", age: 29, role: 'User'},
{name: "Enos", age: 34, role: 'User'}
];
beforeEach(module('ngTable'));
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
}));
it('ngTableParams should be defined', inject(function (ngTableParams) {
var params = new ngTableParams();
expect(ngTableParams).toBeDefined();
}));
it('ngTableParams test generatePagesArray', inject(function (ngTableParams) {
var params = new ngTableParams();
expect(params.generatePagesArray(1, 30, 10)).toEqual([
{ type: 'prev', number: 1, active: false },
{ type: 'first', number: 1, active: false },
{ type: 'page', number: 2, active: true },
{ type: 'last', number: 3, active: true },
{ type: 'next', number: 2, active: true }
]);
expect(params.generatePagesArray(2, 30, 10)).toEqual([
{ type: 'prev', number: 1, active: true },
{ type: 'first', number: 1, active: true },
{ type: 'page', number: 2, active: false },
{ type: 'last', number: 3, active: true },
{ type: 'next', number: 3, active: true }
]);
expect(params.generatePagesArray(2, 100, 10)).toEqual([
{ type: 'prev', number: 1, active: true },
{ type: 'first', number: 1, active: true },
{ type: 'page', number: 2, active: false },
{ type: 'page', number: 3, active: true },
{ type: 'page', number: 4, active: true },
{ type: 'page', number: 5, active: true },
{ type: 'page', number: 6, active: true },
{ type: 'page', number: 7, active: true },
{ type: 'more', active: false },
{ type: 'last', number: 10, active: true },
{ type: 'next', number: 3, active: true }
]);
}));
it('ngTableParams `page` parameter', inject(function (ngTableParams) {
var params = new ngTableParams();
expect(params.page()).toBe(1);
expect(params.page(2)).toEqual(params);
expect(params.page()).toBe(2);
params = new ngTableParams({
page: 3
});
expect(params.page()).toBe(3);
var callCount = 0;
scope.tableParams = params;
scope.$watch('tableParams', function (innerParams) {
callCount++;
expect(innerParams.page()).toBe(4);
});
params.page(4);
scope.$apply();
expect(callCount).toBe(1);
// repeat call
scope.$apply();
expect(callCount).toBe(1);
}));
it('ngTableParams parse url parameters', inject(function (ngTableParams) {
var params = new ngTableParams({
'sorting[name]': 'asc',
'sorting[age]': 'desc',
'filter[name]': 'test',
'filter[age]': 20
});
expect(params.filter()).toEqual({ 'name': 'test', 'age': 20 });
expect(params.filter({})).toEqual(params);
expect(params.sorting()).toEqual({ 'age': 'desc' }); // sorting only by one column
expect(params.sorting({})).toEqual(params);
}));
it('ngTableParams return url parameters', inject(function (ngTableParams) {
var params = new ngTableParams({
'sorting[name]': 'asc',
'sorting[age]': 'desc',
'filter[name]': 'test',
'filter[age]': 20
});
expect(params.url()).toEqual({
'page': '1',
'count': '1',
'filter[name]': 'test',
'filter[age]': 20,
'sorting[age]': 'desc'
});
expect(params.url(true)).toEqual([
'page=1',
'count=1',
'filter[name]=test',
'filter[age]=20',
'sorting[age]=desc'
]);
}));
it('ngTableParams test orderBy', inject(function (ngTableParams) {
var params = new ngTableParams({
'sorting[name]': 'asc'
});
expect(params.orderBy()).toEqual([ '+name' ]); // for angular sorting function
params.sorting({ name: 'desc', age: 'asc' });
expect(params.orderBy()).toEqual([ '-name', '+age' ]);
}));
it('ngTableParams test settings', inject(function (ngTableParams) {
var params = new ngTableParams();
expect(params.settings()).toEqual({
$scope: null,
$loading: false,
data: null,
total: 0,
defaultSort : 'desc',
counts: [10, 25, 50, 100],
getData: params.getData,
getGroups: params.getGroups,
filterDelay: 750
});
params = new ngTableParams({}, { total: 100 });
expect(params.settings()).toEqual({
$scope: null,
$loading: false,
data: null,
total: 100,
defaultSort : 'desc',
counts: [10, 25, 50, 100],
getData: params.getData,
getGroups: params.getGroups,
filterDelay: 750
});
}));
it('ngTableParams test getData', inject(function ($q, ngTableParams) {
var params = new ngTableParams();
$defer = $q.defer();
$defer.promise.then(function(data) {
expect(data).toEqual([]);
});
params.getData($defer);
}));
it('ngTableParams test grouping', inject(function ($q, ngTableParams) {
var params = new ngTableParams();
params.getData = function ($defer) {
$defer.resolve(data);
};
$defer = $q.defer();
$defer.promise.then(function (data) {
expect(data).toEqual([
{
value: 'Administrator',
data: [
{name: "Moroni", age: 50, role: 'Administrator'},
{name: "Tiancum", age: 43, role: 'Administrator'},
{name: "Jacob", age: 27, role: 'Administrator'}
]
},
{
value: 'Moderator',
data: [
{name: "Nephi", age: 29, role: 'Moderator'},
{name: "Nephi", age: 29, role: 'Moderator'},
{name: "Tiancum", age: 43, role: 'Moderator'},
{name: "Enos", age: 34, role: 'Moderator'}
]
},
{
value: 'User',
data: [
{name: "Enos", age: 34, role: 'User'},
{name: "Tiancum", age: 43, role: 'User'},
{name: "Jacob", age: 27, role: 'User'},
{name: "Enos", age: 34, role: 'User'},
{name: "Jacob", age: 27, role: 'User'},
{name: "Nephi", age: 29, role: 'User'},
{name: "Tiancum", age: 43, role: 'User'},
{name: "Jacob", age: 27, role: 'User'},
{name: "Nephi", age: 29, role: 'User'},
{name: "Enos", age: 34, role: 'User'}
]
}
]);
});
params.getGroups($defer, 'role');
$defer = $q.defer();
$defer.promise.then(function (data) {
expect(data).toEqual([
{
value: 50,
data: [
{name: "Moroni", age: 50, role: 'Administrator'}
]
},
{
value: 43,
data: [
{name: "Tiancum", age: 43, role: 'Administrator'},
{name: "Tiancum", age: 43, role: 'User'},
{name: "Tiancum", age: 43, role: 'Moderator'},
{name: "Tiancum", age: 43, role: 'User'}
]
},
{
value: 27,
data: [
{name: "Jacob", age: 27, role: 'Administrator'},
{name: "Jacob", age: 27, role: 'User'},
{name: "Jacob", age: 27, role: 'User'},
{name: "Jacob", age: 27, role: 'User'}
]
},
{
value: 29,
data: [
{name: "Nephi", age: 29, role: 'Moderator'},
{name: "Nephi", age: 29, role: 'Moderator'},
{name: "Nephi", age: 29, role: 'User'},
{name: "Nephi", age: 29, role: 'User'}
]
},
{
value: 34,
data: [
{name: "Enos", age: 34, role: 'User'},
{name: "Enos", age: 34, role: 'User'},
{name: "Enos", age: 34, role: 'Moderator'},
{name: "Enos", age: 34, role: 'User'}
]
}
]);
});
params.getGroups($defer, 'age');
}));
});

View file

@ -0,0 +1,113 @@
describe('ng-table', function () {
var elm, scope, data = [
{id: 1, name: "Moroni", age: 50, money: -10},
{id: 2, name: "Tiancum", age: 43, money: 120},
{id: 3, name: "Jacob", age: 27, money: 5.5},
{id: 4, name: "Nephi", age: 29, money: -54},
{id: 5, name: "Enos", age: 34, money: 110},
{id: 6, name: "Tiancum", age: 43, money: 1000},
{id: 7, name: "Jacob", age: 27, money: -201},
{id: 8, name: "Nephi", age: 29, money: 100},
{id: 9, name: "Enos", age: 34, money: -52.5},
{id: 10, name: "Tiancum", age: 43, money: 52.1},
{id: 11, name: "Jacob", age: 27, money: 110},
{id: 12, name: "Nephi", age: 29, money: -55},
{id: 13, name: "Enos", age: 34, money: 551},
{id: 14, name: "Tiancum", age: 43, money: -1410},
{id: 15, name: "Jacob", age: 27, money: 410},
{id: 16, name: "Nephi", age: 29, money: 100},
{id: 17, name: "Enos", age: 34, money: -100}
];
beforeEach(module('ngTable'));
beforeEach(inject(function ($rootScope, $compile, $q) {
elm = angular.element(
'<div>' +
'<script type="text/ng-template" id="ng-table/filters/money.html"></script>' +
'<table ng-table="tableParams" show-filter="true">' +
'<tr ng-repeat="user in $data">' +
'<td data-title="\'Name of person\'" filter="{ \'name\': \'text\' }" sortable="name">' +
'{{user.name}}' +
'</td>' +
'<td x-data-title="\'Age\'" sortable="age">' +
'{{user.age}}' +
'</td>' +
'<td title="\'Money\'" filter="{ \'action\': \'money\' }" filter-data="money($column)">' +
'{{user.money}}' +
'</td>' +
'</tr>' +
'</table>' +
'</div>');
scope = $rootScope.$new(true);
scope.money = function() {
var def = $q.defer();
def.resolve([{
'id': 10,
'title': '10'
}]);
return def;
};
$compile(elm)(scope);
scope.$digest();
}));
it('should create table header', inject(function ($compile, $rootScope) {
var thead = elm.find('thead');
expect(thead.length).toBe(1);
var rows = thead.find('tr');
expect(rows.length).toBe(2);
var titles = angular.element(rows[0]).find('th');
expect(titles.length).toBe(3);
expect(angular.element(titles[0]).text().trim()).toBe('Name of person');
expect(angular.element(titles[1]).text().trim()).toBe('Age');
expect(angular.element(titles[2]).text().trim()).toBe('Money');
var filters = angular.element(rows[1]).find('th');
expect(filters.length).toBe(3);
}));
it('should show scope data', inject(function ($compile, $rootScope, ngTableParams) {
debugger;
var tbody = elm.find('tbody');
expect(tbody.length).toBe(1);
var rows = tbody.find('tr');
expect(rows.length).toBe(0);
var params = new ngTableParams({
page: 1, // show first page
count: 10 // count per page
}, {
total: data.length, // length of data
getData: function($defer, params) {
$defer.resolve(data.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
scope.tableParams = params;
scope.$digest();
rows = tbody.find('tr');
expect(rows.length).toBe(10);
scope.tableParams.page(2);
scope.$digest();
rows = tbody.find('tr');
expect(rows.length).toBe(7);
params.total(20);
scope.$digest();
rows = tbody.find('tr');
expect(rows.length).toBe(7);
}));
});

View file

@ -17,6 +17,7 @@
<link type="text/css" rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css">
<link type="text/css" rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap-theme.min.css">
<link type="text/css" rel="stylesheet" href="/bower_components/angular-loading-bar/build/loading-bar.min.css">
<link type="text/css" rel="stylesheet" href="/bower_components/ng-table/ng-table.min.css">
<link type="text/css" rel="stylesheet" href="/css/app.css"/>
<script src="/bower_components/html5-boilerplate/js/vendor/modernizr-2.6.2.min.js"></script>
@ -46,6 +47,7 @@
<script src="/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<script src="/bower_components/angularjs-nvd3-directives/dist/angularjs-nvd3-directives.min.js"></script>
<script src="/bower_components/angular-loading-bar/build/loading-bar.min.js"></script>
<script src="/bower_components/ng-table/ng-table.min.js"></script>
<!-- APP -->
<script src="/js/app.js"></script>
@ -62,7 +64,6 @@
<!-- MAIN -->
<script src="/js/main/state.js"></script>
<script src="/js/main/controllers/BalanceCtrl.js"></script>
<script src="/js/main/filters/formatLedgerEntries.js"></script>
</body>
</html>

View file

@ -1,4 +1,5 @@
var app = angular.module( 'app', [ 'ui.router',
'nvd3ChartDirectives',
'angularMoment',
'chieffancypants.loadingBar' ] );
'chieffancypants.loadingBar',
'ngTable' ] );

View file

@ -1,17 +0,0 @@
app.filter( 'formatLedgerEntries',
[ '$sce',
function( $sce ) {
return function( entries ) {
return $sce.trustAsHtml( '<table><tr>'
+ entries
.map( function( entry ) {
return '<td>'
+ entry.account
+ '</td><td>'
+ entry.amount
+' €</td>';
} )
.join( '</tr><tr>' )
+ '</tr></table>' );
};
} ] );

View file

@ -38,7 +38,13 @@
<svg></svg>
</nvd3-pie-chart>
</div>
<div class="panel-footer" data-ng-bind-html="balance.expenses | formatLedgerEntries">
<div class="panel-footer">
<table ng-table="tableParams" class="table">
<tr ng-repeat="account in balance.expenses">
<td data-title="'Account'">{{account.account}}</td>
<td data-title="'Amount'">{{account.amount}} €</td>
</tr>
</table>
</div>
</div>
</div>
@ -64,7 +70,13 @@
<svg></svg>
</nvd3-pie-chart>
</div>
<div class="panel-footer" data-ng-bind-html="balance.income | formatLedgerEntries">
<div class="panel-footer">
<table ng-table="tableParams" class="table">
<tr ng-repeat="account in balance.income">
<td data-title="'Account'">{{account.account}}</td>
<td data-title="'Amount'">{{account.amount}} €</td>
</tr>
</table>
</div>
</div>
</div>

View file

@ -14,6 +14,7 @@
"angular-bootstrap": "latest",
"bootstrap": "latest",
"angular-moment": "latest",
"angular-loading-bar": "latest"
"angular-loading-bar": "latest",
"ng-table": "latest"
}
}