angular-ng-table-rails 0.5.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e39c7adb1a521d431e7778beba70284725ca92fa
4
+ data.tar.gz: 43823248579636a4b7856385273be86177403ff4
5
+ SHA512:
6
+ metadata.gz: 57415fb4b68bc22fe4bdbd0aeb20933a4b6c6562ef60ab1d5a02666bcb7677a4ac979e4a7c36c642fa33da9801a661181286a9e3c8e4b89d1ce1f0c086201fd5
7
+ data.tar.gz: b9cb61a68e3c16da539074ae75652f0d4479713c7a9dad6171ba003b7c6bf1499194645a822b717118d02d371a4f8dd662bec2091c68e773a386b01f70166524
@@ -0,0 +1,22 @@
1
+ Angular-UI-Bootstrap-Rails RubyGem Copyright (c) 2013 Chris Constantin
2
+
3
+ Angular.JS and related components Copyright (c) 2010-2013 Google Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,25 @@
1
+ # angular-ng-table-rails
2
+
3
+ ng-table angular wraps the [Angular.js](https://github.com/esvit/ng-table) library for use in Rails 3.1 and above. Assets will minify automatically during production.
4
+
5
+ ## Usage
6
+
7
+ Add the following to your gemfile:
8
+
9
+ gem 'angular-ng-table-rails'
10
+
11
+ Add the following directive to your Javascript manifest file (application.js):
12
+
13
+ //= require ng-table
14
+
15
+ Add the following directive to your Stylesheets manifest file (application.css):
16
+
17
+ *= require ng-table
18
+
19
+
20
+ You may need to add 'ui.bootstrap' into your app declaration for example
21
+
22
+ app = angular.module('MyApp', ["ngTable"])
23
+
24
+ Gem based on ng-table(https://github.com/esvit/ng-table) by Bazalt CMS
25
+
@@ -0,0 +1,8 @@
1
+ require "angular-ng-table-rails/version"
2
+
3
+ module NgTable
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module NgTable
2
+ module Rails
3
+ VERSION = "0.5.4.1"
4
+ end
5
+ end
@@ -0,0 +1,973 @@
1
+
2
+ (function(angular, factory) {
3
+ 'use strict';
4
+
5
+ if (typeof define === 'function' && define.amd) {
6
+ define(['angular'], function(angular) {
7
+ return factory(angular);
8
+ });
9
+ } else {
10
+ return factory(angular);
11
+ }
12
+ }(angular || null, function(angular) {
13
+ 'use strict';
14
+ /**
15
+ * ngTable: Table + Angular JS
16
+ *
17
+ * @author Vitalii Savchuk <esvit666@gmail.com>
18
+ * @url https://github.com/esvit/ng-table/
19
+ * @license New BSD License <http://creativecommons.org/licenses/BSD/>
20
+ */
21
+
22
+ /**
23
+ * @ngdoc module
24
+ * @name ngTable
25
+ * @description ngTable: Table + Angular JS
26
+ * @example
27
+ <doc:example>
28
+ <doc:source>
29
+ <script>
30
+ var app = angular.module('myApp', ['ngTable']);
31
+ app.controller('MyCtrl', function($scope) {
32
+ $scope.users = [
33
+ {name: "Moroni", age: 50},
34
+ {name: "Tiancum", age: 43},
35
+ {name: "Jacob", age: 27},
36
+ {name: "Nephi", age: 29},
37
+ {name: "Enos", age: 34}
38
+ ];
39
+ });
40
+ </script>
41
+ <table ng-table class="table">
42
+ <tr ng-repeat="user in users">
43
+ <td data-title="'Name'">{{user.name}}</td>
44
+ <td data-title="'Age'">{{user.age}}</td>
45
+ </tr>
46
+ </table>
47
+ </doc:source>
48
+ </doc:example>
49
+ */
50
+ var app = angular.module('ngTable', []);
51
+ /**
52
+ * ngTable: Table + Angular JS
53
+ *
54
+ * @author Vitalii Savchuk <esvit666@gmail.com>
55
+ * @url https://github.com/esvit/ng-table/
56
+ * @license New BSD License <http://creativecommons.org/licenses/BSD/>
57
+ */
58
+
59
+ /**
60
+ * @ngdoc value
61
+ * @name ngTable.value:ngTableDefaultParams
62
+ * @description Default Parameters for ngTable
63
+ */
64
+ app.value('ngTableDefaults', {
65
+ params: {},
66
+ settings: {}
67
+ });
68
+
69
+ /**
70
+ * @ngdoc service
71
+ * @name ngTable.factory:NgTableParams
72
+ * @description Parameters manager for ngTable
73
+ */
74
+
75
+ app.factory('NgTableParams', ['$q', '$log', 'ngTableDefaults', function($q, $log, ngTableDefaults) {
76
+ var isNumber = function(n) {
77
+ return !isNaN(parseFloat(n)) && isFinite(n);
78
+ };
79
+ var NgTableParams = function(baseParameters, baseSettings) {
80
+ var self = this,
81
+ log = function() {
82
+ if (settings.debugMode && $log.debug) {
83
+ $log.debug.apply(this, arguments);
84
+ }
85
+ };
86
+
87
+ this.data = [];
88
+
89
+ /**
90
+ * @ngdoc method
91
+ * @name ngTable.factory:NgTableParams#parameters
92
+ * @methodOf ngTable.factory:NgTableParams
93
+ * @description Set new parameters or get current parameters
94
+ *
95
+ * @param {string} newParameters New parameters
96
+ * @param {string} parseParamsFromUrl Flag if parse parameters like in url
97
+ * @returns {Object} Current parameters or `this`
98
+ */
99
+ this.parameters = function(newParameters, parseParamsFromUrl) {
100
+ parseParamsFromUrl = parseParamsFromUrl || false;
101
+ if (angular.isDefined(newParameters)) {
102
+ for (var key in newParameters) {
103
+ var value = newParameters[key];
104
+ if (parseParamsFromUrl && key.indexOf('[') >= 0) {
105
+ var keys = key.split(/\[(.*)\]/).reverse()
106
+ var lastKey = '';
107
+ for (var i = 0, len = keys.length; i < len; i++) {
108
+ var name = keys[i];
109
+ if (name !== '') {
110
+ var v = value;
111
+ value = {};
112
+ value[lastKey = name] = (isNumber(v) ? parseFloat(v) : v);
113
+ }
114
+ }
115
+ if (lastKey === 'sorting') {
116
+ params[lastKey] = {};
117
+ }
118
+ params[lastKey] = angular.extend(params[lastKey] || {}, value[lastKey]);
119
+ } else {
120
+ params[key] = (isNumber(newParameters[key]) ? parseFloat(newParameters[key]) : newParameters[key]);
121
+ }
122
+ }
123
+ log('ngTable: set parameters', params);
124
+ return this;
125
+ }
126
+ return params;
127
+ };
128
+
129
+ /**
130
+ * @ngdoc method
131
+ * @name ngTable.factory:NgTableParams#settings
132
+ * @methodOf ngTable.factory:NgTableParams
133
+ * @description Set new settings for table
134
+ *
135
+ * @param {string} newSettings New settings or undefined
136
+ * @returns {Object} Current settings or `this`
137
+ */
138
+ this.settings = function(newSettings) {
139
+ if (angular.isDefined(newSettings)) {
140
+ if (angular.isArray(newSettings.data)) {
141
+ //auto-set the total from passed in data
142
+ newSettings.total = newSettings.data.length;
143
+ }
144
+ settings = angular.extend(settings, newSettings);
145
+ log('ngTable: set settings', settings);
146
+ return this;
147
+ }
148
+ return settings;
149
+ };
150
+
151
+ /**
152
+ * @ngdoc method
153
+ * @name ngTable.factory:NgTableParams#page
154
+ * @methodOf ngTable.factory:NgTableParams
155
+ * @description If parameter page not set return current page else set current page
156
+ *
157
+ * @param {string} page Page number
158
+ * @returns {Object|Number} Current page or `this`
159
+ */
160
+ this.page = function(page) {
161
+ return angular.isDefined(page) ? this.parameters({
162
+ 'page': page
163
+ }) : params.page;
164
+ };
165
+
166
+ /**
167
+ * @ngdoc method
168
+ * @name ngTable.factory:NgTableParams#total
169
+ * @methodOf ngTable.factory:NgTableParams
170
+ * @description If parameter total not set return current quantity else set quantity
171
+ *
172
+ * @param {string} total Total quantity of items
173
+ * @returns {Object|Number} Current page or `this`
174
+ */
175
+ this.total = function(total) {
176
+ return angular.isDefined(total) ? this.settings({
177
+ 'total': total
178
+ }) : settings.total;
179
+ };
180
+
181
+ /**
182
+ * @ngdoc method
183
+ * @name ngTable.factory:NgTableParams#count
184
+ * @methodOf ngTable.factory:NgTableParams
185
+ * @description If parameter count not set return current count per page else set count per page
186
+ *
187
+ * @param {string} count Count per number
188
+ * @returns {Object|Number} Count per page or `this`
189
+ */
190
+ this.count = function(count) {
191
+ // reset to first page because can be blank page
192
+ return angular.isDefined(count) ? this.parameters({
193
+ 'count': count,
194
+ 'page': 1
195
+ }) : params.count;
196
+ };
197
+
198
+ /**
199
+ * @ngdoc method
200
+ * @name ngTable.factory:NgTableParams#filter
201
+ * @methodOf ngTable.factory:NgTableParams
202
+ * @description If parameter page not set return current filter else set current filter
203
+ *
204
+ * @param {string} filter New filter
205
+ * @returns {Object} Current filter or `this`
206
+ */
207
+ this.filter = function(filter) {
208
+ return angular.isDefined(filter) ? this.parameters({
209
+ 'filter': filter,
210
+ 'page': 1
211
+ }) : params.filter;
212
+ };
213
+
214
+ /**
215
+ * @ngdoc method
216
+ * @name ngTable.factory:NgTableParams#sorting
217
+ * @methodOf ngTable.factory:NgTableParams
218
+ * @description If 'sorting' parameter is not set, return current sorting. Otherwise set current sorting.
219
+ *
220
+ * @param {string} sorting New sorting
221
+ * @returns {Object} Current sorting or `this`
222
+ */
223
+ this.sorting = function(sorting) {
224
+ if (arguments.length == 2) {
225
+ var sortArray = {};
226
+ sortArray[sorting] = arguments[1];
227
+ this.parameters({
228
+ 'sorting': sortArray
229
+ });
230
+ return this;
231
+ }
232
+ return angular.isDefined(sorting) ? this.parameters({
233
+ 'sorting': sorting
234
+ }) : params.sorting;
235
+ };
236
+
237
+ /**
238
+ * @ngdoc method
239
+ * @name ngTable.factory:NgTableParams#isSortBy
240
+ * @methodOf ngTable.factory:NgTableParams
241
+ * @description Checks sort field
242
+ *
243
+ * @param {string} field Field name
244
+ * @param {string} direction Direction of sorting 'asc' or 'desc'
245
+ * @returns {Array} Return true if field sorted by direction
246
+ */
247
+ this.isSortBy = function(field, direction) {
248
+ return angular.isDefined(params.sorting[field]) && angular.equals(params.sorting[field], direction);
249
+ };
250
+
251
+ /**
252
+ * @ngdoc method
253
+ * @name ngTable.factory:NgTableParams#orderBy
254
+ * @methodOf ngTable.factory:NgTableParams
255
+ * @description Return object of sorting parameters for angular filter
256
+ *
257
+ * @returns {Array} Array like: [ '-name', '+age' ]
258
+ */
259
+ this.orderBy = function() {
260
+ var sorting = [];
261
+ for (var column in params.sorting) {
262
+ sorting.push((params.sorting[column] === "asc" ? "+" : "-") + column);
263
+ }
264
+ return sorting;
265
+ };
266
+
267
+ /**
268
+ * @ngdoc method
269
+ * @name ngTable.factory:NgTableParams#getData
270
+ * @methodOf ngTable.factory:NgTableParams
271
+ * @description Called when updated some of parameters for get new data
272
+ *
273
+ * @param {Object} $defer promise object
274
+ * @param {Object} params New parameters
275
+ */
276
+ this.getData = function($defer, params) {
277
+ if (angular.isArray(this.data) && angular.isObject(params)) {
278
+ $defer.resolve(this.data.slice((params.page() - 1) * params.count(), params.page() * params.count()));
279
+ } else {
280
+ $defer.resolve([]);
281
+ }
282
+ return $defer.promise;
283
+ };
284
+
285
+ /**
286
+ * @ngdoc method
287
+ * @name ngTable.factory:NgTableParams#getGroups
288
+ * @methodOf ngTable.factory:NgTableParams
289
+ * @description Return groups for table grouping
290
+ */
291
+ this.getGroups = function($defer, column) {
292
+ var defer = $q.defer();
293
+
294
+ defer.promise.then(function(data) {
295
+ var groups = {};
296
+ angular.forEach(data, function(item) {
297
+ var groupName = angular.isFunction(column) ? column(item) : item[column];
298
+
299
+ groups[groupName] = groups[groupName] || {
300
+ data: []
301
+ };
302
+ groups[groupName]['value'] = groupName;
303
+ groups[groupName].data.push(item);
304
+ });
305
+ var result = [];
306
+ for (var i in groups) {
307
+ result.push(groups[i]);
308
+ }
309
+ log('ngTable: refresh groups', result);
310
+ $defer.resolve(result);
311
+ });
312
+ return this.getData(defer, self);
313
+ };
314
+
315
+ /**
316
+ * @ngdoc method
317
+ * @name ngTable.factory:NgTableParams#generatePagesArray
318
+ * @methodOf ngTable.factory:NgTableParams
319
+ * @description Generate array of pages
320
+ *
321
+ * @param {boolean} currentPage which page must be active
322
+ * @param {boolean} totalItems Total quantity of items
323
+ * @param {boolean} pageSize Quantity of items on page
324
+ * @returns {Array} Array of pages
325
+ */
326
+ this.generatePagesArray = function(currentPage, totalItems, pageSize) {
327
+ var maxBlocks, maxPage, maxPivotPages, minPage, numPages, pages;
328
+ maxBlocks = 11;
329
+ pages = [];
330
+ numPages = Math.ceil(totalItems / pageSize);
331
+ if (numPages > 1) {
332
+ pages.push({
333
+ type: 'prev',
334
+ number: Math.max(1, currentPage - 1),
335
+ active: currentPage > 1
336
+ });
337
+ pages.push({
338
+ type: 'first',
339
+ number: 1,
340
+ active: currentPage > 1,
341
+ current: currentPage === 1
342
+ });
343
+ maxPivotPages = Math.round((maxBlocks - 5) / 2);
344
+ minPage = Math.max(2, currentPage - maxPivotPages);
345
+ maxPage = Math.min(numPages - 1, currentPage + maxPivotPages * 2 - (currentPage - minPage));
346
+ minPage = Math.max(2, minPage - (maxPivotPages * 2 - (maxPage - minPage)));
347
+ var i = minPage;
348
+ while (i <= maxPage) {
349
+ if ((i === minPage && i !== 2) || (i === maxPage && i !== numPages - 1)) {
350
+ pages.push({
351
+ type: 'more',
352
+ active: false
353
+ });
354
+ } else {
355
+ pages.push({
356
+ type: 'page',
357
+ number: i,
358
+ active: currentPage !== i,
359
+ current: currentPage === i
360
+ });
361
+ }
362
+ i++;
363
+ }
364
+ pages.push({
365
+ type: 'last',
366
+ number: numPages,
367
+ active: currentPage !== numPages,
368
+ current: currentPage === numPages
369
+ });
370
+ pages.push({
371
+ type: 'next',
372
+ number: Math.min(numPages, currentPage + 1),
373
+ active: currentPage < numPages
374
+ });
375
+ }
376
+ return pages;
377
+ };
378
+
379
+ /**
380
+ * @ngdoc method
381
+ * @name ngTable.factory:NgTableParams#url
382
+ * @methodOf ngTable.factory:NgTableParams
383
+ * @description Return groups for table grouping
384
+ *
385
+ * @param {boolean} asString flag indicates return array of string or object
386
+ * @returns {Array} If asString = true will be return array of url string parameters else key-value object
387
+ */
388
+ this.url = function(asString) {
389
+ asString = asString || false;
390
+ var pairs = (asString ? [] : {});
391
+ for (var key in params) {
392
+ if (params.hasOwnProperty(key)) {
393
+ var item = params[key],
394
+ name = encodeURIComponent(key);
395
+ if (typeof item === "object") {
396
+ for (var subkey in item) {
397
+ if (!angular.isUndefined(item[subkey]) && item[subkey] !== "") {
398
+ var pname = name + "[" + encodeURIComponent(subkey) + "]";
399
+ if (asString) {
400
+ pairs.push(pname + "=" + item[subkey]);
401
+ } else {
402
+ pairs[pname] = item[subkey];
403
+ }
404
+ }
405
+ }
406
+ } else if (!angular.isFunction(item) && !angular.isUndefined(item) && item !== "") {
407
+ if (asString) {
408
+ pairs.push(name + "=" + encodeURIComponent(item));
409
+ } else {
410
+ pairs[name] = encodeURIComponent(item);
411
+ }
412
+ }
413
+ }
414
+ }
415
+ return pairs;
416
+ };
417
+
418
+ /**
419
+ * @ngdoc method
420
+ * @name ngTable.factory:NgTableParams#reload
421
+ * @methodOf ngTable.factory:NgTableParams
422
+ * @description Reload table data
423
+ */
424
+ this.reload = function() {
425
+ var $defer = $q.defer(),
426
+ self = this,
427
+ pData = null;
428
+
429
+ if (!settings.$scope) {
430
+ return;
431
+ }
432
+
433
+ settings.$loading = true;
434
+ if (settings.groupBy) {
435
+ pData = settings.getGroups($defer, settings.groupBy, this);
436
+ } else {
437
+ pData = settings.getData($defer, this);
438
+ }
439
+ log('ngTable: reload data');
440
+
441
+ if (!pData) {
442
+ // If getData resolved the $defer, and didn't promise us data,
443
+ // create a promise from the $defer. We need to return a promise.
444
+ pData = $defer.promise;
445
+ }
446
+ return pData.then(function(data) {
447
+ settings.$loading = false;
448
+ log('ngTable: current scope', settings.$scope);
449
+ if (settings.groupBy) {
450
+ self.data = data;
451
+ if (settings.$scope) settings.$scope.$groups = data;
452
+ } else {
453
+ self.data = data;
454
+ if (settings.$scope) settings.$scope.$data = data;
455
+ }
456
+ if (settings.$scope) settings.$scope.pages = self.generatePagesArray(self.page(), self.total(), self.count());
457
+ settings.$scope.$emit('ngTableAfterReloadData');
458
+ return data;
459
+ });
460
+ };
461
+
462
+ this.reloadPages = function() {
463
+ var self = this;
464
+ settings.$scope.pages = self.generatePagesArray(self.page(), self.total(), self.count());
465
+ };
466
+
467
+ var params = this.$params = {
468
+ page: 1,
469
+ count: 1,
470
+ filter: {},
471
+ sorting: {},
472
+ group: {},
473
+ groupBy: null
474
+ };
475
+ angular.extend(params, ngTableDefaults.params);
476
+
477
+ var settings = {
478
+ $scope: null, // set by ngTable controller
479
+ $loading: false,
480
+ data: null, //allows data to be set when table is initialized
481
+ total: 0,
482
+ defaultSort: 'desc',
483
+ filterDelay: 750,
484
+ counts: [10, 25, 50, 100],
485
+ sortingIndicator: 'span',
486
+ getGroups: this.getGroups,
487
+ getData: this.getData
488
+ };
489
+ angular.extend(settings, ngTableDefaults.settings);
490
+
491
+ this.settings(baseSettings);
492
+ this.parameters(baseParameters, true);
493
+ return this;
494
+ };
495
+ return NgTableParams;
496
+ }]);
497
+
498
+ /**
499
+ * @ngdoc service
500
+ * @name ngTable.factory:ngTableParams
501
+ * @description Backwards compatible shim for lowercase 'n' in NgTableParams
502
+ */
503
+ app.factory('ngTableParams', ['NgTableParams', function(NgTableParams) {
504
+ return NgTableParams;
505
+ }]);
506
+
507
+ /**
508
+ * ngTable: Table + Angular JS
509
+ *
510
+ * @author Vitalii Savchuk <esvit666@gmail.com>
511
+ * @url https://github.com/esvit/ng-table/
512
+ * @license New BSD License <http://creativecommons.org/licenses/BSD/>
513
+ */
514
+
515
+ /**
516
+ * @ngdoc object
517
+ * @name ngTable.directive:ngTable.ngTableController
518
+ *
519
+ * @description
520
+ * Each {@link ngTable.directive:ngTable ngTable} directive creates an instance of `ngTableController`
521
+ */
522
+ app.controller('ngTableController', ['$scope', 'NgTableParams', '$timeout', '$parse', '$compile', '$attrs', '$element',
523
+ 'ngTableColumn',
524
+ function($scope, NgTableParams, $timeout, $parse, $compile, $attrs, $element, ngTableColumn) {
525
+ var isFirstTimeLoad = true;
526
+ $scope.$filterRow = {};
527
+ $scope.$loading = false;
528
+
529
+ // until such times as the directive uses an isolated scope, we need to ensure that the check for
530
+ // the params field only consults the "own properties" of the $scope. This is to avoid seeing the params
531
+ // field on a $scope higher up in the prototype chain
532
+ if (!$scope.hasOwnProperty("params")) {
533
+ $scope.params = new NgTableParams();
534
+ $scope.params.isNullInstance = true;
535
+ }
536
+ $scope.params.settings().$scope = $scope;
537
+
538
+ var delayFilter = (function() {
539
+ var timer = 0;
540
+ return function(callback, ms) {
541
+ $timeout.cancel(timer);
542
+ timer = $timeout(callback, ms);
543
+ };
544
+ })();
545
+
546
+ function resetPage() {
547
+ $scope.params.$params.page = 1;
548
+ }
549
+
550
+ $scope.$watch('params.$params', function(newParams, oldParams) {
551
+
552
+ if (newParams === oldParams) {
553
+ return;
554
+ }
555
+
556
+ $scope.params.settings().$scope = $scope;
557
+
558
+ if (!angular.equals(newParams.filter, oldParams.filter)) {
559
+ var maybeResetPage = isFirstTimeLoad ? angular.noop : resetPage;
560
+ delayFilter(function() {
561
+ maybeResetPage();
562
+ $scope.params.reload();
563
+ }, $scope.params.settings().filterDelay);
564
+ } else {
565
+ $scope.params.reload();
566
+ }
567
+
568
+ if (!$scope.params.isNullInstance) {
569
+ isFirstTimeLoad = false;
570
+ }
571
+
572
+ }, true);
573
+
574
+ this.compileDirectiveTemplates = function () {
575
+ if (!$element.hasClass('ng-table')) {
576
+ $scope.templates = {
577
+ header: ($attrs.templateHeader ? $attrs.templateHeader : 'ng-table/header.html'),
578
+ pagination: ($attrs.templatePagination ? $attrs.templatePagination : 'ng-table/pager.html')
579
+ };
580
+ $element.addClass('ng-table');
581
+ var headerTemplate = null;
582
+ if ($element.find('> thead').length === 0) {
583
+ headerTemplate = angular.element(document.createElement('thead')).attr('ng-include', 'templates.header');
584
+ $element.prepend(headerTemplate);
585
+ }
586
+ var paginationTemplate = angular.element(document.createElement('div')).attr({
587
+ 'ng-table-pagination': 'params',
588
+ 'template-url': 'templates.pagination'
589
+ });
590
+ $element.after(paginationTemplate);
591
+ if (headerTemplate) {
592
+ $compile(headerTemplate)($scope);
593
+ }
594
+ $compile(paginationTemplate)($scope);
595
+ }
596
+ };
597
+
598
+ this.loadFilterData = function ($columns) {
599
+ angular.forEach($columns, function ($column) {
600
+ var def;
601
+ def = $column.filterData($scope, {
602
+ $column: $column
603
+ });
604
+ if (!def) {
605
+ delete $column.filterData;
606
+ return;
607
+ }
608
+
609
+ // if we're working with a deferred object, let's wait for the promise
610
+ if ((angular.isObject(def) && angular.isObject(def.promise))) {
611
+ delete $column.filterData;
612
+ return def.promise.then(function(data) {
613
+ // our deferred can eventually return arrays, functions and objects
614
+ if (!angular.isArray(data) && !angular.isFunction(data) && !angular.isObject(data)) {
615
+ // if none of the above was found - we just want an empty array
616
+ data = [];
617
+ } else if (angular.isArray(data)) {
618
+ data.unshift({
619
+ title: '-',
620
+ id: ''
621
+ });
622
+ }
623
+ $column.data = data;
624
+ });
625
+ }
626
+ // otherwise, we just return what the user gave us. It could be a function, array, object, whatever
627
+ else {
628
+ return $column.data = def;
629
+ }
630
+ });
631
+ };
632
+
633
+ this.buildColumns = function (columns) {
634
+ return columns.map(function(col){
635
+ return ngTableColumn.buildColumn(col, $scope)
636
+ })
637
+ };
638
+
639
+ this.setupBindingsToInternalScope = function(tableParamsExpr){
640
+
641
+ // note: this we're setting up watches to simulate angular's isolated scope bindings
642
+
643
+ // note: is REALLY important to watch for a change to the ngTableParams *reference* rather than
644
+ // $watch for value equivalence. This is because ngTableParams references the current page of data as
645
+ // a field and it's important not to watch this
646
+ var tableParamsGetter = $parse(tableParamsExpr);
647
+ $scope.$watch(tableParamsGetter, (function (params) {
648
+ if (angular.isUndefined(params)) {
649
+ return;
650
+ }
651
+ $scope.paramsModel = tableParamsGetter;
652
+ $scope.params = params;
653
+ }), false);
654
+
655
+ if ($attrs.showFilter) {
656
+ $scope.$parent.$watch($attrs.showFilter, function(value) {
657
+ $scope.show_filter = value;
658
+ });
659
+ }
660
+ if ($attrs.disableFilter) {
661
+ $scope.$parent.$watch($attrs.disableFilter, function(value) {
662
+ $scope.$filterRow.disabled = value;
663
+ });
664
+ }
665
+ };
666
+
667
+ $scope.sortBy = function($column, event) {
668
+ var parsedSortable = $column.sortable && $column.sortable();
669
+ if (!parsedSortable) {
670
+ return;
671
+ }
672
+ var defaultSort = $scope.params.settings().defaultSort;
673
+ var inverseSort = (defaultSort === 'asc' ? 'desc' : 'asc');
674
+ var sorting = $scope.params.sorting() && $scope.params.sorting()[parsedSortable] && ($scope.params.sorting()[parsedSortable] === defaultSort);
675
+ var sortingParams = (event.ctrlKey || event.metaKey) ? $scope.params.sorting() : {};
676
+ sortingParams[parsedSortable] = (sorting ? inverseSort : defaultSort);
677
+ $scope.params.parameters({
678
+ sorting: sortingParams
679
+ });
680
+ };
681
+ }]);
682
+
683
+
684
+ /**
685
+ * @ngdoc service
686
+ * @name ngTable.factory:ngTableColumn
687
+ *
688
+ * @description
689
+ * Service to construct a $column definition used by {@link ngTable.directive:ngTable ngTable} directive
690
+ */
691
+ app.factory('ngTableColumn', [function () {
692
+
693
+ var defaults = {
694
+ 'class': function(){ return ''; },
695
+ filter: function(){ return false; },
696
+ filterData: angular.noop,
697
+ headerTemplateURL: function(){ return false; },
698
+ headerTitle: function(){ return ' '; },
699
+ sortable: function(){ return false; },
700
+ show: function(){ return true; },
701
+ title: function(){ return ' '; },
702
+ titleAlt: function(){ return ''; }
703
+ };
704
+
705
+ /**
706
+ * @ngdoc method
707
+ * @name ngTable.factory:ngTableColumn#buildColumn
708
+ * @methodOf ngTable.factory:ngTableColumn
709
+ * @description Creates a $column for use within a header template
710
+ *
711
+ * @param {Object} column an existing $column or simple column data object
712
+ * @param {Scope} defaultScope the $scope to supply to the $column getter methods when not supplied by caller
713
+ * @returns {Object} a $column object
714
+ */
715
+ function buildColumn(column, defaultScope){
716
+ // note: we're not modifying the original column object. This helps to avoid unintended side affects
717
+ var extendedCol = Object.create(column);
718
+ for (var prop in defaults) {
719
+ if (extendedCol[prop] === undefined) {
720
+ extendedCol[prop] = defaults[prop];
721
+ }
722
+ if(!angular.isFunction(extendedCol[prop])){
723
+ // wrap raw field values with "getter" functions
724
+ // - this is to ensure consistency with how ngTable.compile builds columns
725
+ // - note that the original column object is being "proxied"; this is important
726
+ // as it ensure that any changes to the original object will be returned by the "getter"
727
+ (function(prop1){
728
+ extendedCol[prop1] = function(){
729
+ return column[prop1];
730
+ };
731
+ })(prop);
732
+ }
733
+ (function(prop1){
734
+ // satisfy the arguments expected by the function returned by parsedAttribute in the ngTable directive
735
+ var getterFn = extendedCol[prop1];
736
+ extendedCol[prop1] = function(){
737
+ if (arguments.length === 0){
738
+ return getterFn.call(column, defaultScope);
739
+ } else {
740
+ return getterFn.apply(column, arguments);
741
+ }
742
+ };
743
+ })(prop);
744
+ }
745
+ return extendedCol;
746
+ }
747
+
748
+ return {
749
+ buildColumn: buildColumn
750
+ };
751
+ }]);
752
+
753
+ /**
754
+ * ngTable: Table + Angular JS
755
+ *
756
+ * @author Vitalii Savchuk <esvit666@gmail.com>
757
+ * @url https://github.com/esvit/ng-table/
758
+ * @license New BSD License <http://creativecommons.org/licenses/BSD/>
759
+ */
760
+
761
+ /**
762
+ * @ngdoc directive
763
+ * @name ngTable.directive:ngTable
764
+ * @restrict A
765
+ *
766
+ * @description
767
+ * Directive that instantiates {@link ngTable.directive:ngTable.ngTableController ngTableController}.
768
+ */
769
+ app.directive('ngTable', ['$q', '$parse',
770
+ function($q, $parse) {
771
+ 'use strict';
772
+
773
+ return {
774
+ restrict: 'A',
775
+ priority: 1001,
776
+ scope: true,
777
+ controller: 'ngTableController',
778
+ compile: function(element) {
779
+ var columns = [],
780
+ i = 0,
781
+ row = null;
782
+
783
+ // IE 8 fix :not(.ng-table-group) selector
784
+ angular.forEach(angular.element(element.find('tr')), function(tr) {
785
+ tr = angular.element(tr);
786
+ if (!tr.hasClass('ng-table-group') && !row) {
787
+ row = tr;
788
+ }
789
+ });
790
+ if (!row) {
791
+ return;
792
+ }
793
+ angular.forEach(row.find('td'), function(item) {
794
+ var el = angular.element(item);
795
+ if (el.attr('ignore-cell') && 'true' === el.attr('ignore-cell')) {
796
+ return;
797
+ }
798
+
799
+ var getAttrValue = function(attr){
800
+ return el.attr('x-data-' + attr) || el.attr('data-' + attr) || el.attr(attr);
801
+ };
802
+
803
+ var parsedAttribute = function(attr) {
804
+ var expr = getAttrValue(attr);
805
+ if (!expr){
806
+ return undefined;
807
+ }
808
+ return function(scope, locals) {
809
+ return $parse(expr)(scope, angular.extend(locals || {}, {
810
+ $columns: columns
811
+ }));
812
+ };
813
+ };
814
+
815
+ var titleExpr = getAttrValue('title-alt') || getAttrValue('title');
816
+ if (titleExpr){
817
+ el.attr('data-title-text', '{{' + titleExpr + '}}'); // this used in responsive table
818
+ }
819
+ // NOTE TO MAINTAINERS: if you add extra fields to a $column be sure to extend ngTableColumn with
820
+ // a corresponding "safe" default
821
+ columns.push({
822
+ id: i++,
823
+ title: parsedAttribute('title'),
824
+ titleAlt: parsedAttribute('title-alt'),
825
+ headerTitle: parsedAttribute('header-title'),
826
+ sortable: parsedAttribute('sortable'),
827
+ 'class': parsedAttribute('header-class'),
828
+ filter: parsedAttribute('filter'),
829
+ headerTemplateURL: parsedAttribute('header'),
830
+ filterData: parsedAttribute('filter-data'),
831
+ show: (el.attr("ng-show") ? function (scope) {
832
+ return $parse(el.attr("ng-show"))(scope);
833
+ } : undefined)
834
+ });
835
+ });
836
+ return function(scope, element, attrs, controller) {
837
+ scope.$columns = columns = controller.buildColumns(columns);
838
+
839
+ controller.setupBindingsToInternalScope(attrs.ngTable);
840
+ controller.loadFilterData(columns);
841
+ controller.compileDirectiveTemplates();
842
+ };
843
+ }
844
+ }
845
+ }
846
+ ]);
847
+
848
+ /**
849
+ * @ngdoc directive
850
+ * @name ngTable.directive:ngTableDynamic
851
+ * @restrict A
852
+ *
853
+ * @description
854
+ * A dynamic version of the {@link ngTable.directive:ngTable ngTable} directive that accepts a dynamic list of columns
855
+ * definitions to render
856
+ */
857
+ app.directive('ngTableDynamic', ['$parse', function ($parse){
858
+
859
+ function parseDirectiveExpression(attr) {
860
+ if (!attr || attr.indexOf(" with ") > -1) {
861
+ var parts = attr.split(/\s+with\s+/);
862
+ return {
863
+ tableParams: parts[0],
864
+ columns: parts[1]
865
+ };
866
+ } else {
867
+ throw new Error('Parse error (expected example: ng-table-dynamic=\'tableParams with cols\')');
868
+ }
869
+ }
870
+
871
+ return {
872
+ restrict: 'A',
873
+ priority: 1001,
874
+ scope: true,
875
+ controller: 'ngTableController',
876
+ compile: function(tElement) {
877
+ var row;
878
+
879
+ // IE 8 fix :not(.ng-table-group) selector
880
+ angular.forEach(angular.element(tElement.find('tr')), function(tr) {
881
+ tr = angular.element(tr);
882
+ if (!tr.hasClass('ng-table-group') && !row) {
883
+ row = tr;
884
+ }
885
+ });
886
+ if (!row) {
887
+ return;
888
+ }
889
+
890
+ angular.forEach(row.find('td'), function(item) {
891
+ var el = angular.element(item);
892
+ var getAttrValue = function(attr){
893
+ return el.attr('x-data-' + attr) || el.attr('data-' + attr) || el.attr(attr);
894
+ };
895
+
896
+ // this used in responsive table
897
+ var titleExpr = getAttrValue('title');
898
+ if (!titleExpr){
899
+ el.attr('data-title-text', '{{$columns[$index].titleAlt(this) || $columns[$index].title(this)}}');
900
+ }
901
+ var showExpr = el.attr('ng-show');
902
+ if (!showExpr){
903
+ el.attr('ng-show', '$columns[$index].show(this)');
904
+ }
905
+ });
906
+
907
+ return function(scope, element, attrs, controller) {
908
+ var expr = parseDirectiveExpression(attrs.ngTableDynamic);
909
+ var columns = $parse(expr.columns)(scope) || [];
910
+ scope.$columns = controller.buildColumns(columns);
911
+
912
+ controller.setupBindingsToInternalScope(expr.tableParams);
913
+ controller.loadFilterData(scope.$columns);
914
+ controller.compileDirectiveTemplates();
915
+ };
916
+ }
917
+ };
918
+ }]);
919
+
920
+ /**
921
+ * ngTable: Table + Angular JS
922
+ *
923
+ * @author Vitalii Savchuk <esvit666@gmail.com>
924
+ * @url https://github.com/esvit/ng-table/
925
+ * @license New BSD License <http://creativecommons.org/licenses/BSD/>
926
+ */
927
+
928
+ /**
929
+ * @ngdoc directive
930
+ * @name ngTable.directive:ngTablePagination
931
+ * @restrict A
932
+ */
933
+ app.directive('ngTablePagination', ['$compile',
934
+ function($compile) {
935
+ 'use strict';
936
+
937
+ return {
938
+ restrict: 'A',
939
+ scope: {
940
+ 'params': '=ngTablePagination',
941
+ 'templateUrl': '='
942
+ },
943
+ replace: false,
944
+ link: function(scope, element, attrs) {
945
+
946
+ scope.params.settings().$scope.$on('ngTableAfterReloadData', function() {
947
+ scope.pages = scope.params.generatePagesArray(scope.params.page(), scope.params.total(), scope.params.count());
948
+ }, true);
949
+
950
+ scope.$watch('templateUrl', function(templateUrl) {
951
+ if (angular.isUndefined(templateUrl)) {
952
+ return;
953
+ }
954
+ var template = angular.element(document.createElement('div'))
955
+ template.attr({
956
+ 'ng-include': 'templateUrl'
957
+ });
958
+ element.append(template);
959
+ $compile(template)(scope);
960
+ });
961
+ }
962
+ };
963
+ }
964
+ ]);
965
+ angular.module('ngTable').run(['$templateCache', function ($templateCache) {
966
+ $templateCache.put('ng-table/filters/select-multiple.html', '<select ng-options="data.id as data.title for data in $column.data" ng-disabled="$filterRow.disabled" multiple ng-multiple="true" ng-model="params.filter()[name]" ng-show="filter==\'select-multiple\'" class="filter filter-select-multiple form-control" name="{{name}}"> </select>');
967
+ $templateCache.put('ng-table/filters/select.html', '<select ng-options="data.id as data.title for data in $column.data" ng-disabled="$filterRow.disabled" ng-model="params.filter()[name]" ng-show="filter==\'select\'" class="filter filter-select form-control" name="{{name}}"> </select>');
968
+ $templateCache.put('ng-table/filters/text.html', '<input type="text" name="{{name}}" ng-disabled="$filterRow.disabled" ng-model="params.filter()[name]" ng-if="filter==\'text\'" class="input-filter form-control"/>');
969
+ $templateCache.put('ng-table/header.html', '<tr> <th title="{{$column.headerTitle(this)}}" ng-repeat="$column in $columns" ng-class="{ \'sortable\': $column.sortable(this), \'sort-asc\': params.sorting()[$column.sortable(this)]==\'asc\', \'sort-desc\': params.sorting()[$column.sortable(this)]==\'desc\' }" ng-click="sortBy($column, $event)" ng-show="$column.show(this)" ng-init="template=$column.headerTemplateURL(this)" class="header {{$column.class(this)}}"> <div ng-if="!template" ng-show="!template" class="ng-table-header" ng-class="{\'sort-indicator\': params.settings().sortingIndicator==\'div\'}"> <span ng-bind="$column.title(this)" ng-class="{\'sort-indicator\': params.settings().sortingIndicator==\'span\'}"></span> </div> <div ng-if="template" ng-show="template" ng-include="template"></div> </th> </tr> <tr ng-show="show_filter" class="ng-table-filters"> <th data-title-text="{{$column.titleAlt(this) || $column.title(this)}}" ng-repeat="$column in $columns" ng-show="$column.show(this)" class="filter"> <div ng-repeat="(name, filter) in $column.filter(this)"> <div ng-if="filter.indexOf(\'/\') !==-1" ng-include="filter"></div> <div ng-if="filter.indexOf(\'/\')===-1" ng-include="\'ng-table/filters/\' + filter + \'.html\'"></div> </div> </th> </tr> ');
970
+ $templateCache.put('ng-table/pager.html', '<div class="ng-cloak ng-table-pager" ng-if="params.data.length"> <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 && !page.current, \'active\': page.current}" 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> ');
971
+ }]);
972
+ return app;
973
+ }));
@@ -0,0 +1,137 @@
1
+
2
+ .ng-table th {
3
+ text-align: center;
4
+ -webkit-touch-callout: none;
5
+ -webkit-user-select: none;
6
+ -khtml-user-select: none;
7
+ -moz-user-select: none;
8
+ -ms-user-select: none;
9
+ user-select: none;
10
+ }
11
+ .ng-table th.sortable {
12
+ cursor: pointer;
13
+ }
14
+ .ng-table th.sortable .sort-indicator {
15
+ padding-right: 18px;
16
+ position: relative;
17
+ }
18
+ .ng-table th.sortable .sort-indicator:after,
19
+ .ng-table th.sortable .sort-indicator:before {
20
+ content: "";
21
+ border-width: 0 4px 4px;
22
+ border-style: solid;
23
+ border-color: #000 transparent;
24
+ visibility: visible;
25
+ right: 5px;
26
+ top: 50%;
27
+ position: absolute;
28
+ opacity: .3;
29
+ margin-top: -4px;
30
+ }
31
+ .ng-table th.sortable .sort-indicator:before {
32
+ margin-top: 2px;
33
+ border-bottom: none;
34
+ border-left: 4px solid transparent;
35
+ border-right: 4px solid transparent;
36
+ border-top: 4px solid #000;
37
+ }
38
+ .ng-table th.sortable .sort-indicator:hover:after,
39
+ .ng-table th.sortable .sort-indicator:hover:before {
40
+ opacity: 1;
41
+ visibility: visible;
42
+ }
43
+ .ng-table th.sortable.sort-desc,
44
+ .ng-table th.sortable.sort-asc {
45
+ background-color: rgba(141, 192, 219, 0.25);
46
+ text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
47
+ }
48
+ .ng-table th.sortable.sort-desc .sort-indicator:after,
49
+ .ng-table th.sortable.sort-asc .sort-indicator:after {
50
+ margin-top: -2px;
51
+ }
52
+ .ng-table th.sortable.sort-desc .sort-indicator:before,
53
+ .ng-table th.sortable.sort-asc .sort-indicator:before {
54
+ visibility: hidden;
55
+ }
56
+ .ng-table th.sortable.sort-asc .sort-indicator:after,
57
+ .ng-table th.sortable.sort-asc .sort-indicator:hover:after {
58
+ visibility: visible;
59
+ filter: alpha(opacity=60);
60
+ -khtml-opacity: 0.6;
61
+ -moz-opacity: 0.6;
62
+ opacity: 0.6;
63
+ }
64
+ .ng-table th.sortable.sort-desc .sort-indicator:after {
65
+ border-bottom: none;
66
+ border-left: 4px solid transparent;
67
+ border-right: 4px solid transparent;
68
+ border-top: 4px solid #000;
69
+ visibility: visible;
70
+ -webkit-box-shadow: none;
71
+ -moz-box-shadow: none;
72
+ box-shadow: none;
73
+ filter: alpha(opacity=60);
74
+ -khtml-opacity: 0.6;
75
+ -moz-opacity: 0.6;
76
+ opacity: 0.6;
77
+ }
78
+ .ng-table th.filter .input-filter {
79
+ margin: 0;
80
+ display: block;
81
+ width: 100%;
82
+ min-height: 30px;
83
+ -webkit-box-sizing: border-box;
84
+ -moz-box-sizing: border-box;
85
+ box-sizing: border-box;
86
+ }
87
+ .ng-table + .pagination {
88
+ margin-top: 0;
89
+ }
90
+ @media only screen and (max-width: 800px) {
91
+ .ng-table-responsive {
92
+ border-bottom: 1px solid #999999;
93
+ }
94
+ .ng-table-responsive tr {
95
+ border-top: 1px solid #999999;
96
+ border-left: 1px solid #999999;
97
+ border-right: 1px solid #999999;
98
+ }
99
+ .ng-table-responsive td:before {
100
+ position: absolute;
101
+ padding: 8px;
102
+ left: 0;
103
+ top: 0;
104
+ width: 50%;
105
+ white-space: nowrap;
106
+ text-align: left;
107
+ font-weight: bold;
108
+ }
109
+ .ng-table-responsive thead tr th {
110
+ text-align: left;
111
+ }
112
+ .ng-table-responsive thead tr.ng-table-filters th {
113
+ padding: 0;
114
+ }
115
+ .ng-table-responsive thead tr.ng-table-filters th form > div {
116
+ padding: 8px;
117
+ }
118
+ .ng-table-responsive td {
119
+ border: none;
120
+ border-bottom: 1px solid #eeeeee;
121
+ position: relative;
122
+ padding-left: 50%;
123
+ white-space: normal;
124
+ text-align: left;
125
+ }
126
+ .ng-table-responsive td:before {
127
+ content: attr(data-title-text);
128
+ }
129
+ .ng-table-responsive,
130
+ .ng-table-responsive thead,
131
+ .ng-table-responsive tbody,
132
+ .ng-table-responsive th,
133
+ .ng-table-responsive td,
134
+ .ng-table-responsive tr {
135
+ display: block;
136
+ }
137
+ }
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: angular-ng-table-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.4.1
5
+ platform: ruby
6
+ authors:
7
+ - Daniel García-Gil
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-22 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Injects ng-table Rails directives into your asset pipeline.
14
+ email: 'danielgarciagil@gmail.com '
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - MIT-LICENSE
20
+ - README.md
21
+ - lib/angular-ng-table-rails.rb
22
+ - lib/angular-ng-table-rails/version.rb
23
+ - vendor/assets/javascripts/ng-table.js
24
+ - vendor/assets/stylesheets/ng-table.css
25
+ homepage: https://github.com/danielgarciagil/angular-ng-table-rails.git
26
+ licenses:
27
+ - MIT
28
+ metadata: {}
29
+ post_install_message:
30
+ rdoc_options: []
31
+ require_paths:
32
+ - lib
33
+ required_ruby_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ required_rubygems_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ requirements: []
44
+ rubyforge_project:
45
+ rubygems_version: 2.4.6
46
+ signing_key:
47
+ specification_version: 4
48
+ summary: ng-table directive for angular on rails
49
+ test_files: []