faalis 0.26.3 → 1.0.0.alpha0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +35 -6
  3. data/Rakefile +2 -25
  4. data/app/assets/javascripts/faalis/angular-manifest.js +8 -2
  5. data/app/assets/javascripts/faalis/application.js +0 -3
  6. data/app/assets/javascripts/faalis/dashboard/application.js.erb +0 -5
  7. data/app/assets/javascripts/faalis/dashboard/functions.js.erb +9 -0
  8. data/app/assets/javascripts/faalis/dashboard/init.js +1 -1
  9. data/app/assets/javascripts/faalis/dashboard/modules/auth/group.js +0 -6
  10. data/app/assets/javascripts/faalis/dashboard/modules/fields/fields.js +1 -1
  11. data/app/assets/javascripts/faalis/dashboard/modules/fields/image.js +115 -0
  12. data/app/assets/javascripts/faalis/dashboard/modules/fields/tag.js +76 -0
  13. data/app/assets/javascripts/faalis/dashboard/variables.js.erb +1 -1
  14. data/app/assets/locale/templates.pot +282 -0
  15. data/app/assets/stylesheets/faalis/dashboard/dashboard.css.scss +4 -0
  16. data/app/assets/stylesheets/faalis/dashboard/ltr/application.css +4 -4
  17. data/app/assets/stylesheets/faalis/dashboard/rtl/application.css +4 -4
  18. data/app/assets/stylesheets/faalis/dashboard/rtl/base.css.scss.erb +2 -2
  19. data/app/controllers/faalis/api/v1/permissions_controller.rb +8 -39
  20. data/app/controllers/faalis/api/v1/users_controller.rb +7 -7
  21. data/app/models/ability.rb +4 -6
  22. data/app/models/faalis/concerns/assignment.rb +2 -2
  23. data/app/models/faalis/group.rb +18 -4
  24. data/app/models/faalis/permission.rb +11 -2
  25. data/app/models/faalis/permissions/auth.rb +3 -2
  26. data/app/models/faalis/user.rb +27 -73
  27. data/app/models/faalis/user/auth_definitions.rb +94 -0
  28. data/app/models/faalis/user/mongoid_fields.rb +76 -0
  29. data/app/models/faalis/user/permission.rb +21 -0
  30. data/app/views/angularjs_templates/auth/groups/new.html +0 -20
  31. data/app/views/angularjs_templates/fields/image/image.html +1 -0
  32. data/app/views/angularjs_templates/fields/relation/relation.html +3 -1
  33. data/app/views/angularjs_templates/fields/tag/tag.html +1 -0
  34. data/app/views/angularjs_templates/nav.html.erb +0 -1
  35. data/app/views/faalis/api/v1/users/index.json.jbuilder +1 -1
  36. data/app/views/layouts/faalis/application.html.erb +2 -0
  37. data/app/views/layouts/faalis/dashboard.html.erb +1 -0
  38. data/app/views/layouts/faalis/simple.html.erb +1 -0
  39. data/config/initializers/devise.rb +0 -7
  40. data/db/migrate/20131013091000_devise_create_faalis_users.rb +3 -2
  41. data/db/migrate/20140613120923_add_users_groups_table.rb +8 -0
  42. data/db/migrate/20140617124019_faalis_groups_users.rb +4 -0
  43. data/db/seeds.rb +39 -11
  44. data/lib/faalis.rb +5 -4
  45. data/lib/faalis/concerns.rb +7 -0
  46. data/lib/faalis/concerns/authorizable.rb +76 -0
  47. data/lib/faalis/discovery.rb +8 -0
  48. data/lib/faalis/discovery/permissions.rb +51 -0
  49. data/lib/faalis/engine.rb +19 -5
  50. data/lib/faalis/extensions.rb +18 -0
  51. data/lib/faalis/extensions/base.rb +29 -0
  52. data/lib/faalis/fake_assets.rb +7 -0
  53. data/lib/faalis/generators/dashboard_scaffold.rb +23 -5
  54. data/lib/faalis/omniauth.rb +3 -0
  55. data/lib/faalis/orm.rb +29 -0
  56. data/lib/faalis/{active_record.rb → patches/models.rb} +1 -3
  57. data/lib/faalis/version.rb +1 -1
  58. data/lib/generators/faalis/install_generator.rb +7 -3
  59. data/lib/{faalis/plugins.rb → generators/faalis/js/install_i18n_generator.rb} +20 -17
  60. data/lib/generators/faalis/scaffold_generator.rb +139 -0
  61. data/lib/generators/faalis/templates/application.js +1 -1
  62. data/lib/generators/faalis/templates/i18n/Gruntfile.js.erb +30 -0
  63. data/lib/generators/faalis/templates/i18n/README +13 -0
  64. data/lib/generators/faalis/templates/i18n/fa.js +3 -0
  65. data/lib/generators/faalis/templates/js/list_view/README +1 -1
  66. data/lib/tasks/faalis_tasks.rake +26 -20
  67. data/lib/tasks/grunt/Gruntfile.js +7 -2
  68. data/spec/dummy/config/initializers/faalis.rb +40 -0
  69. metadata +134 -44
  70. data/app/assets/javascripts/faalis/dashboard/lib/angular-gettext.js +0 -202
  71. data/app/assets/javascripts/faalis/dashboard/lib/ng-grid.js +0 -3260
  72. data/app/assets/javascripts/faalis/dashboard/lib/ng-quick-date.js +0 -297
  73. data/app/assets/javascripts/faalis/dashboard/lib/restangular.js +0 -1066
  74. data/app/assets/javascripts/faalis/dashboard/lib/select2.js +0 -3255
  75. data/app/assets/javascripts/faalis/dashboard/lib/ui.select2.js +0 -217
  76. data/app/assets/stylesheets/faalis/dashboard/ng-grid.css.scss +0 -442
  77. data/app/assets/stylesheets/faalis/dashboard/ng-quick-date-default-theme.css.scss +0 -20
  78. data/app/assets/stylesheets/faalis/dashboard/ng-quick-date.css.scss +0 -19
  79. data/app/assets/stylesheets/faalis/dashboard/select2.css.scss.erb +0 -618
  80. data/app/controllers/faalis/api/v1/#conversations_controller.rb# +0 -120
  81. data/app/models/faalis/workflow.rb +0 -4
  82. data/db/migrate/20140413180202_create_faalis_workflows.rb +0 -9
  83. data/lib/faalis/permissions.rb +0 -72
  84. data/lib/faalis/workflows.rb +0 -7
  85. data/lib/faalis/workflows/base.rb +0 -70
  86. data/lib/faalis/workflows/discovery.rb +0 -42
  87. data/lib/generators/faalis/js_scaffold_generator.rb +0 -113
@@ -1,202 +0,0 @@
1
- if (typeof jQuery === 'undefined') {
2
- throw new Error('Angular-gettext depends on jQuery, be sure to include it!');
3
- }
4
- angular.module('gettext', []);
5
- angular.module('gettext').factory('gettext', function () {
6
- return function (str) {
7
- return str;
8
- };
9
- });
10
- angular.module('gettext').factory('gettextCatalog', [
11
- 'gettextPlurals',
12
- function (gettextPlurals) {
13
- var catalog;
14
- var prefixDebug = function (string) {
15
- if (catalog.debug && catalog.currentLanguage !== 'en') {
16
- return '[MISSING]: ' + string;
17
- } else {
18
- return string;
19
- }
20
- };
21
- catalog = {
22
- debug: false,
23
- strings: {},
24
- currentLanguage: 'en',
25
- setStrings: function (language, strings) {
26
- var key, val, _results;
27
- if (!this.strings[language]) {
28
- this.strings[language] = {};
29
- }
30
- for (key in strings) {
31
- val = strings[key];
32
- if (typeof val === 'string') {
33
- this.strings[language][key] = [val];
34
- } else {
35
- this.strings[language][key] = val;
36
- }
37
- }
38
- },
39
- getStringForm: function (string, n) {
40
- var stringTable = this.strings[this.currentLanguage] || {};
41
- var plurals = stringTable[string] || [];
42
- return plurals[n];
43
- },
44
- getString: function (string) {
45
- return this.getStringForm(string, 0) || prefixDebug(string);
46
- },
47
- getPlural: function (n, string, stringPlural) {
48
- var form = gettextPlurals(this.currentLanguage, n);
49
- return this.getStringForm(string, form) || prefixDebug(n === 1 ? string : stringPlural);
50
- }
51
- };
52
- return catalog;
53
- }
54
- ]);
55
- angular.module('gettext').directive('translate', [
56
- 'gettextCatalog',
57
- '$interpolate',
58
- '$parse',
59
- function (gettextCatalog, $interpolate, $parse) {
60
- return {
61
- transclude: 'element',
62
- priority: 499,
63
- compile: function (element, attrs, transclude) {
64
- return function ($scope, $element) {
65
- var assert = function (condition, missing, found) {
66
- if (!condition) {
67
- throw new Error('You should add a ' + missing + ' attribute whenever you add a ' + found + ' attribute.');
68
- }
69
- };
70
- assert(!attrs.translatePlural || attrs.translateN, 'translate-n', 'translate-plural');
71
- assert(!attrs.translateN || attrs.translatePlural, 'translate-plural', 'translate-n');
72
- assert(!attrs.ngIf, 'ng-if', 'translate');
73
- assert(!attrs.ngSwitchWhen, 'ng-switch-when', 'translate');
74
- var countFn = $parse(attrs.translateN);
75
- transclude($scope, function (clone) {
76
- var input = $.trim(clone.html());
77
- clone.removeAttr('translate');
78
- $element.replaceWith(clone);
79
- return $scope.$watch(function () {
80
- var prev = clone.html();
81
- var translated;
82
- if (attrs.translatePlural) {
83
- translated = gettextCatalog.getPlural(countFn($scope), input, attrs.translatePlural);
84
- } else {
85
- translated = gettextCatalog.getString(input);
86
- }
87
- var interpolated = $interpolate(translated)($scope);
88
- if (prev === interpolated) {
89
- return;
90
- }
91
- return clone.html(interpolated);
92
- });
93
- });
94
- };
95
- }
96
- };
97
- }
98
- ]);
99
- angular.module('gettext').filter('translate', [
100
- 'gettextCatalog',
101
- '$interpolate',
102
- '$parse',
103
- function (gettextCatalog, $interpolate, $parse) {
104
- return function (input) {
105
- return gettextCatalog.getString(input);
106
- };
107
- }
108
- ]);
109
- angular.module('gettext').factory('gettextPlurals', function () {
110
- return function (langCode, n) {
111
- switch (langCode) {
112
- case 'ay':
113
- case 'bo':
114
- case 'cgg':
115
- case 'dz':
116
- case 'fa':
117
- case 'id':
118
- case 'ja':
119
- case 'jbo':
120
- case 'ka':
121
- case 'kk':
122
- case 'km':
123
- case 'ko':
124
- case 'ky':
125
- case 'lo':
126
- case 'ms':
127
- case 'my':
128
- case 'sah':
129
- case 'su':
130
- case 'th':
131
- case 'tt':
132
- case 'ug':
133
- case 'vi':
134
- case 'wo':
135
- case 'zh':
136
- return 0;
137
- case 'is':
138
- return n % 10 != 1 || n % 100 == 11 ? 1 : 0;
139
- case 'jv':
140
- return n != 0 ? 1 : 0;
141
- case 'mk':
142
- return n == 1 || n % 10 == 1 ? 0 : 1;
143
- case 'ach':
144
- case 'ak':
145
- case 'am':
146
- case 'arn':
147
- case 'br':
148
- case 'fil':
149
- case 'fr':
150
- case 'gun':
151
- case 'ln':
152
- case 'mfe':
153
- case 'mg':
154
- case 'mi':
155
- case 'oc':
156
- case 'pt_BR':
157
- case 'tg':
158
- case 'ti':
159
- case 'tr':
160
- case 'uz':
161
- case 'wa':
162
- case 'zh':
163
- return n > 1 ? 1 : 0;
164
- case 'lv':
165
- return n % 10 == 1 && n % 100 != 11 ? 0 : n != 0 ? 1 : 2;
166
- case 'lt':
167
- return n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2;
168
- case 'be':
169
- case 'bs':
170
- case 'hr':
171
- case 'ru':
172
- case 'sr':
173
- case 'uk':
174
- return n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2;
175
- case 'mnk':
176
- return n == 0 ? 0 : n == 1 ? 1 : 2;
177
- case 'ro':
178
- return n == 1 ? 0 : n == 0 || n % 100 > 0 && n % 100 < 20 ? 1 : 2;
179
- case 'pl':
180
- return n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2;
181
- case 'cs':
182
- case 'sk':
183
- return n == 1 ? 0 : n >= 2 && n <= 4 ? 1 : 2;
184
- case 'sl':
185
- return n % 100 == 1 ? 1 : n % 100 == 2 ? 2 : n % 100 == 3 || n % 100 == 4 ? 3 : 0;
186
- case 'mt':
187
- return n == 1 ? 0 : n == 0 || n % 100 > 1 && n % 100 < 11 ? 1 : n % 100 > 10 && n % 100 < 20 ? 2 : 3;
188
- case 'gd':
189
- return n == 1 || n == 11 ? 0 : n == 2 || n == 12 ? 1 : n > 2 && n < 20 ? 2 : 3;
190
- case 'cy':
191
- return n == 1 ? 0 : n == 2 ? 1 : n != 8 && n != 11 ? 2 : 3;
192
- case 'kw':
193
- return n == 1 ? 0 : n == 2 ? 1 : n == 3 ? 2 : 3;
194
- case 'ga':
195
- return n == 1 ? 0 : n == 2 ? 1 : n < 7 ? 2 : n < 11 ? 3 : 4;
196
- case 'ar':
197
- return n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;
198
- default:
199
- return n != 1 ? 1 : 0;
200
- }
201
- };
202
- });
@@ -1,3260 +0,0 @@
1
- /***********************************************
2
- * ng-grid JavaScript Library
3
- * Authors: https://github.com/angular-ui/ng-grid/blob/master/README.md
4
- * License: MIT (http://www.opensource.org/licenses/mit-license.php)
5
- * Compiled At: 07/06/2013 13:50
6
- ***********************************************/
7
- (function(window, $) {
8
- 'use strict';
9
-
10
- var EXCESS_ROWS = 6;
11
- var SCROLL_THRESHOLD = 4;
12
- var ASC = "asc";
13
-
14
- var DESC = "desc";
15
-
16
- var NG_FIELD = '_ng_field_';
17
- var NG_DEPTH = '_ng_depth_';
18
- var NG_HIDDEN = '_ng_hidden_';
19
- var NG_COLUMN = '_ng_column_';
20
- var CUSTOM_FILTERS = /CUSTOM_FILTERS/g;
21
- var COL_FIELD = /COL_FIELD/g;
22
- var DISPLAY_CELL_TEMPLATE = /DISPLAY_CELL_TEMPLATE/g;
23
- var EDITABLE_CELL_TEMPLATE = /EDITABLE_CELL_TEMPLATE/g;
24
- var TEMPLATE_REGEXP = /<.+>/;
25
- window.ngGrid = {};
26
- window.ngGrid.i18n = {};
27
- var ngGridServices = angular.module('ngGrid.services', []);
28
- var ngGridDirectives = angular.module('ngGrid.directives', []);
29
- var ngGridFilters = angular.module('ngGrid.filters', []);
30
-
31
- angular.module('ngGrid', ['ngGrid.services', 'ngGrid.directives', 'ngGrid.filters']);
32
-
33
- var ngMoveSelectionHandler = function($scope, elm, evt, grid) {
34
- if ($scope.selectionProvider.selectedItems === undefined) {
35
- return true;
36
- }
37
-
38
- var charCode = evt.which || evt.keyCode,
39
- newColumnIndex,
40
- lastInRow = false,
41
- firstInRow = false,
42
- rowIndex = $scope.selectionProvider.lastClickedRow === undefined ? 1 : $scope.selectionProvider.lastClickedRow.rowIndex,
43
- visibleCols = $scope.columns.filter(function(c) { return c.visible; }),
44
- pinnedCols = $scope.columns.filter(function(c) { return c.pinned; });
45
-
46
- if ($scope.col) {
47
- newColumnIndex = visibleCols.indexOf($scope.col);
48
- }
49
-
50
- if (charCode !== 37 && charCode !== 38 && charCode !== 39 && charCode !== 40 && charCode !== 9 && charCode !== 13) {
51
- return true;
52
- }
53
- if ($scope.enableCellSelection) {
54
- if (charCode === 9) {
55
- evt.preventDefault();
56
- }
57
-
58
- var focusedOnFirstColumn = $scope.showSelectionCheckbox ? $scope.col.index === 1 : $scope.col.index === 0;
59
- var focusedOnFirstVisibleColumns = $scope.$index === 1 || $scope.$index === 0;
60
- var focusedOnLastVisibleColumns = $scope.$index === ($scope.renderedColumns.length - 1) || $scope.$index === ($scope.renderedColumns.length - 2);
61
- var focusedOnLastColumn = visibleCols.indexOf($scope.col) === (visibleCols.length - 1);
62
- var focusedOnLastPinnedColumn = pinnedCols.indexOf($scope.col) === (pinnedCols.length - 1);
63
- if (charCode === 37 || charCode === 9 && evt.shiftKey) {
64
- var scrollTo = 0;
65
-
66
- if (!focusedOnFirstColumn) {
67
- newColumnIndex -= 1;
68
- }
69
-
70
- if (focusedOnFirstVisibleColumns) {
71
- if (focusedOnFirstColumn && charCode === 9 && evt.shiftKey){
72
- scrollTo = grid.$canvas.width();
73
- newColumnIndex = visibleCols.length - 1;
74
- firstInRow = true;
75
- }
76
- else {
77
- scrollTo = grid.$viewport.scrollLeft() - $scope.col.width;
78
- }
79
- }
80
- else if (pinnedCols.length > 0) {
81
- scrollTo = grid.$viewport.scrollLeft() - visibleCols[newColumnIndex].width;
82
- }
83
-
84
- grid.$viewport.scrollLeft(scrollTo);
85
- }
86
- else if (charCode === 39 || charCode === 9 && !evt.shiftKey) {
87
- if (focusedOnLastVisibleColumns) {
88
- if (focusedOnLastColumn && charCode === 9 && !evt.shiftKey) {
89
- grid.$viewport.scrollLeft(0);
90
- newColumnIndex = $scope.showSelectionCheckbox ? 1 : 0;
91
- lastInRow = true;
92
- }
93
- else {
94
- grid.$viewport.scrollLeft(grid.$viewport.scrollLeft() + $scope.col.width);
95
- }
96
- }
97
- else if (focusedOnLastPinnedColumn) {
98
- grid.$viewport.scrollLeft(0);
99
- }
100
-
101
- if (!focusedOnLastColumn) {
102
- newColumnIndex += 1;
103
- }
104
- }
105
- }
106
- var items;
107
- if ($scope.configGroups.length > 0) {
108
- items = grid.rowFactory.parsedData.filter(function (row) {
109
- return !row.isAggRow;
110
- });
111
- }
112
- else {
113
- items = grid.filteredRows;
114
- }
115
- var offset = 0;
116
- if (rowIndex !== 0 && (charCode === 38 || charCode === 13 && evt.shiftKey || charCode === 9 && evt.shiftKey && firstInRow)) {
117
- offset = -1;
118
- }
119
- else if (rowIndex !== items.length - 1 && (charCode === 40 || charCode === 13 && !evt.shiftKey || charCode === 9 && lastInRow)) {
120
- offset = 1;
121
- }
122
- if (offset) {
123
- var r = items[rowIndex + offset];
124
- if (r.beforeSelectionChange(r, evt)) {
125
- r.continueSelection(evt);
126
- $scope.$emit('ngGridEventDigestGridParent');
127
-
128
- if ($scope.selectionProvider.lastClickedRow.renderedRowIndex >= $scope.renderedRows.length - EXCESS_ROWS - 2) {
129
- grid.$viewport.scrollTop(grid.$viewport.scrollTop() + $scope.rowHeight);
130
- }
131
- else if ($scope.selectionProvider.lastClickedRow.renderedRowIndex <= EXCESS_ROWS + 2) {
132
- grid.$viewport.scrollTop(grid.$viewport.scrollTop() - $scope.rowHeight);
133
- }
134
- }
135
- }
136
- if ($scope.enableCellSelection) {
137
- setTimeout(function(){
138
- $scope.domAccessProvider.focusCellElement($scope, $scope.renderedColumns.indexOf(visibleCols[newColumnIndex]));
139
- }, 3);
140
- }
141
-
142
- return false;
143
- };
144
-
145
- if (!String.prototype.trim) {
146
- String.prototype.trim = function() {
147
- return this.replace(/^\s+|\s+$/g, '');
148
- };
149
- }
150
- if (!Array.prototype.indexOf) {
151
- Array.prototype.indexOf = function(elt ) {
152
- var len = this.length >>> 0;
153
- var from = Number(arguments[1]) || 0;
154
- from = (from < 0) ? Math.ceil(from) : Math.floor(from);
155
- if (from < 0) {
156
- from += len;
157
- }
158
- for (; from < len; from++) {
159
- if (from in this && this[from] === elt) {
160
- return from;
161
- }
162
- }
163
- return -1;
164
- };
165
- }
166
- if (!Array.prototype.filter) {
167
- Array.prototype.filter = function(fun ) {
168
- "use strict";
169
- var t = Object(this);
170
- var len = t.length >>> 0;
171
- if (typeof fun !== "function") {
172
- throw new TypeError();
173
- }
174
- var res = [];
175
- var thisp = arguments[1];
176
- for (var i = 0; i < len; i++) {
177
- if (i in t) {
178
- var val = t[i];
179
- if (fun.call(thisp, val, i, t)) {
180
- res.push(val);
181
- }
182
- }
183
- }
184
- return res;
185
- };
186
- }
187
- ngGridFilters.filter('checkmark', function() {
188
- return function(input) {
189
- return input ? '\u2714' : '\u2718';
190
- };
191
- });
192
- ngGridFilters.filter('ngColumns', function() {
193
- return function(input) {
194
- return input.filter(function(col) {
195
- return !col.isAggCol;
196
- });
197
- };
198
- });
199
- angular.module('ngGrid.services').factory('$domUtilityService',['$utilityService', function($utils) {
200
- var domUtilityService = {};
201
- var regexCache = {};
202
- var getWidths = function() {
203
- var $testContainer = $('<div></div>');
204
- $testContainer.appendTo('body');
205
- $testContainer.height(100).width(100).css("position", "absolute").css("overflow", "scroll");
206
- $testContainer.append('<div style="height: 400px; width: 400px;"></div>');
207
- domUtilityService.ScrollH = ($testContainer.height() - $testContainer[0].clientHeight);
208
- domUtilityService.ScrollW = ($testContainer.width() - $testContainer[0].clientWidth);
209
- $testContainer.empty();
210
- $testContainer.attr('style', '');
211
- $testContainer.append('<span style="font-family: Verdana, Helvetica, Sans-Serif; font-size: 14px;"><strong>M</strong></span>');
212
- domUtilityService.LetterW = $testContainer.children().first().width();
213
- $testContainer.remove();
214
- };
215
- domUtilityService.eventStorage = {};
216
- domUtilityService.AssignGridContainers = function($scope, rootEl, grid) {
217
- grid.$root = $(rootEl);
218
- grid.$topPanel = grid.$root.find(".ngTopPanel");
219
- grid.$groupPanel = grid.$root.find(".ngGroupPanel");
220
- grid.$headerContainer = grid.$topPanel.find(".ngHeaderContainer");
221
- $scope.$headerContainer = grid.$headerContainer;
222
-
223
- grid.$headerScroller = grid.$topPanel.find(".ngHeaderScroller");
224
- grid.$headers = grid.$headerScroller.children();
225
- grid.$viewport = grid.$root.find(".ngViewport");
226
- grid.$canvas = grid.$viewport.find(".ngCanvas");
227
- grid.$footerPanel = grid.$root.find(".ngFooterPanel");
228
- $scope.$watch(function () {
229
- return grid.$viewport.scrollLeft();
230
- }, function (newLeft) {
231
- return grid.$headerContainer.scrollLeft(newLeft);
232
- });
233
- domUtilityService.UpdateGridLayout($scope, grid);
234
- };
235
- domUtilityService.getRealWidth = function (obj) {
236
- var width = 0;
237
- var props = { visibility: "hidden", display: "block" };
238
- var hiddenParents = obj.parents().andSelf().not(':visible');
239
- $.swap(hiddenParents[0], props, function () {
240
- width = obj.outerWidth();
241
- });
242
- return width;
243
- };
244
- domUtilityService.UpdateGridLayout = function($scope, grid) {
245
- var scrollTop = grid.$viewport.scrollTop();
246
- grid.elementDims.rootMaxW = grid.$root.width();
247
- if (grid.$root.is(':hidden')) {
248
- grid.elementDims.rootMaxW = domUtilityService.getRealWidth(grid.$root);
249
- }
250
- grid.elementDims.rootMaxH = grid.$root.height();
251
- grid.refreshDomSizes();
252
- $scope.adjustScrollTop(scrollTop, true);
253
- };
254
- domUtilityService.numberOfGrids = 0;
255
- domUtilityService.BuildStyles = function($scope, grid, digest) {
256
- var rowHeight = grid.config.rowHeight,
257
- $style = grid.$styleSheet,
258
- gridId = grid.gridId,
259
- css,
260
- cols = $scope.columns,
261
- sumWidth = 0;
262
-
263
- if (!$style) {
264
- $style = $('#' + gridId);
265
- if (!$style[0]) {
266
- $style = $("<style id='" + gridId + "' type='text/css' rel='stylesheet' />").appendTo(grid.$root);
267
- }
268
- }
269
- $style.empty();
270
- var trw = $scope.totalRowWidth();
271
- css = "." + gridId + " .ngCanvas { width: " + trw + "px; }" +
272
- "." + gridId + " .ngRow { width: " + trw + "px; }" +
273
- "." + gridId + " .ngCanvas { width: " + trw + "px; }" +
274
- "." + gridId + " .ngHeaderScroller { width: " + (trw + domUtilityService.ScrollH) + "px}";
275
-
276
- for (var i = 0; i < cols.length; i++) {
277
- var col = cols[i];
278
- if (col.visible !== false) {
279
- css += "." + gridId + " .col" + i + " { width: " + col.width + "px; left: " + sumWidth + "px; height: " + rowHeight + "px }" +
280
- "." + gridId + " .colt" + i + " { width: " + col.width + "px; }";
281
- sumWidth += col.width;
282
- }
283
- }
284
-
285
- if ($utils.isIe) {
286
- $style[0].styleSheet.cssText = css;
287
- }
288
-
289
- else {
290
- $style[0].appendChild(document.createTextNode(css));
291
- }
292
-
293
- grid.$styleSheet = $style;
294
- $scope.adjustScrollLeft(grid.$viewport.scrollLeft());
295
- if (digest) {
296
- domUtilityService.digest($scope);
297
- }
298
- };
299
- domUtilityService.setColLeft = function(col, colLeft, grid) {
300
- if (grid.$styleSheet) {
301
- var regex = regexCache[col.index];
302
- if (!regex) {
303
- regex = regexCache[col.index] = new RegExp(".col" + col.index + " { width: [0-9]+px; left: [0-9]+px");
304
- }
305
- var str = grid.$styleSheet.html();
306
- var newStr = str.replace(regex, ".col" + col.index + " { width: " + col.width + "px; left: " + colLeft + "px");
307
- if ($utils.isIe) {
308
- setTimeout(function() {
309
- grid.$styleSheet.html(newStr);
310
- });
311
- }
312
- else {
313
- grid.$styleSheet.html(newStr);
314
- }
315
- }
316
- };
317
- domUtilityService.setColLeft.immediate = 1;
318
- domUtilityService.RebuildGrid = function($scope, grid){
319
- domUtilityService.UpdateGridLayout($scope, grid);
320
- if (grid.config.maintainColumnRatios == null || grid.config.maintainColumnRatios) {
321
- grid.configureColumnWidths();
322
- }
323
- $scope.adjustScrollLeft(grid.$viewport.scrollLeft());
324
- domUtilityService.BuildStyles($scope, grid, true);
325
- };
326
-
327
- domUtilityService.digest = function($scope) {
328
- if (!$scope.$root.$$phase) {
329
- $scope.$digest();
330
- }
331
- };
332
- domUtilityService.ScrollH = 17;
333
- domUtilityService.ScrollW = 17;
334
- domUtilityService.LetterW = 10;
335
- getWidths();
336
- return domUtilityService;
337
- }]);
338
- angular.module('ngGrid.services').factory('$sortService', ['$parse', function($parse) {
339
- var sortService = {};
340
- sortService.colSortFnCache = {};
341
- sortService.guessSortFn = function(item) {
342
- var itemType = typeof(item);
343
- switch (itemType) {
344
- case "number":
345
- return sortService.sortNumber;
346
- case "boolean":
347
- return sortService.sortBool;
348
- case "string":
349
- return item.match(/^[-+]?[£$¤]?[\d,.]+%?$/) ? sortService.sortNumberStr : sortService.sortAlpha;
350
- default:
351
- if (Object.prototype.toString.call(item) === '[object Date]') {
352
- return sortService.sortDate;
353
- }
354
- else {
355
- return sortService.basicSort;
356
- }
357
- }
358
- };
359
- sortService.basicSort = function(a, b) {
360
- if (a === b) {
361
- return 0;
362
- }
363
- if (a < b) {
364
- return -1;
365
- }
366
- return 1;
367
- };
368
- sortService.sortNumber = function(a, b) {
369
- return a - b;
370
- };
371
- sortService.sortNumberStr = function(a, b) {
372
- var numA, numB, badA = false, badB = false;
373
- numA = parseFloat(a.replace(/[^0-9.-]/g, ''));
374
- if (isNaN(numA)) {
375
- badA = true;
376
- }
377
- numB = parseFloat(b.replace(/[^0-9.-]/g, ''));
378
- if (isNaN(numB)) {
379
- badB = true;
380
- }
381
- if (badA && badB) {
382
- return 0;
383
- }
384
- if (badA) {
385
- return 1;
386
- }
387
- if (badB) {
388
- return -1;
389
- }
390
- return numA - numB;
391
- };
392
- sortService.sortAlpha = function(a, b) {
393
- var strA = a.toLowerCase(),
394
- strB = b.toLowerCase();
395
- return strA === strB ? 0 : (strA < strB ? -1 : 1);
396
- };
397
- sortService.sortDate = function(a, b) {
398
- var timeA = a.getTime(),
399
- timeB = b.getTime();
400
- return timeA === timeB ? 0 : (timeA < timeB ? -1 : 1);
401
- };
402
- sortService.sortBool = function(a, b) {
403
- if (a && b) {
404
- return 0;
405
- }
406
- if (!a && !b) {
407
- return 0;
408
- } else {
409
- return a ? 1 : -1;
410
- }
411
- };
412
- sortService.sortData = function(sortInfo, data ) {
413
- if (!data || !sortInfo) {
414
- return;
415
- }
416
- var l = sortInfo.fields.length,
417
- order = sortInfo.fields,
418
- col,
419
- direction,
420
- d = data.slice(0);
421
- data.sort(function (itemA, itemB) {
422
- var tem = 0,
423
- indx = 0,
424
- sortFn;
425
- while (tem === 0 && indx < l) {
426
- col = sortInfo.columns[indx];
427
- direction = sortInfo.directions[indx];
428
- sortFn = sortService.getSortFn(col, d);
429
- var propA = $parse(order[indx])(itemA);
430
- var propB = $parse(order[indx])(itemB);
431
- if ((!propA && propA !== 0) || (!propB && propB !== 0)) {
432
- if (!propB && !propA) {
433
- tem = 0;
434
- }
435
- else if (!propA) {
436
- tem = 1;
437
- }
438
- else if (!propB) {
439
- tem = -1;
440
- }
441
- }
442
- else {
443
- tem = sortFn(propA, propB);
444
- }
445
- indx++;
446
- }
447
- if (direction === ASC) {
448
- return tem;
449
- } else {
450
- return 0 - tem;
451
- }
452
- });
453
- };
454
- sortService.Sort = function(sortInfo, data) {
455
- if (sortService.isSorting) {
456
- return;
457
- }
458
- sortService.isSorting = true;
459
- sortService.sortData(sortInfo, data);
460
- sortService.isSorting = false;
461
- };
462
- sortService.getSortFn = function(col, data) {
463
- var sortFn, item;
464
- if (sortService.colSortFnCache[col.field]) {
465
- sortFn = sortService.colSortFnCache[col.field];
466
- }
467
- else if (col.sortingAlgorithm !== undefined) {
468
- sortFn = col.sortingAlgorithm;
469
- sortService.colSortFnCache[col.field] = col.sortingAlgorithm;
470
- }
471
- else {
472
- item = data[0];
473
- if (!item) {
474
- return sortFn;
475
- }
476
- sortFn = sortService.guessSortFn($parse(col.field)(item));
477
- if (sortFn) {
478
- sortService.colSortFnCache[col.field] = sortFn;
479
- } else {
480
- sortFn = sortService.sortAlpha;
481
- }
482
- }
483
- return sortFn;
484
- };
485
- return sortService;
486
- }]);
487
-
488
- angular.module('ngGrid.services').factory('$utilityService', ['$parse', function ($parse) {
489
- var funcNameRegex = /function (.{1,})\(/;
490
- var utils = {
491
- visualLength: function(node) {
492
- var elem = document.getElementById('testDataLength');
493
- if (!elem) {
494
- elem = document.createElement('SPAN');
495
- elem.id = "testDataLength";
496
- elem.style.visibility = "hidden";
497
- document.body.appendChild(elem);
498
- }
499
- $(elem).css('font', $(node).css('font'));
500
- $(elem).css('font-size', $(node).css('font-size'));
501
- $(elem).css('font-family', $(node).css('font-family'));
502
- elem.innerHTML = $(node).text();
503
- return elem.offsetWidth;
504
- },
505
- forIn: function(obj, action) {
506
- for (var prop in obj) {
507
- if (obj.hasOwnProperty(prop)) {
508
- action(obj[prop], prop);
509
- }
510
- }
511
- },
512
- evalProperty: function (entity, path) {
513
- return $parse(path)(entity);
514
- },
515
- endsWith: function(str, suffix) {
516
- if (!str || !suffix || typeof str !== "string") {
517
- return false;
518
- }
519
- return str.indexOf(suffix, str.length - suffix.length) !== -1;
520
- },
521
- isNullOrUndefined: function(obj) {
522
- if (obj === undefined || obj === null) {
523
- return true;
524
- }
525
- return false;
526
- },
527
- getElementsByClassName: function(cl) {
528
- var retnode = [];
529
- var myclass = new RegExp('\\b' + cl + '\\b');
530
- var elem = document.getElementsByTagName('*');
531
- for (var i = 0; i < elem.length; i++) {
532
- var classes = elem[i].className;
533
- if (myclass.test(classes)) {
534
- retnode.push(elem[i]);
535
- }
536
- }
537
- return retnode;
538
- },
539
- newId: (function() {
540
- var seedId = new Date().getTime();
541
- return function() {
542
- return seedId += 1;
543
- };
544
- })(),
545
- seti18n: function($scope, language) {
546
- var $langPack = window.ngGrid.i18n[language];
547
- for (var label in $langPack) {
548
- $scope.i18n[label] = $langPack[label];
549
- }
550
- },
551
- getInstanceType: function (o) {
552
- var results = (funcNameRegex).exec(o.constructor.toString());
553
- if (results && results.length > 1) {
554
- var instanceType = results[1].replace(/^\s+|\s+$/g, "");
555
- return instanceType;
556
- }
557
- else {
558
- return "";
559
- }
560
- },
561
- ieVersion: (function() {
562
- var version = 3, div = document.createElement('div'), iElems = div.getElementsByTagName('i');
563
- do{
564
- div.innerHTML = '<!--[if gt IE ' + (++version) + ']><i></i><![endif]-->';
565
- }while(iElems[0]);
566
- return version > 4 ? version : undefined;
567
- })()
568
- };
569
-
570
- $.extend(utils, {
571
- isIe: (function() {
572
- return utils.ieVersion !== undefined;
573
- })()
574
- });
575
- return utils;
576
- }]);
577
-
578
- var ngAggregate = function (aggEntity, rowFactory, rowHeight, groupInitState) {
579
- this.rowIndex = 0;
580
- this.offsetTop = this.rowIndex * rowHeight;
581
- this.entity = aggEntity;
582
- this.label = aggEntity.gLabel;
583
- this.field = aggEntity.gField;
584
- this.depth = aggEntity.gDepth;
585
- this.parent = aggEntity.parent;
586
- this.children = aggEntity.children;
587
- this.aggChildren = aggEntity.aggChildren;
588
- this.aggIndex = aggEntity.aggIndex;
589
- this.collapsed = groupInitState;
590
- this.groupInitState = groupInitState;
591
- this.rowFactory = rowFactory;
592
- this.rowHeight = rowHeight;
593
- this.isAggRow = true;
594
- this.offsetLeft = aggEntity.gDepth * 25;
595
- this.aggLabelFilter = aggEntity.aggLabelFilter;
596
- };
597
-
598
- ngAggregate.prototype.toggleExpand = function () {
599
- this.collapsed = this.collapsed ? false : true;
600
- if (this.orig) {
601
- this.orig.collapsed = this.collapsed;
602
- }
603
- this.notifyChildren();
604
- };
605
- ngAggregate.prototype.setExpand = function (state) {
606
- this.collapsed = state;
607
- this.notifyChildren();
608
- };
609
- ngAggregate.prototype.notifyChildren = function () {
610
- var longest = Math.max(this.rowFactory.aggCache.length, this.children.length);
611
- for (var i = 0; i < longest; i++) {
612
- if (this.aggChildren[i]) {
613
- this.aggChildren[i].entity[NG_HIDDEN] = this.collapsed;
614
- if (this.collapsed) {
615
- this.aggChildren[i].setExpand(this.collapsed);
616
- }
617
- }
618
- if (this.children[i]) {
619
- this.children[i][NG_HIDDEN] = this.collapsed;
620
- }
621
- if (i > this.aggIndex && this.rowFactory.aggCache[i]) {
622
- var agg = this.rowFactory.aggCache[i];
623
- var offset = (30 * this.children.length);
624
- agg.offsetTop = this.collapsed ? agg.offsetTop - offset : agg.offsetTop + offset;
625
- }
626
- }
627
- this.rowFactory.renderedChange();
628
- };
629
- ngAggregate.prototype.aggClass = function () {
630
- return this.collapsed ? "ngAggArrowCollapsed" : "ngAggArrowExpanded";
631
- };
632
- ngAggregate.prototype.totalChildren = function () {
633
- if (this.aggChildren.length > 0) {
634
- var i = 0;
635
- var recurse = function (cur) {
636
- if (cur.aggChildren.length > 0) {
637
- angular.forEach(cur.aggChildren, function (a) {
638
- recurse(a);
639
- });
640
- } else {
641
- i += cur.children.length;
642
- }
643
- };
644
- recurse(this);
645
- return i;
646
- } else {
647
- return this.children.length;
648
- }
649
- };
650
- ngAggregate.prototype.copy = function () {
651
- var ret = new ngAggregate(this.entity, this.rowFactory, this.rowHeight, this.groupInitState);
652
- ret.orig = this;
653
- return ret;
654
- };
655
- var ngColumn = function (config, $scope, grid, domUtilityService, $templateCache, $utils) {
656
- var self = this,
657
- colDef = config.colDef,
658
- delay = 500,
659
- clicks = 0,
660
- timer = null;
661
- self.colDef = config.colDef;
662
- self.width = colDef.width;
663
- self.groupIndex = 0;
664
- self.isGroupedBy = false;
665
- self.minWidth = !colDef.minWidth ? 50 : colDef.minWidth;
666
- self.maxWidth = !colDef.maxWidth ? 9000 : colDef.maxWidth;
667
- self.enableCellEdit = colDef.enableCellEdit !== undefined ? colDef.enableCellEdit : (config.enableCellEdit || config.enableCellEditOnFocus);
668
-
669
- self.headerRowHeight = config.headerRowHeight;
670
- self.displayName = (colDef.displayName === undefined) ? colDef.field : colDef.displayName;
671
-
672
- self.index = config.index;
673
- self.isAggCol = config.isAggCol;
674
- self.cellClass = colDef.cellClass;
675
- self.sortPriority = undefined;
676
- self.cellFilter = colDef.cellFilter ? colDef.cellFilter : "";
677
- self.field = colDef.field;
678
- self.aggLabelFilter = colDef.cellFilter || colDef.aggLabelFilter;
679
- self.visible = $utils.isNullOrUndefined(colDef.visible) || colDef.visible;
680
- self.sortable = false;
681
- self.resizable = false;
682
- self.pinnable = false;
683
- self.pinned = (config.enablePinning && colDef.pinned);
684
- self.originalIndex = config.originalIndex == null ? self.index : config.originalIndex;
685
- self.groupable = $utils.isNullOrUndefined(colDef.groupable) || colDef.groupable;
686
- if (config.enableSort) {
687
- self.sortable = $utils.isNullOrUndefined(colDef.sortable) || colDef.sortable;
688
- }
689
- if (config.enableResize) {
690
- self.resizable = $utils.isNullOrUndefined(colDef.resizable) || colDef.resizable;
691
- }
692
- if (config.enablePinning) {
693
- self.pinnable = $utils.isNullOrUndefined(colDef.pinnable) || colDef.pinnable;
694
- }
695
- self.sortDirection = undefined;
696
- self.sortingAlgorithm = colDef.sortFn;
697
- self.headerClass = colDef.headerClass;
698
- self.cursor = self.sortable ? 'pointer' : 'default';
699
- self.headerCellTemplate = colDef.headerCellTemplate || $templateCache.get('headerCellTemplate.html');
700
- self.cellTemplate = colDef.cellTemplate || $templateCache.get('cellTemplate.html').replace(CUSTOM_FILTERS, self.cellFilter ? "|" + self.cellFilter : "");
701
- if(self.enableCellEdit) {
702
- self.cellEditTemplate = $templateCache.get('cellEditTemplate.html');
703
- self.editableCellTemplate = colDef.editableCellTemplate || $templateCache.get('editableCellTemplate.html');
704
- }
705
- if (colDef.cellTemplate && !TEMPLATE_REGEXP.test(colDef.cellTemplate)) {
706
- self.cellTemplate = $.ajax({
707
- type: "GET",
708
- url: colDef.cellTemplate,
709
- async: false
710
- }).responseText;
711
- }
712
- if (self.enableCellEdit && colDef.editableCellTemplate && !TEMPLATE_REGEXP.test(colDef.editableCellTemplate)) {
713
- self.editableCellTemplate = $.ajax({
714
- type: "GET",
715
- url: colDef.editableCellTemplate,
716
- async: false
717
- }).responseText;
718
- }
719
- if (colDef.headerCellTemplate && !TEMPLATE_REGEXP.test(colDef.headerCellTemplate)) {
720
- self.headerCellTemplate = $.ajax({
721
- type: "GET",
722
- url: colDef.headerCellTemplate,
723
- async: false
724
- }).responseText;
725
- }
726
- self.colIndex = function () {
727
- var classes = self.pinned ? "pinned " : "";
728
- classes += "col" + self.index + " colt" + self.index;
729
- if (self.cellClass) {
730
- classes += " " + self.cellClass;
731
- }
732
- return classes;
733
- };
734
- self.groupedByClass = function() {
735
- return self.isGroupedBy ? "ngGroupedByIcon" : "ngGroupIcon";
736
- };
737
- self.toggleVisible = function() {
738
- self.visible = !self.visible;
739
- };
740
- self.showSortButtonUp = function() {
741
- return self.sortable ? self.sortDirection === DESC : self.sortable;
742
- };
743
- self.showSortButtonDown = function() {
744
- return self.sortable ? self.sortDirection === ASC : self.sortable;
745
- };
746
- self.noSortVisible = function() {
747
- return !self.sortDirection;
748
- };
749
- self.sort = function(evt) {
750
- if (!self.sortable) {
751
- return true;
752
- }
753
- var dir = self.sortDirection === ASC ? DESC : ASC;
754
- self.sortDirection = dir;
755
- config.sortCallback(self, evt);
756
- return false;
757
- };
758
- self.gripClick = function() {
759
- clicks++;
760
- if (clicks === 1) {
761
- timer = setTimeout(function() {
762
- clicks = 0;
763
- }, delay);
764
- } else {
765
- clearTimeout(timer);
766
- config.resizeOnDataCallback(self);
767
- clicks = 0;
768
- }
769
- };
770
- self.gripOnMouseDown = function(event) {
771
- $scope.isColumnResizing = true;
772
- if (event.ctrlKey && !self.pinned) {
773
- self.toggleVisible();
774
- domUtilityService.BuildStyles($scope, grid);
775
- return true;
776
- }
777
- event.target.parentElement.style.cursor = 'col-resize';
778
- self.startMousePosition = event.clientX;
779
- self.origWidth = self.width;
780
- $(document).mousemove(self.onMouseMove);
781
- $(document).mouseup(self.gripOnMouseUp);
782
- return false;
783
- };
784
- self.onMouseMove = function(event) {
785
- var diff = event.clientX - self.startMousePosition;
786
- var newWidth = diff + self.origWidth;
787
- self.width = (newWidth < self.minWidth ? self.minWidth : (newWidth > self.maxWidth ? self.maxWidth : newWidth));
788
- $scope.hasUserChangedGridColumnWidths = true;
789
- domUtilityService.BuildStyles($scope, grid);
790
- return false;
791
- };
792
- self.gripOnMouseUp = function (event) {
793
- $(document).off('mousemove', self.onMouseMove);
794
- $(document).off('mouseup', self.gripOnMouseUp);
795
- event.target.parentElement.style.cursor = 'default';
796
- domUtilityService.digest($scope);
797
- $scope.isColumnResizing = false;
798
- return false;
799
- };
800
- self.copy = function() {
801
- var ret = new ngColumn(config, $scope, grid, domUtilityService, $templateCache);
802
- ret.isClone = true;
803
- ret.orig = self;
804
- return ret;
805
- };
806
- self.setVars = function (fromCol) {
807
- self.orig = fromCol;
808
- self.width = fromCol.width;
809
- self.groupIndex = fromCol.groupIndex;
810
- self.isGroupedBy = fromCol.isGroupedBy;
811
- self.displayName = fromCol.displayName;
812
- self.index = fromCol.index;
813
- self.isAggCol = fromCol.isAggCol;
814
- self.cellClass = fromCol.cellClass;
815
- self.cellFilter = fromCol.cellFilter;
816
- self.field = fromCol.field;
817
- self.aggLabelFilter = fromCol.aggLabelFilter;
818
- self.visible = fromCol.visible;
819
- self.sortable = fromCol.sortable;
820
- self.resizable = fromCol.resizable;
821
- self.pinnable = fromCol.pinnable;
822
- self.pinned = fromCol.pinned;
823
- self.originalIndex = fromCol.originalIndex;
824
- self.sortDirection = fromCol.sortDirection;
825
- self.sortingAlgorithm = fromCol.sortingAlgorithm;
826
- self.headerClass = fromCol.headerClass;
827
- self.headerCellTemplate = fromCol.headerCellTemplate;
828
- self.cellTemplate = fromCol.cellTemplate;
829
- self.cellEditTemplate = fromCol.cellEditTemplate;
830
- };
831
- };
832
-
833
- var ngDimension = function (options) {
834
- this.outerHeight = null;
835
- this.outerWidth = null;
836
- $.extend(this, options);
837
- };
838
- var ngDomAccessProvider = function (grid) {
839
- this.previousColumn = null;
840
- this.grid = grid;
841
-
842
- };
843
-
844
- ngDomAccessProvider.prototype.changeUserSelect = function (elm, value) {
845
- elm.css({
846
- '-webkit-touch-callout': value,
847
- '-webkit-user-select': value,
848
- '-khtml-user-select': value,
849
- '-moz-user-select': value === 'none' ? '-moz-none' : value,
850
- '-ms-user-select': value,
851
- 'user-select': value
852
- });
853
- };
854
- ngDomAccessProvider.prototype.focusCellElement = function ($scope, index) {
855
- if ($scope.selectionProvider.lastClickedRow) {
856
- var columnIndex = index !== undefined ? index : this.previousColumn;
857
- var elm = $scope.selectionProvider.lastClickedRow.clone ? $scope.selectionProvider.lastClickedRow.clone.elm : $scope.selectionProvider.lastClickedRow.elm;
858
- if (columnIndex !== undefined && elm) {
859
- var columns = angular.element(elm[0].children).filter(function () { return this.nodeType !== 8; });
860
- var i = Math.max(Math.min($scope.renderedColumns.length - 1, columnIndex), 0);
861
- if (this.grid.config.showSelectionCheckbox && angular.element(columns[i]).scope() && angular.element(columns[i]).scope().col.index === 0) {
862
- i = 1;
863
- }
864
- if (columns[i]) {
865
- columns[i].children[1].children[0].focus();
866
- }
867
- this.previousColumn = columnIndex;
868
- }
869
- }
870
- };
871
- ngDomAccessProvider.prototype.selectionHandlers = function ($scope, elm) {
872
- var doingKeyDown = false;
873
- var self = this;
874
- elm.bind('keydown', function (evt) {
875
- if (evt.keyCode === 16) {
876
- self.changeUserSelect(elm, 'none', evt);
877
- return true;
878
- } else if (!doingKeyDown) {
879
- doingKeyDown = true;
880
- var ret = ngMoveSelectionHandler($scope, elm, evt, self.grid);
881
- doingKeyDown = false;
882
- return ret;
883
- }
884
- return true;
885
- });
886
- elm.bind('keyup', function (evt) {
887
- if (evt.keyCode === 16) {
888
- self.changeUserSelect(elm, 'text', evt);
889
- }
890
- return true;
891
- });
892
- };
893
- var ngEventProvider = function (grid, $scope, domUtilityService, $timeout) {
894
- var self = this;
895
- self.colToMove = undefined;
896
- self.groupToMove = undefined;
897
- self.assignEvents = function() {
898
- if (grid.config.jqueryUIDraggable && !grid.config.enablePinning) {
899
- grid.$groupPanel.droppable({
900
- addClasses: false,
901
- drop: function(event) {
902
- self.onGroupDrop(event);
903
- }
904
- });
905
- } else {
906
- grid.$groupPanel.on('mousedown', self.onGroupMouseDown).on('dragover', self.dragOver).on('drop', self.onGroupDrop);
907
- grid.$headerScroller.on('mousedown', self.onHeaderMouseDown).on('dragover', self.dragOver);
908
- if (grid.config.enableColumnReordering && !grid.config.enablePinning) {
909
- grid.$headerScroller.on('drop', self.onHeaderDrop);
910
- }
911
- }
912
- $scope.$watch('renderedColumns', function() {
913
- $timeout(self.setDraggables);
914
- });
915
- };
916
- self.dragStart = function(evt){
917
- evt.dataTransfer.setData('text', '');
918
- };
919
- self.dragOver = function(evt) {
920
- evt.preventDefault();
921
- };
922
- self.setDraggables = function() {
923
- if (!grid.config.jqueryUIDraggable) {
924
- var columns = grid.$root.find('.ngHeaderSortColumn');
925
- angular.forEach(columns, function(col){
926
- if(col.className && col.className.indexOf("ngHeaderSortColumn") !== -1){
927
- col.setAttribute('draggable', 'true');
928
- if (col.addEventListener) {
929
- col.addEventListener('dragstart', self.dragStart);
930
- }
931
- }
932
- });
933
- if (navigator.userAgent.indexOf("MSIE") !== -1){
934
- grid.$root.find('.ngHeaderSortColumn').bind('selectstart', function () {
935
- this.dragDrop();
936
- return false;
937
- });
938
- }
939
- } else {
940
- grid.$root.find('.ngHeaderSortColumn').draggable({
941
- helper: 'clone',
942
- appendTo: 'body',
943
- stack: 'div',
944
- addClasses: false,
945
- start: function(event) {
946
- self.onHeaderMouseDown(event);
947
- }
948
- }).droppable({
949
- drop: function(event) {
950
- self.onHeaderDrop(event);
951
- }
952
- });
953
- }
954
- };
955
- self.onGroupMouseDown = function(event) {
956
- var groupItem = $(event.target);
957
- if (groupItem[0].className !== 'ngRemoveGroup') {
958
- var groupItemScope = angular.element(groupItem).scope();
959
- if (groupItemScope) {
960
- if (!grid.config.jqueryUIDraggable) {
961
- groupItem.attr('draggable', 'true');
962
- if(this.addEventListener){
963
- this.addEventListener('dragstart', self.dragStart);
964
- }
965
- if (navigator.userAgent.indexOf("MSIE") !== -1){
966
- groupItem.bind('selectstart', function () {
967
- this.dragDrop();
968
- return false;
969
- });
970
- }
971
- }
972
- self.groupToMove = { header: groupItem, groupName: groupItemScope.group, index: groupItemScope.$index };
973
- }
974
- } else {
975
- self.groupToMove = undefined;
976
- }
977
- };
978
- self.onGroupDrop = function(event) {
979
- event.stopPropagation();
980
- var groupContainer;
981
- var groupScope;
982
- if (self.groupToMove) {
983
- groupContainer = $(event.target).closest('.ngGroupElement');
984
- if (groupContainer.context.className === 'ngGroupPanel') {
985
- $scope.configGroups.splice(self.groupToMove.index, 1);
986
- $scope.configGroups.push(self.groupToMove.groupName);
987
- } else {
988
- groupScope = angular.element(groupContainer).scope();
989
- if (groupScope) {
990
- if (self.groupToMove.index !== groupScope.$index) {
991
- $scope.configGroups.splice(self.groupToMove.index, 1);
992
- $scope.configGroups.splice(groupScope.$index, 0, self.groupToMove.groupName);
993
- }
994
- }
995
- }
996
- self.groupToMove = undefined;
997
- grid.fixGroupIndexes();
998
- } else if (self.colToMove) {
999
- if ($scope.configGroups.indexOf(self.colToMove.col) === -1) {
1000
- groupContainer = $(event.target).closest('.ngGroupElement');
1001
- if (groupContainer.context.className === 'ngGroupPanel' || groupContainer.context.className === 'ngGroupPanelDescription ng-binding') {
1002
- $scope.groupBy(self.colToMove.col);
1003
- } else {
1004
- groupScope = angular.element(groupContainer).scope();
1005
- if (groupScope) {
1006
- $scope.removeGroup(groupScope.$index);
1007
- }
1008
- }
1009
- }
1010
- self.colToMove = undefined;
1011
- }
1012
- if (!$scope.$$phase) {
1013
- $scope.$apply();
1014
- }
1015
- };
1016
- self.onHeaderMouseDown = function(event) {
1017
- var headerContainer = $(event.target).closest('.ngHeaderSortColumn');
1018
- var headerScope = angular.element(headerContainer).scope();
1019
- if (headerScope) {
1020
- self.colToMove = { header: headerContainer, col: headerScope.col };
1021
- }
1022
- };
1023
- self.onHeaderDrop = function(event) {
1024
- if (!self.colToMove || self.colToMove.col.pinned) {
1025
- return;
1026
- }
1027
- var headerContainer = $(event.target).closest('.ngHeaderSortColumn');
1028
- var headerScope = angular.element(headerContainer).scope();
1029
- if (headerScope) {
1030
- if (self.colToMove.col === headerScope.col) {
1031
- return;
1032
- }
1033
- $scope.columns.splice(self.colToMove.col.index, 1);
1034
- $scope.columns.splice(headerScope.col.index, 0, self.colToMove.col);
1035
- grid.fixColumnIndexes();
1036
- self.colToMove = undefined;
1037
- domUtilityService.digest($scope);
1038
- }
1039
- };
1040
-
1041
- self.assignGridEventHandlers = function() {
1042
- if (grid.config.tabIndex === -1) {
1043
- grid.$viewport.attr('tabIndex', domUtilityService.numberOfGrids);
1044
- domUtilityService.numberOfGrids++;
1045
- } else {
1046
- grid.$viewport.attr('tabIndex', grid.config.tabIndex);
1047
- }
1048
- var windowThrottle;
1049
- $(window).resize(function(){
1050
- clearTimeout(windowThrottle);
1051
- windowThrottle = setTimeout(function() {
1052
- domUtilityService.RebuildGrid($scope,grid);
1053
- }, 100);
1054
- });
1055
- var parentThrottle;
1056
- $(grid.$root.parent()).on('resize', function() {
1057
- clearTimeout(parentThrottle);
1058
- parentThrottle = setTimeout(function() {
1059
- domUtilityService.RebuildGrid($scope,grid);
1060
- }, 100);
1061
- });
1062
- };
1063
- self.assignGridEventHandlers();
1064
- self.assignEvents();
1065
- };
1066
-
1067
- var ngFooter = function ($scope, grid) {
1068
- $scope.maxRows = function () {
1069
- var ret = Math.max($scope.totalServerItems, grid.data.length);
1070
- return ret;
1071
- };
1072
- $scope.multiSelect = (grid.config.enableRowSelection && grid.config.multiSelect);
1073
- $scope.selectedItemCount = grid.selectedItemCount;
1074
- $scope.maxPages = function () {
1075
- return Math.ceil($scope.maxRows() / $scope.pagingOptions.pageSize);
1076
- };
1077
-
1078
- $scope.pageForward = function() {
1079
- var page = $scope.pagingOptions.currentPage;
1080
- if ($scope.totalServerItems > 0) {
1081
- $scope.pagingOptions.currentPage = Math.min(page + 1, $scope.maxPages());
1082
- } else {
1083
- $scope.pagingOptions.currentPage++;
1084
- }
1085
- };
1086
-
1087
- $scope.pageBackward = function() {
1088
- var page = $scope.pagingOptions.currentPage;
1089
- $scope.pagingOptions.currentPage = Math.max(page - 1, 1);
1090
- };
1091
-
1092
- $scope.pageToFirst = function() {
1093
- $scope.pagingOptions.currentPage = 1;
1094
- };
1095
-
1096
- $scope.pageToLast = function() {
1097
- var maxPages = $scope.maxPages();
1098
- $scope.pagingOptions.currentPage = maxPages;
1099
- };
1100
-
1101
- $scope.cantPageForward = function() {
1102
- var curPage = $scope.pagingOptions.currentPage;
1103
- var maxPages = $scope.maxPages();
1104
- if ($scope.totalServerItems > 0) {
1105
- return curPage >= maxPages;
1106
- } else {
1107
- return grid.data.length < 1;
1108
- }
1109
-
1110
- };
1111
- $scope.cantPageToLast = function() {
1112
- if ($scope.totalServerItems > 0) {
1113
- return $scope.cantPageForward();
1114
- } else {
1115
- return true;
1116
- }
1117
- };
1118
- $scope.cantPageBackward = function() {
1119
- var curPage = $scope.pagingOptions.currentPage;
1120
- return curPage <= 1;
1121
- };
1122
- };
1123
-
1124
- var ngGrid = function ($scope, options, sortService, domUtilityService, $filter, $templateCache, $utils, $timeout, $parse, $http, $q) {
1125
- var defaults = {
1126
- aggregateTemplate: undefined,
1127
- afterSelectionChange: function() {
1128
- },
1129
- beforeSelectionChange: function() {
1130
- return true;
1131
- },
1132
- checkboxCellTemplate: undefined,
1133
- checkboxHeaderTemplate: undefined,
1134
- columnDefs: undefined,
1135
- data: [],
1136
- dataUpdated: function() {
1137
- },
1138
- enableCellEdit: false,
1139
- enableCellEditOnFocus: false,
1140
- enableCellSelection: false,
1141
- enableColumnResize: false,
1142
- enableColumnReordering: false,
1143
- enableColumnHeavyVirt: false,
1144
- enablePaging: false,
1145
- enablePinning: false,
1146
- enableRowSelection: true,
1147
- enableSorting: true,
1148
- enableHighlighting: false,
1149
- excludeProperties: [],
1150
- filterOptions: {
1151
- filterText: "",
1152
- useExternalFilter: false
1153
- },
1154
- footerRowHeight: 55,
1155
- footerTemplate: undefined,
1156
- groups: [],
1157
- groupsCollapsedByDefault: true,
1158
- headerRowHeight: 30,
1159
- headerRowTemplate: undefined,
1160
- jqueryUIDraggable: false,
1161
- jqueryUITheme: false,
1162
- keepLastSelected: true,
1163
- maintainColumnRatios: undefined,
1164
- menuTemplate: undefined,
1165
- multiSelect: true,
1166
- pagingOptions: {
1167
- pageSizes: [250, 500, 1000],
1168
- pageSize: 250,
1169
- currentPage: 1
1170
- },
1171
- pinSelectionCheckbox: false,
1172
- plugins: [],
1173
- primaryKey: undefined,
1174
- rowHeight: 30,
1175
- rowTemplate: undefined,
1176
- selectedItems: [],
1177
- selectWithCheckboxOnly: false,
1178
- showColumnMenu: false,
1179
- showFilter: false,
1180
- showFooter: false,
1181
- showGroupPanel: false,
1182
- showSelectionCheckbox: false,
1183
- sortInfo: {fields: [], columns: [], directions: [] },
1184
- tabIndex: -1,
1185
- totalServerItems: 0,
1186
- useExternalSorting: false,
1187
- i18n: 'en',
1188
- virtualizationThreshold: 50
1189
- },
1190
- self = this;
1191
- self.maxCanvasHt = 0;
1192
- self.config = $.extend(defaults, window.ngGrid.config, options);
1193
- self.config.showSelectionCheckbox = (self.config.showSelectionCheckbox && self.config.enableColumnHeavyVirt === false);
1194
- self.config.enablePinning = (self.config.enablePinning && self.config.enableColumnHeavyVirt === false);
1195
- self.config.selectWithCheckboxOnly = (self.config.selectWithCheckboxOnly && self.config.showSelectionCheckbox !== false);
1196
- self.config.pinSelectionCheckbox = self.config.enablePinning;
1197
-
1198
- if (typeof options.columnDefs === "string") {
1199
- self.config.columnDefs = $scope.$eval(options.columnDefs);
1200
- }
1201
- self.rowCache = [];
1202
- self.rowMap = [];
1203
- self.gridId = "ng" + $utils.newId();
1204
- self.$root = null;
1205
- self.$groupPanel = null;
1206
- self.$topPanel = null;
1207
- self.$headerContainer = null;
1208
- self.$headerScroller = null;
1209
- self.$headers = null;
1210
- self.$viewport = null;
1211
- self.$canvas = null;
1212
- self.rootDim = self.config.gridDim;
1213
- self.data = [];
1214
- self.lateBindColumns = false;
1215
- self.filteredRows = [];
1216
-
1217
- self.initTemplates = function() {
1218
- var templates = ['rowTemplate', 'aggregateTemplate', 'headerRowTemplate', 'checkboxCellTemplate', 'checkboxHeaderTemplate', 'menuTemplate', 'footerTemplate'];
1219
-
1220
- var promises = [];
1221
- angular.forEach(templates, function(template) {
1222
- promises.push( self.getTemplate(template) );
1223
- });
1224
-
1225
- return $q.all(promises);
1226
- };
1227
- self.getTemplate = function (key) {
1228
- var t = self.config[key];
1229
- var uKey = self.gridId + key + ".html";
1230
- var p = $q.defer();
1231
- if (t && !TEMPLATE_REGEXP.test(t)) {
1232
- $http.get(t, {
1233
- cache: $templateCache
1234
- })
1235
- .success(function(data){
1236
- $templateCache.put(uKey, data);
1237
- p.resolve();
1238
- })
1239
- .error(function(err){
1240
- p.reject("Could not load template: " + t);
1241
- });
1242
- } else if (t) {
1243
- $templateCache.put(uKey, t);
1244
- p.resolve();
1245
- } else {
1246
- var dKey = key + ".html";
1247
- $templateCache.put(uKey, $templateCache.get(dKey));
1248
- p.resolve();
1249
- }
1250
-
1251
- return p.promise;
1252
- };
1253
-
1254
- if (typeof self.config.data === "object") {
1255
- self.data = self.config.data;
1256
- }
1257
- self.calcMaxCanvasHeight = function() {
1258
- var calculatedHeight;
1259
- if(self.config.groups.length > 0){
1260
- calculatedHeight = self.rowFactory.parsedData.filter(function(e) {
1261
- return !e[NG_HIDDEN];
1262
- }).length * self.config.rowHeight;
1263
- } else {
1264
- calculatedHeight = self.filteredRows.length * self.config.rowHeight;
1265
- }
1266
- return calculatedHeight;
1267
- };
1268
- self.elementDims = {
1269
- scrollW: 0,
1270
- scrollH: 0,
1271
- rowIndexCellW: 25,
1272
- rowSelectedCellW: 25,
1273
- rootMaxW: 0,
1274
- rootMaxH: 0
1275
- };
1276
- self.setRenderedRows = function (newRows) {
1277
- $scope.renderedRows.length = newRows.length;
1278
- for (var i = 0; i < newRows.length; i++) {
1279
- if (!$scope.renderedRows[i] || (newRows[i].isAggRow || $scope.renderedRows[i].isAggRow)) {
1280
- $scope.renderedRows[i] = newRows[i].copy();
1281
- $scope.renderedRows[i].collapsed = newRows[i].collapsed;
1282
- if (!newRows[i].isAggRow) {
1283
- $scope.renderedRows[i].setVars(newRows[i]);
1284
- }
1285
- } else {
1286
- $scope.renderedRows[i].setVars(newRows[i]);
1287
- }
1288
- $scope.renderedRows[i].rowIndex = newRows[i].rowIndex;
1289
- $scope.renderedRows[i].offsetTop = newRows[i].offsetTop;
1290
- $scope.renderedRows[i].selected = newRows[i].selected;
1291
- newRows[i].renderedRowIndex = i;
1292
- }
1293
- self.refreshDomSizes();
1294
- $scope.$emit('ngGridEventRows', newRows);
1295
- };
1296
- self.minRowsToRender = function() {
1297
- var viewportH = $scope.viewportDimHeight() || 1;
1298
- return Math.floor(viewportH / self.config.rowHeight);
1299
- };
1300
- self.refreshDomSizes = function() {
1301
- var dim = new ngDimension();
1302
- dim.outerWidth = self.elementDims.rootMaxW;
1303
- dim.outerHeight = self.elementDims.rootMaxH;
1304
- self.rootDim = dim;
1305
- self.maxCanvasHt = self.calcMaxCanvasHeight();
1306
- };
1307
- self.buildColumnDefsFromData = function () {
1308
- self.config.columnDefs = [];
1309
- var item = self.data[0];
1310
- if (!item) {
1311
- self.lateBoundColumns = true;
1312
- return;
1313
- }
1314
- $utils.forIn(item, function (prop, propName) {
1315
- if (self.config.excludeProperties.indexOf(propName) === -1) {
1316
- self.config.columnDefs.push({
1317
- field: propName
1318
- });
1319
- }
1320
- });
1321
- };
1322
- self.buildColumns = function() {
1323
- var columnDefs = self.config.columnDefs,
1324
- cols = [];
1325
- if (!columnDefs) {
1326
- self.buildColumnDefsFromData();
1327
- columnDefs = self.config.columnDefs;
1328
- }
1329
- if (self.config.showSelectionCheckbox) {
1330
- cols.push(new ngColumn({
1331
- colDef: {
1332
- field: '\u2714',
1333
- width: self.elementDims.rowSelectedCellW,
1334
- sortable: false,
1335
- resizable: false,
1336
- groupable: false,
1337
- headerCellTemplate: $templateCache.get($scope.gridId + 'checkboxHeaderTemplate.html'),
1338
- cellTemplate: $templateCache.get($scope.gridId + 'checkboxCellTemplate.html'),
1339
- pinned: self.config.pinSelectionCheckbox
1340
- },
1341
- index: 0,
1342
- headerRowHeight: self.config.headerRowHeight,
1343
- sortCallback: self.sortData,
1344
- resizeOnDataCallback: self.resizeOnData,
1345
- enableResize: self.config.enableColumnResize,
1346
- enableSort: self.config.enableSorting,
1347
- enablePinning: self.config.enablePinning
1348
- }, $scope, self, domUtilityService, $templateCache, $utils));
1349
- }
1350
- if (columnDefs.length > 0) {
1351
- var checkboxOffset = self.config.showSelectionCheckbox ? 1 : 0;
1352
- var groupOffset = $scope.configGroups.length;
1353
- $scope.configGroups.length = 0;
1354
- angular.forEach(columnDefs, function(colDef, i) {
1355
- i += checkboxOffset;
1356
- var column = new ngColumn({
1357
- colDef: colDef,
1358
- index: i + groupOffset,
1359
- originalIndex: i,
1360
- headerRowHeight: self.config.headerRowHeight,
1361
- sortCallback: self.sortData,
1362
- resizeOnDataCallback: self.resizeOnData,
1363
- enableResize: self.config.enableColumnResize,
1364
- enableSort: self.config.enableSorting,
1365
- enablePinning: self.config.enablePinning,
1366
- enableCellEdit: self.config.enableCellEdit || self.config.enableCellEditOnFocus
1367
- }, $scope, self, domUtilityService, $templateCache, $utils);
1368
- var indx = self.config.groups.indexOf(colDef.field);
1369
- if (indx !== -1) {
1370
- column.isGroupedBy = true;
1371
- $scope.configGroups.splice(indx, 0, column);
1372
- column.groupIndex = $scope.configGroups.length;
1373
- }
1374
- cols.push(column);
1375
- });
1376
- $scope.columns = cols;
1377
- if (self.config.groups.length > 0) {
1378
- self.rowFactory.getGrouping(self.config.groups);
1379
- }
1380
- }
1381
- };
1382
- self.configureColumnWidths = function() {
1383
- var asterisksArray = [],
1384
- percentArray = [],
1385
- asteriskNum = 0,
1386
- totalWidth = 0;
1387
- var indexMap = {};
1388
- angular.forEach($scope.columns, function(ngCol, i) {
1389
- if (!$utils.isNullOrUndefined(ngCol.originalIndex)) {
1390
- var origIndex = ngCol.originalIndex;
1391
- if (self.config.showSelectionCheckbox) {
1392
- if(ngCol.originalIndex === 0 && ngCol.visible){
1393
- totalWidth += 25;
1394
- }
1395
- origIndex--;
1396
- }
1397
- indexMap[origIndex] = i;
1398
- }
1399
- });
1400
-
1401
- angular.forEach(self.config.columnDefs, function(colDef, i) {
1402
- var ngColumn = $scope.columns[indexMap[i]];
1403
-
1404
- colDef.index = i;
1405
-
1406
- var isPercent = false, t;
1407
- if ($utils.isNullOrUndefined(colDef.width)) {
1408
- colDef.width = "*";
1409
- } else {
1410
- isPercent = isNaN(colDef.width) ? $utils.endsWith(colDef.width, "%") : false;
1411
- t = isPercent ? colDef.width : parseInt(colDef.width, 10);
1412
- }
1413
- if (isNaN(t) && !$scope.hasUserChangedGridColumnWidths) {
1414
- t = colDef.width;
1415
- if (t === 'auto') {
1416
- ngColumn.width = ngColumn.minWidth;
1417
- totalWidth += ngColumn.width;
1418
- var temp = ngColumn;
1419
-
1420
- $scope.$on("ngGridEventData", function () {
1421
- self.resizeOnData(temp);
1422
- });
1423
- return;
1424
- } else if (t.indexOf("*") !== -1) {
1425
- if (ngColumn.visible !== false) {
1426
- asteriskNum += t.length;
1427
- }
1428
- asterisksArray.push(colDef);
1429
- return;
1430
- } else if (isPercent) {
1431
- percentArray.push(colDef);
1432
- return;
1433
- } else {
1434
- throw "unable to parse column width, use percentage (\"10%\",\"20%\", etc...) or \"*\" to use remaining width of grid";
1435
- }
1436
- } else if (ngColumn.visible !== false) {
1437
- totalWidth += ngColumn.width = parseInt(ngColumn.width, 10);
1438
- }
1439
- });
1440
- if (percentArray.length > 0) {
1441
- self.config.maintainColumnRatios = self.config.maintainColumnRatios !== false;
1442
- var percentWidth = 0;
1443
- var hiddenPercent = 0;
1444
- angular.forEach(percentArray, function(colDef) {
1445
- var ngColumn = $scope.columns[indexMap[colDef.index]];
1446
- var t = colDef.width;
1447
- var percent = parseInt(t.slice(0, -1), 10) / 100;
1448
- percentWidth += percent;
1449
-
1450
- if (!ngColumn.visible) {
1451
- hiddenPercent += percent;
1452
- }
1453
- });
1454
- var percentWidthUsed = percentWidth - hiddenPercent;
1455
- angular.forEach(percentArray, function(colDef) {
1456
- var ngColumn = $scope.columns[indexMap[colDef.index]];
1457
- var t = colDef.width;
1458
- var percent = parseInt(t.slice(0, -1), 10) / 100;
1459
- if (hiddenPercent > 0) {
1460
- percent = percent / percentWidthUsed;
1461
- }
1462
- else {
1463
- percent = percent / percentWidth;
1464
- }
1465
-
1466
- var pixelsForPercentBasedWidth = self.rootDim.outerWidth * percentWidth;
1467
- ngColumn.width = Math.floor(pixelsForPercentBasedWidth * percent);
1468
- totalWidth += ngColumn.width;
1469
- });
1470
- }
1471
- if (asterisksArray.length > 0) {
1472
- self.config.maintainColumnRatios = self.config.maintainColumnRatios !== false;
1473
- var remainingWidth = self.rootDim.outerWidth - totalWidth;
1474
- if (self.maxCanvasHt > $scope.viewportDimHeight()) {
1475
- remainingWidth -= domUtilityService.ScrollW;
1476
- }
1477
- var asteriskVal = Math.floor(remainingWidth / asteriskNum);
1478
- angular.forEach(asterisksArray, function(colDef, i) {
1479
- var ngColumn = $scope.columns[indexMap[colDef.index]];
1480
- ngColumn.width = asteriskVal * colDef.width.length;
1481
- if (ngColumn.visible !== false) {
1482
- totalWidth += ngColumn.width;
1483
- }
1484
-
1485
- var isLast = (i === (asterisksArray.length - 1));
1486
- if(isLast && totalWidth < self.rootDim.outerWidth){
1487
- var gridWidthDifference = self.rootDim.outerWidth - totalWidth;
1488
- if(self.maxCanvasHt > $scope.viewportDimHeight()){
1489
- gridWidthDifference -= domUtilityService.ScrollW;
1490
- }
1491
- ngColumn.width += gridWidthDifference;
1492
- }
1493
- });
1494
- }
1495
- };
1496
- self.init = function() {
1497
- return self.initTemplates().then(function(){
1498
- $scope.selectionProvider = new ngSelectionProvider(self, $scope, $parse);
1499
- $scope.domAccessProvider = new ngDomAccessProvider(self);
1500
- self.rowFactory = new ngRowFactory(self, $scope, domUtilityService, $templateCache, $utils);
1501
- self.searchProvider = new ngSearchProvider($scope, self, $filter);
1502
- self.styleProvider = new ngStyleProvider($scope, self);
1503
- $scope.$watch('configGroups', function(a) {
1504
- var tempArr = [];
1505
- angular.forEach(a, function(item) {
1506
- tempArr.push(item.field || item);
1507
- });
1508
- self.config.groups = tempArr;
1509
- self.rowFactory.filteredRowsChanged();
1510
- $scope.$emit('ngGridEventGroups', a);
1511
- }, true);
1512
- $scope.$watch('columns', function (a) {
1513
- if(!$scope.isColumnResizing){
1514
- domUtilityService.RebuildGrid($scope, self);
1515
- }
1516
- $scope.$emit('ngGridEventColumns', a);
1517
- }, true);
1518
- $scope.$watch(function() {
1519
- return options.i18n;
1520
- }, function(newLang) {
1521
- $utils.seti18n($scope, newLang);
1522
- });
1523
- self.maxCanvasHt = self.calcMaxCanvasHeight();
1524
-
1525
- if (self.config.sortInfo.fields && self.config.sortInfo.fields.length > 0) {
1526
- $scope.$watch(function() {
1527
- return self.config.sortInfo;
1528
- }, function(sortInfo){
1529
- if (!sortService.isSorting) {
1530
- self.sortColumnsInit();
1531
- $scope.$emit('ngGridEventSorted', self.config.sortInfo);
1532
- }
1533
- },true);
1534
- }
1535
- });
1536
- };
1537
- self.resizeOnData = function(col) {
1538
- var longest = col.minWidth;
1539
- var arr = $utils.getElementsByClassName('col' + col.index);
1540
- angular.forEach(arr, function(elem, index) {
1541
- var i;
1542
- if (index === 0) {
1543
- var kgHeaderText = $(elem).find('.ngHeaderText');
1544
- i = $utils.visualLength(kgHeaderText) + 10;
1545
- } else {
1546
- var ngCellText = $(elem).find('.ngCellText');
1547
- i = $utils.visualLength(ngCellText) + 10;
1548
- }
1549
- if (i > longest) {
1550
- longest = i;
1551
- }
1552
- });
1553
- col.width = col.longest = Math.min(col.maxWidth, longest + 7);
1554
- domUtilityService.BuildStyles($scope, self, true);
1555
- };
1556
- self.lastSortedColumns = [];
1557
- self.sortData = function(col, evt) {
1558
- if (evt && evt.shiftKey && self.config.sortInfo) {
1559
- var indx = self.config.sortInfo.columns.indexOf(col);
1560
- if (indx === -1) {
1561
- if (self.config.sortInfo.columns.length === 1) {
1562
- self.config.sortInfo.columns[0].sortPriority = 1;
1563
- }
1564
- self.config.sortInfo.columns.push(col);
1565
- col.sortPriority = self.config.sortInfo.columns.length;
1566
- self.config.sortInfo.fields.push(col.field);
1567
- self.config.sortInfo.directions.push(col.sortDirection);
1568
- self.lastSortedColumns.push(col);
1569
- } else {
1570
- self.config.sortInfo.directions[indx] = col.sortDirection;
1571
- }
1572
- } else {
1573
- var isArr = $.isArray(col);
1574
- self.config.sortInfo.columns.length = 0;
1575
- self.config.sortInfo.fields.length = 0;
1576
- self.config.sortInfo.directions.length = 0;
1577
- var push = function (c) {
1578
- self.config.sortInfo.columns.push(c);
1579
- self.config.sortInfo.fields.push(c.field);
1580
- self.config.sortInfo.directions.push(c.sortDirection);
1581
- self.lastSortedColumns.push(c);
1582
- };
1583
- if (isArr) {
1584
- self.clearSortingData();
1585
- angular.forEach(col, function (c, i) {
1586
- c.sortPriority = i + 1;
1587
- push(c);
1588
- });
1589
- } else {
1590
- self.clearSortingData(col);
1591
- col.sortPriority = undefined;
1592
- push(col);
1593
- }
1594
- }
1595
- self.sortActual();
1596
- self.searchProvider.evalFilter();
1597
- $scope.$emit('ngGridEventSorted', self.config.sortInfo);
1598
- };
1599
- self.sortColumnsInit = function() {
1600
- if (self.config.sortInfo.columns) {
1601
- self.config.sortInfo.columns.length = 0;
1602
- } else {
1603
- self.config.sortInfo.columns = [];
1604
- }
1605
- angular.forEach($scope.columns, function(c) {
1606
- var i = self.config.sortInfo.fields.indexOf(c.field);
1607
- if (i !== -1) {
1608
- c.sortDirection = self.config.sortInfo.directions[i] || 'asc';
1609
- self.config.sortInfo.columns[i] = c;
1610
- }
1611
- });
1612
- angular.forEach(self.config.sortInfo.columns, function(c){
1613
- self.sortData(c);
1614
- });
1615
- };
1616
- self.sortActual = function() {
1617
- if (!self.config.useExternalSorting) {
1618
- var tempData = self.data.slice(0);
1619
- angular.forEach(tempData, function(item, i) {
1620
- var e = self.rowMap[i];
1621
- if (e !== undefined) {
1622
- var v = self.rowCache[e];
1623
- if (v !== undefined) {
1624
- item.preSortSelected = v.selected;
1625
- item.preSortIndex = i;
1626
- }
1627
- }
1628
- });
1629
- sortService.Sort(self.config.sortInfo, tempData);
1630
- angular.forEach(tempData, function(item, i) {
1631
- self.rowCache[i].entity = item;
1632
- self.rowCache[i].selected = item.preSortSelected;
1633
- self.rowMap[item.preSortIndex] = i;
1634
- delete item.preSortSelected;
1635
- delete item.preSortIndex;
1636
- });
1637
- }
1638
- };
1639
-
1640
- self.clearSortingData = function (col) {
1641
- if (!col) {
1642
- angular.forEach(self.lastSortedColumns, function (c) {
1643
- c.sortDirection = "";
1644
- c.sortPriority = null;
1645
- });
1646
- self.lastSortedColumns = [];
1647
- } else {
1648
- angular.forEach(self.lastSortedColumns, function (c) {
1649
- if (col.index !== c.index) {
1650
- c.sortDirection = "";
1651
- c.sortPriority = null;
1652
- }
1653
- });
1654
- self.lastSortedColumns[0] = col;
1655
- self.lastSortedColumns.length = 1;
1656
- }
1657
- };
1658
- self.fixColumnIndexes = function() {
1659
- for (var i = 0; i < $scope.columns.length; i++) {
1660
- $scope.columns[i].index = i;
1661
- }
1662
- };
1663
- self.fixGroupIndexes = function() {
1664
- angular.forEach($scope.configGroups, function(item, i) {
1665
- item.groupIndex = i + 1;
1666
- });
1667
- };
1668
- $scope.elementsNeedMeasuring = true;
1669
- $scope.columns = [];
1670
- $scope.renderedRows = [];
1671
- $scope.renderedColumns = [];
1672
- $scope.headerRow = null;
1673
- $scope.rowHeight = self.config.rowHeight;
1674
- $scope.jqueryUITheme = self.config.jqueryUITheme;
1675
- $scope.showSelectionCheckbox = self.config.showSelectionCheckbox;
1676
- $scope.enableCellSelection = self.config.enableCellSelection;
1677
- $scope.enableCellEditOnFocus = self.config.enableCellEditOnFocus;
1678
- $scope.footer = null;
1679
- $scope.selectedItems = self.config.selectedItems;
1680
- $scope.multiSelect = self.config.multiSelect;
1681
- $scope.showFooter = self.config.showFooter;
1682
- $scope.footerRowHeight = $scope.showFooter ? self.config.footerRowHeight : 0;
1683
- $scope.showColumnMenu = self.config.showColumnMenu;
1684
- $scope.showMenu = false;
1685
- $scope.configGroups = [];
1686
- $scope.gridId = self.gridId;
1687
- $scope.enablePaging = self.config.enablePaging;
1688
- $scope.pagingOptions = self.config.pagingOptions;
1689
- $scope.i18n = {};
1690
- $utils.seti18n($scope, self.config.i18n);
1691
- $scope.adjustScrollLeft = function (scrollLeft) {
1692
- var colwidths = 0,
1693
- totalLeft = 0,
1694
- x = $scope.columns.length,
1695
- newCols = [],
1696
- dcv = !self.config.enableColumnHeavyVirt;
1697
- var r = 0;
1698
- var addCol = function (c) {
1699
- if (dcv) {
1700
- newCols.push(c);
1701
- } else {
1702
- if (!$scope.renderedColumns[r]) {
1703
- $scope.renderedColumns[r] = c.copy();
1704
- } else {
1705
- $scope.renderedColumns[r].setVars(c);
1706
- }
1707
- }
1708
- r++;
1709
- };
1710
- for (var i = 0; i < x; i++) {
1711
- var col = $scope.columns[i];
1712
- if (col.visible !== false) {
1713
- var w = col.width + colwidths;
1714
- if (col.pinned) {
1715
- addCol(col);
1716
- var newLeft = i > 0 ? (scrollLeft + totalLeft) : scrollLeft;
1717
- domUtilityService.setColLeft(col, newLeft, self);
1718
- totalLeft += col.width;
1719
- } else {
1720
- if (w >= scrollLeft) {
1721
- if (colwidths <= scrollLeft + self.rootDim.outerWidth) {
1722
- addCol(col);
1723
- }
1724
- }
1725
- }
1726
- colwidths += col.width;
1727
- }
1728
- }
1729
- if (dcv) {
1730
- $scope.renderedColumns = newCols;
1731
- }
1732
- };
1733
- self.prevScrollTop = 0;
1734
- self.prevScrollIndex = 0;
1735
- $scope.adjustScrollTop = function(scrollTop, force) {
1736
- if (self.prevScrollTop === scrollTop && !force) {
1737
- return;
1738
- }
1739
- if (scrollTop > 0 && self.$viewport[0].scrollHeight - scrollTop <= self.$viewport.outerHeight()) {
1740
- $scope.$emit('ngGridEventScroll');
1741
- }
1742
- var rowIndex = Math.floor(scrollTop / self.config.rowHeight);
1743
- var newRange;
1744
- if (self.filteredRows.length > self.config.virtualizationThreshold) {
1745
- if (self.prevScrollTop < scrollTop && rowIndex < self.prevScrollIndex + SCROLL_THRESHOLD) {
1746
- return;
1747
- }
1748
- if (self.prevScrollTop > scrollTop && rowIndex > self.prevScrollIndex - SCROLL_THRESHOLD) {
1749
- return;
1750
- }
1751
- newRange = new ngRange(Math.max(0, rowIndex - EXCESS_ROWS), rowIndex + self.minRowsToRender() + EXCESS_ROWS);
1752
- } else {
1753
- var maxLen = $scope.configGroups.length > 0 ? self.rowFactory.parsedData.length : self.data.length;
1754
- newRange = new ngRange(0, Math.max(maxLen, self.minRowsToRender() + EXCESS_ROWS));
1755
- }
1756
- self.prevScrollTop = scrollTop;
1757
- self.rowFactory.UpdateViewableRange(newRange);
1758
- self.prevScrollIndex = rowIndex;
1759
- };
1760
- $scope.toggleShowMenu = function() {
1761
- $scope.showMenu = !$scope.showMenu;
1762
- };
1763
- $scope.toggleSelectAll = function(state, selectOnlyVisible) {
1764
- $scope.selectionProvider.toggleSelectAll(state, false, selectOnlyVisible);
1765
- };
1766
- $scope.totalFilteredItemsLength = function() {
1767
- return self.filteredRows.length;
1768
- };
1769
- $scope.showGroupPanel = function() {
1770
- return self.config.showGroupPanel;
1771
- };
1772
- $scope.topPanelHeight = function() {
1773
- return self.config.showGroupPanel === true ? self.config.headerRowHeight + 32 : self.config.headerRowHeight;
1774
- };
1775
-
1776
- $scope.viewportDimHeight = function() {
1777
- return Math.max(0, self.rootDim.outerHeight - $scope.topPanelHeight() - $scope.footerRowHeight - 2);
1778
- };
1779
- $scope.groupBy = function (col) {
1780
- if (self.data.length < 1 || !col.groupable || !col.field) {
1781
- return;
1782
- }
1783
- if (!col.sortDirection) {
1784
- col.sort({ shiftKey: $scope.configGroups.length > 0 ? true : false });
1785
- }
1786
-
1787
- var indx = $scope.configGroups.indexOf(col);
1788
- if (indx === -1) {
1789
- col.isGroupedBy = true;
1790
- $scope.configGroups.push(col);
1791
- col.groupIndex = $scope.configGroups.length;
1792
- } else {
1793
- $scope.removeGroup(indx);
1794
- }
1795
- self.$viewport.scrollTop(0);
1796
- domUtilityService.digest($scope);
1797
- };
1798
- $scope.removeGroup = function(index) {
1799
- var col = $scope.columns.filter(function(item) {
1800
- return item.groupIndex === (index + 1);
1801
- })[0];
1802
- col.isGroupedBy = false;
1803
- col.groupIndex = 0;
1804
- if ($scope.columns[index].isAggCol) {
1805
- $scope.columns.splice(index, 1);
1806
- $scope.configGroups.splice(index, 1);
1807
- self.fixGroupIndexes();
1808
- }
1809
- if ($scope.configGroups.length === 0) {
1810
- self.fixColumnIndexes();
1811
- domUtilityService.digest($scope);
1812
- }
1813
- $scope.adjustScrollLeft(0);
1814
- };
1815
- $scope.togglePin = function (col) {
1816
- var indexFrom = col.index;
1817
- var indexTo = 0;
1818
- for (var i = 0; i < $scope.columns.length; i++) {
1819
- if (!$scope.columns[i].pinned) {
1820
- break;
1821
- }
1822
- indexTo++;
1823
- }
1824
- if (col.pinned) {
1825
- indexTo = Math.max(col.originalIndex, indexTo - 1);
1826
- }
1827
- col.pinned = !col.pinned;
1828
- $scope.columns.splice(indexFrom, 1);
1829
- $scope.columns.splice(indexTo, 0, col);
1830
- self.fixColumnIndexes();
1831
- domUtilityService.BuildStyles($scope, self, true);
1832
- self.$viewport.scrollLeft(self.$viewport.scrollLeft() - col.width);
1833
- };
1834
- $scope.totalRowWidth = function() {
1835
- var totalWidth = 0,
1836
- cols = $scope.columns;
1837
- for (var i = 0; i < cols.length; i++) {
1838
- if (cols[i].visible !== false) {
1839
- totalWidth += cols[i].width;
1840
- }
1841
- }
1842
- return totalWidth;
1843
- };
1844
- $scope.headerScrollerDim = function() {
1845
- var viewportH = $scope.viewportDimHeight(),
1846
- maxHeight = self.maxCanvasHt,
1847
- vScrollBarIsOpen = (maxHeight > viewportH),
1848
- newDim = new ngDimension();
1849
-
1850
- newDim.autoFitHeight = true;
1851
- newDim.outerWidth = $scope.totalRowWidth();
1852
- if (vScrollBarIsOpen) {
1853
- newDim.outerWidth += self.elementDims.scrollW;
1854
- } else if ((maxHeight - viewportH) <= self.elementDims.scrollH) {
1855
- newDim.outerWidth += self.elementDims.scrollW;
1856
- }
1857
- return newDim;
1858
- };
1859
- };
1860
-
1861
- var ngRange = function (top, bottom) {
1862
- this.topRow = top;
1863
- this.bottomRow = bottom;
1864
- };
1865
- var ngRow = function (entity, config, selectionProvider, rowIndex, $utils) {
1866
- this.entity = entity;
1867
- this.config = config;
1868
- this.selectionProvider = selectionProvider;
1869
- this.rowIndex = rowIndex;
1870
- this.utils = $utils;
1871
- this.selected = selectionProvider.getSelection(entity);
1872
- this.cursor = this.config.enableRowSelection ? 'pointer' : 'default';
1873
- this.beforeSelectionChange = config.beforeSelectionChangeCallback;
1874
- this.afterSelectionChange = config.afterSelectionChangeCallback;
1875
- this.offsetTop = this.rowIndex * config.rowHeight;
1876
- this.rowDisplayIndex = 0;
1877
- };
1878
-
1879
- ngRow.prototype.setSelection = function (isSelected) {
1880
- this.selectionProvider.setSelection(this, isSelected);
1881
- this.selectionProvider.lastClickedRow = this;
1882
- };
1883
- ngRow.prototype.continueSelection = function (event) {
1884
- this.selectionProvider.ChangeSelection(this, event);
1885
- };
1886
- ngRow.prototype.ensureEntity = function (expected) {
1887
- if (this.entity !== expected) {
1888
- this.entity = expected;
1889
- this.selected = this.selectionProvider.getSelection(this.entity);
1890
- }
1891
- };
1892
- ngRow.prototype.toggleSelected = function (event) {
1893
- if (!this.config.enableRowSelection && !this.config.enableCellSelection) {
1894
- return true;
1895
- }
1896
- var element = event.target || event;
1897
- if (element.type === "checkbox" && element.parentElement.className !== "ngSelectionCell ng-scope") {
1898
- return true;
1899
- }
1900
- if (this.config.selectWithCheckboxOnly && element.type !== "checkbox") {
1901
- this.selectionProvider.lastClickedRow = this;
1902
- return true;
1903
- }
1904
- if (this.beforeSelectionChange(this, event)) {
1905
- this.continueSelection(event);
1906
- }
1907
- return false;
1908
- };
1909
- ngRow.prototype.alternatingRowClass = function () {
1910
- var isEven = (this.rowIndex % 2) === 0;
1911
- var classes = {
1912
- 'ngRow' : true,
1913
- 'selected': this.selected,
1914
- 'even': isEven,
1915
- 'odd': !isEven,
1916
- 'ui-state-default': this.config.jqueryUITheme && isEven,
1917
- 'ui-state-active': this.config.jqueryUITheme && !isEven
1918
- };
1919
- return classes;
1920
- };
1921
- ngRow.prototype.getProperty = function (path) {
1922
- return this.utils.evalProperty(this.entity, path);
1923
- };
1924
- ngRow.prototype.copy = function () {
1925
- this.clone = new ngRow(this.entity, this.config, this.selectionProvider, this.rowIndex, this.utils);
1926
- this.clone.isClone = true;
1927
- this.clone.elm = this.elm;
1928
- this.clone.orig = this;
1929
- return this.clone;
1930
- };
1931
- ngRow.prototype.setVars = function (fromRow) {
1932
- fromRow.clone = this;
1933
- this.entity = fromRow.entity;
1934
- this.selected = fromRow.selected;
1935
- this.orig = fromRow;
1936
- };
1937
- var ngRowFactory = function (grid, $scope, domUtilityService, $templateCache, $utils) {
1938
- var self = this;
1939
- self.aggCache = {};
1940
- self.parentCache = [];
1941
- self.dataChanged = true;
1942
- self.parsedData = [];
1943
- self.rowConfig = {};
1944
- self.selectionProvider = $scope.selectionProvider;
1945
- self.rowHeight = 30;
1946
- self.numberOfAggregates = 0;
1947
- self.groupedData = undefined;
1948
- self.rowHeight = grid.config.rowHeight;
1949
- self.rowConfig = {
1950
- enableRowSelection: grid.config.enableRowSelection,
1951
- rowClasses: grid.config.rowClasses,
1952
- selectedItems: $scope.selectedItems,
1953
- selectWithCheckboxOnly: grid.config.selectWithCheckboxOnly,
1954
- beforeSelectionChangeCallback: grid.config.beforeSelectionChange,
1955
- afterSelectionChangeCallback: grid.config.afterSelectionChange,
1956
- jqueryUITheme: grid.config.jqueryUITheme,
1957
- enableCellSelection: grid.config.enableCellSelection,
1958
- rowHeight: grid.config.rowHeight
1959
- };
1960
-
1961
- self.renderedRange = new ngRange(0, grid.minRowsToRender() + EXCESS_ROWS);
1962
- self.buildEntityRow = function(entity, rowIndex) {
1963
- return new ngRow(entity, self.rowConfig, self.selectionProvider, rowIndex, $utils);
1964
- };
1965
-
1966
- self.buildAggregateRow = function(aggEntity, rowIndex) {
1967
- var agg = self.aggCache[aggEntity.aggIndex];
1968
- if (!agg) {
1969
- agg = new ngAggregate(aggEntity, self, self.rowConfig.rowHeight, grid.config.groupsCollapsedByDefault);
1970
- self.aggCache[aggEntity.aggIndex] = agg;
1971
- }
1972
- agg.rowIndex = rowIndex;
1973
- agg.offsetTop = rowIndex * self.rowConfig.rowHeight;
1974
- return agg;
1975
- };
1976
- self.UpdateViewableRange = function(newRange) {
1977
- self.renderedRange = newRange;
1978
- self.renderedChange();
1979
- };
1980
- self.filteredRowsChanged = function() {
1981
- if (grid.lateBoundColumns && grid.filteredRows.length > 0) {
1982
- grid.config.columnDefs = undefined;
1983
- grid.buildColumns();
1984
- grid.lateBoundColumns = false;
1985
- $scope.$evalAsync(function() {
1986
- $scope.adjustScrollLeft(0);
1987
- });
1988
- }
1989
- self.dataChanged = true;
1990
- if (grid.config.groups.length > 0) {
1991
- self.getGrouping(grid.config.groups);
1992
- }
1993
- self.UpdateViewableRange(self.renderedRange);
1994
- };
1995
-
1996
- self.renderedChange = function() {
1997
- if (!self.groupedData || grid.config.groups.length < 1) {
1998
- self.renderedChangeNoGroups();
1999
- grid.refreshDomSizes();
2000
- return;
2001
- }
2002
- self.wasGrouped = true;
2003
- self.parentCache = [];
2004
- var x = 0;
2005
- var temp = self.parsedData.filter(function (e) {
2006
- if (e.isAggRow) {
2007
- if (e.parent && e.parent.collapsed) {
2008
- return false;
2009
- }
2010
- return true;
2011
- }
2012
- if (!e[NG_HIDDEN]) {
2013
- e.rowIndex = x++;
2014
- }
2015
- return !e[NG_HIDDEN];
2016
- });
2017
- self.totalRows = temp.length;
2018
- var rowArr = [];
2019
- for (var i = self.renderedRange.topRow; i < self.renderedRange.bottomRow; i++) {
2020
- if (temp[i]) {
2021
- temp[i].offsetTop = i * grid.config.rowHeight;
2022
- rowArr.push(temp[i]);
2023
- }
2024
- }
2025
- grid.setRenderedRows(rowArr);
2026
- };
2027
-
2028
- self.renderedChangeNoGroups = function () {
2029
- var rowArr = [];
2030
- for (var i = self.renderedRange.topRow; i < self.renderedRange.bottomRow; i++) {
2031
- if (grid.filteredRows[i]) {
2032
- grid.filteredRows[i].rowIndex = i;
2033
- grid.filteredRows[i].offsetTop = i * grid.config.rowHeight;
2034
- rowArr.push(grid.filteredRows[i]);
2035
- }
2036
- }
2037
- grid.setRenderedRows(rowArr);
2038
- };
2039
-
2040
- self.fixRowCache = function () {
2041
- var newLen = grid.data.length;
2042
- var diff = newLen - grid.rowCache.length;
2043
- if (diff < 0) {
2044
- grid.rowCache.length = grid.rowMap.length = newLen;
2045
- } else {
2046
- for (var i = grid.rowCache.length; i < newLen; i++) {
2047
- grid.rowCache[i] = grid.rowFactory.buildEntityRow(grid.data[i], i);
2048
- }
2049
- }
2050
- };
2051
- self.parseGroupData = function(g) {
2052
- if (g.values) {
2053
- for (var x = 0; x < g.values.length; x++){
2054
- self.parentCache[self.parentCache.length - 1].children.push(g.values[x]);
2055
- self.parsedData.push(g.values[x]);
2056
- }
2057
- } else {
2058
- for (var prop in g) {
2059
- if (prop === NG_FIELD || prop === NG_DEPTH || prop === NG_COLUMN) {
2060
- continue;
2061
- } else if (g.hasOwnProperty(prop)) {
2062
- var agg = self.buildAggregateRow({
2063
- gField: g[NG_FIELD],
2064
- gLabel: prop,
2065
- gDepth: g[NG_DEPTH],
2066
- isAggRow: true,
2067
- '_ng_hidden_': false,
2068
- children: [],
2069
- aggChildren: [],
2070
- aggIndex: self.numberOfAggregates,
2071
- aggLabelFilter: g[NG_COLUMN].aggLabelFilter
2072
- }, 0);
2073
- self.numberOfAggregates++;
2074
- agg.parent = self.parentCache[agg.depth - 1];
2075
- if (agg.parent) {
2076
- agg.parent.collapsed = false;
2077
- agg.parent.aggChildren.push(agg);
2078
- }
2079
- self.parsedData.push(agg);
2080
- self.parentCache[agg.depth] = agg;
2081
- self.parseGroupData(g[prop]);
2082
- }
2083
- }
2084
- }
2085
- };
2086
- self.getGrouping = function(groups) {
2087
- self.aggCache = [];
2088
- self.numberOfAggregates = 0;
2089
- self.groupedData = {};
2090
- var rows = grid.filteredRows,
2091
- maxDepth = groups.length,
2092
- cols = $scope.columns;
2093
-
2094
- function filterCols(cols, group) {
2095
- return cols.filter(function(c) {
2096
- return c.field === group;
2097
- });
2098
- }
2099
-
2100
- for (var x = 0; x < rows.length; x++) {
2101
- var model = rows[x].entity;
2102
- if (!model) {
2103
- return;
2104
- }
2105
- rows[x][NG_HIDDEN] = grid.config.groupsCollapsedByDefault;
2106
- var ptr = self.groupedData;
2107
-
2108
- for (var y = 0; y < groups.length; y++) {
2109
- var group = groups[y];
2110
-
2111
- var col = filterCols(cols, group)[0];
2112
-
2113
- var val = $utils.evalProperty(model, group);
2114
- val = val ? val.toString() : 'null';
2115
- if (!ptr[val]) {
2116
- ptr[val] = {};
2117
- }
2118
- if (!ptr[NG_FIELD]) {
2119
- ptr[NG_FIELD] = group;
2120
- }
2121
- if (!ptr[NG_DEPTH]) {
2122
- ptr[NG_DEPTH] = y;
2123
- }
2124
- if (!ptr[NG_COLUMN]) {
2125
- ptr[NG_COLUMN] = col;
2126
- }
2127
- ptr = ptr[val];
2128
- }
2129
- if (!ptr.values) {
2130
- ptr.values = [];
2131
- }
2132
- ptr.values.push(rows[x]);
2133
- }
2134
- if(cols.length > 0) {
2135
- for (var z = 0; z < groups.length; z++) {
2136
- if (!cols[z].isAggCol && z <= maxDepth) {
2137
- cols.splice(0, 0, new ngColumn({
2138
- colDef: {
2139
- field: '',
2140
- width: 25,
2141
- sortable: false,
2142
- resizable: false,
2143
- headerCellTemplate: '<div class="ngAggHeader"></div>',
2144
- pinned: grid.config.pinSelectionCheckbox
2145
- },
2146
- enablePinning: grid.config.enablePinning,
2147
- isAggCol: true,
2148
- headerRowHeight: grid.config.headerRowHeight
2149
- }, $scope, grid, domUtilityService, $templateCache, $utils));
2150
- }
2151
- }
2152
- }
2153
-
2154
- grid.fixColumnIndexes();
2155
- $scope.adjustScrollLeft(0);
2156
- self.parsedData.length = 0;
2157
- self.parseGroupData(self.groupedData);
2158
- self.fixRowCache();
2159
- };
2160
-
2161
- if (grid.config.groups.length > 0 && grid.filteredRows.length > 0) {
2162
- self.getGrouping(grid.config.groups);
2163
- }
2164
- };
2165
- var ngSearchProvider = function ($scope, grid, $filter) {
2166
- var self = this,
2167
- searchConditions = [];
2168
-
2169
- self.extFilter = grid.config.filterOptions.useExternalFilter;
2170
- $scope.showFilter = grid.config.showFilter;
2171
- $scope.filterText = '';
2172
-
2173
- self.fieldMap = {};
2174
-
2175
- var searchEntireRow = function(condition, item, fieldMap){
2176
- var result;
2177
- for (var prop in item) {
2178
- if (item.hasOwnProperty(prop)) {
2179
- var c = fieldMap[prop.toLowerCase()];
2180
- if (!c) {
2181
- continue;
2182
- }
2183
- var pVal = item[prop];
2184
- if(typeof pVal === 'object'){
2185
- return searchEntireRow(condition, pVal, c);
2186
- } else {
2187
- var f = null,
2188
- s = null;
2189
- if (c && c.cellFilter) {
2190
- s = c.cellFilter.split(':');
2191
- f = $filter(s[0]);
2192
- }
2193
- if (pVal !== null && pVal !== undefined) {
2194
- if (typeof f === "function") {
2195
- var filterRes = f(pVal, s[1]).toString();
2196
- result = condition.regex.test(filterRes);
2197
- } else {
2198
- result = condition.regex.test(pVal.toString());
2199
- }
2200
- if (result) {
2201
- return true;
2202
- }
2203
- }
2204
- }
2205
- }
2206
- }
2207
- return false;
2208
- };
2209
-
2210
- var searchColumn = function(condition, item){
2211
- var result;
2212
- var col = self.fieldMap[condition.columnDisplay];
2213
- if (!col) {
2214
- return false;
2215
- }
2216
- var sp = col.cellFilter.split(':');
2217
- var filter = col.cellFilter ? $filter(sp[0]) : null;
2218
- var value = item[condition.column] || item[col.field.split('.')[0]];
2219
- if (value === null || value === undefined) {
2220
- return false;
2221
- }
2222
- if (typeof filter === "function") {
2223
- var filterResults = filter(typeof value === "object" ? evalObject(value, col.field) : value, sp[1]).toString();
2224
- result = condition.regex.test(filterResults);
2225
- }
2226
- else {
2227
- result = condition.regex.test(typeof value === "object" ? evalObject(value, col.field).toString() : value.toString());
2228
- }
2229
- if (result) {
2230
- return true;
2231
- }
2232
- return false;
2233
- };
2234
-
2235
- var filterFunc = function(item) {
2236
- for (var x = 0, len = searchConditions.length; x < len; x++) {
2237
- var condition = searchConditions[x];
2238
- var result;
2239
- if (!condition.column) {
2240
- result = searchEntireRow(condition, item, self.fieldMap);
2241
- } else {
2242
- result = searchColumn(condition, item);
2243
- }
2244
- if(!result) {
2245
- return false;
2246
- }
2247
- }
2248
- return true;
2249
- };
2250
-
2251
- self.evalFilter = function () {
2252
- if (searchConditions.length === 0) {
2253
- grid.filteredRows = grid.rowCache;
2254
- } else {
2255
- grid.filteredRows = grid.rowCache.filter(function(row) {
2256
- return filterFunc(row.entity);
2257
- });
2258
- }
2259
- for (var i = 0; i < grid.filteredRows.length; i++)
2260
- {
2261
- grid.filteredRows[i].rowIndex = i;
2262
- }
2263
- grid.rowFactory.filteredRowsChanged();
2264
- };
2265
- var evalObject = function (obj, columnName) {
2266
- if (typeof obj !== "object" || typeof columnName !== "string") {
2267
- return obj;
2268
- }
2269
- var args = columnName.split('.');
2270
- var cObj = obj;
2271
- if (args.length > 1) {
2272
- for (var i = 1, len = args.length; i < len; i++) {
2273
- cObj = cObj[args[i]];
2274
- if (!cObj) {
2275
- return obj;
2276
- }
2277
- }
2278
- return cObj;
2279
- }
2280
- return obj;
2281
- };
2282
- var getRegExp = function (str, modifiers) {
2283
- try {
2284
- return new RegExp(str, modifiers);
2285
- } catch (err) {
2286
- return new RegExp(str.replace(/(\^|\$|\(|\)|<|>|\[|\]|\{|\}|\\|\||\.|\*|\+|\?)/g, '\\$1'));
2287
- }
2288
- };
2289
- var buildSearchConditions = function (a) {
2290
- searchConditions = [];
2291
- var qStr;
2292
- if (!(qStr = $.trim(a))) {
2293
- return;
2294
- }
2295
- var columnFilters = qStr.split(";");
2296
- for (var i = 0; i < columnFilters.length; i++) {
2297
- var args = columnFilters[i].split(':');
2298
- if (args.length > 1) {
2299
- var columnName = $.trim(args[0]);
2300
- var columnValue = $.trim(args[1]);
2301
- if (columnName && columnValue) {
2302
- searchConditions.push({
2303
- column: columnName,
2304
- columnDisplay: columnName.replace(/\s+/g, '').toLowerCase(),
2305
- regex: getRegExp(columnValue, 'i')
2306
- });
2307
- }
2308
- } else {
2309
- var val = $.trim(args[0]);
2310
- if (val) {
2311
- searchConditions.push({
2312
- column: '',
2313
- regex: getRegExp(val, 'i')
2314
- });
2315
- }
2316
- }
2317
- }
2318
- };
2319
-
2320
- if (!self.extFilter) {
2321
- $scope.$watch('columns', function (cs) {
2322
- for (var i = 0; i < cs.length; i++) {
2323
- var col = cs[i];
2324
- if (col.field) {
2325
- if(col.field.match(/\./g)){
2326
- var properties = col.field.split('.');
2327
- var currentProperty = self.fieldMap;
2328
- for(var j = 0; j < properties.length - 1; j++) {
2329
- currentProperty[ properties[j] ] = currentProperty[ properties[j] ] || {};
2330
- currentProperty = currentProperty[properties[j]];
2331
- }
2332
- currentProperty[ properties[properties.length - 1] ] = col;
2333
- } else {
2334
- self.fieldMap[col.field.toLowerCase()] = col;
2335
- }
2336
- }
2337
- if (col.displayName) {
2338
- self.fieldMap[col.displayName.toLowerCase().replace(/\s+/g, '')] = col;
2339
- }
2340
- }
2341
- });
2342
- }
2343
-
2344
- $scope.$watch(
2345
- function () {
2346
- return grid.config.filterOptions.filterText;
2347
- },
2348
- function (a) {
2349
- $scope.filterText = a;
2350
- }
2351
- );
2352
-
2353
- $scope.$watch('filterText', function(a){
2354
- if (!self.extFilter) {
2355
- $scope.$emit('ngGridEventFilter', a);
2356
- buildSearchConditions(a);
2357
- self.evalFilter();
2358
- }
2359
- });
2360
- };
2361
- var ngSelectionProvider = function (grid, $scope, $parse) {
2362
- var self = this;
2363
- self.multi = grid.config.multiSelect;
2364
- self.selectedItems = grid.config.selectedItems;
2365
- self.selectedIndex = grid.config.selectedIndex;
2366
- self.lastClickedRow = undefined;
2367
- self.ignoreSelectedItemChanges = false;
2368
- self.pKeyParser = $parse(grid.config.primaryKey);
2369
- self.ChangeSelection = function (rowItem, evt) {
2370
- var charCode = evt.which || evt.keyCode;
2371
- var isUpDownKeyPress = (charCode === 40 || charCode === 38);
2372
-
2373
- if (evt && evt.shiftKey && !evt.keyCode && self.multi && grid.config.enableRowSelection) {
2374
- if (self.lastClickedRow) {
2375
- var rowsArr;
2376
- if ($scope.configGroups.length > 0) {
2377
- rowsArr = grid.rowFactory.parsedData.filter(function(row) {
2378
- return !row.isAggRow;
2379
- });
2380
- }
2381
- else {
2382
- rowsArr = grid.filteredRows;
2383
- }
2384
-
2385
- var thisIndx = rowItem.rowIndex;
2386
- var prevIndx = self.lastClickedRowIndex;
2387
- if (thisIndx === prevIndx) {
2388
- return false;
2389
- }
2390
-
2391
- if (thisIndx < prevIndx) {
2392
- thisIndx = thisIndx ^ prevIndx;
2393
- prevIndx = thisIndx ^ prevIndx;
2394
- thisIndx = thisIndx ^ prevIndx;
2395
- thisIndx--;
2396
- }
2397
- else {
2398
- prevIndx++;
2399
- }
2400
-
2401
- var rows = [];
2402
- for (; prevIndx <= thisIndx; prevIndx++) {
2403
- rows.push(rowsArr[prevIndx]);
2404
- }
2405
-
2406
- if (rows[rows.length - 1].beforeSelectionChange(rows, evt)) {
2407
- for (var i = 0; i < rows.length; i++) {
2408
- var ri = rows[i];
2409
- var selectionState = ri.selected;
2410
- ri.selected = !selectionState;
2411
- if (ri.clone) {
2412
- ri.clone.selected = ri.selected;
2413
- }
2414
- var index = self.selectedItems.indexOf(ri.entity);
2415
- if (index === -1) {
2416
- self.selectedItems.push(ri.entity);
2417
- }
2418
- else {
2419
- self.selectedItems.splice(index, 1);
2420
- }
2421
- }
2422
- rows[rows.length - 1].afterSelectionChange(rows, evt);
2423
- }
2424
- self.lastClickedRow = rowItem;
2425
- self.lastClickedRowIndex = rowItem.rowIndex;
2426
-
2427
- return true;
2428
- }
2429
- }
2430
- else if (!self.multi) {
2431
- if (self.lastClickedRow === rowItem) {
2432
- self.setSelection(self.lastClickedRow, grid.config.keepLastSelected ? true : !rowItem.selected);
2433
- } else {
2434
- if (self.lastClickedRow) {
2435
- self.setSelection(self.lastClickedRow, false);
2436
- }
2437
- self.setSelection(rowItem, !rowItem.selected);
2438
- }
2439
- }
2440
- else if (!evt.keyCode || isUpDownKeyPress && !grid.config.selectWithCheckboxOnly) {
2441
- self.setSelection(rowItem, !rowItem.selected);
2442
- }
2443
- self.lastClickedRow = rowItem;
2444
- self.lastClickedRowIndex = rowItem.rowIndex;
2445
- return true;
2446
- };
2447
-
2448
- self.getSelection = function (entity) {
2449
- var isSelected = false;
2450
- if (grid.config.primaryKey) {
2451
- var val = self.pKeyParser(entity);
2452
- angular.forEach(self.selectedItems, function (c) {
2453
- if (val === self.pKeyParser(c)) {
2454
- isSelected = true;
2455
- }
2456
- });
2457
- }
2458
- else {
2459
- isSelected = self.selectedItems.indexOf(entity) !== -1;
2460
- }
2461
- return isSelected;
2462
- };
2463
- self.setSelection = function (rowItem, isSelected) {
2464
- if(grid.config.enableRowSelection){
2465
- if (!isSelected) {
2466
- var indx = self.selectedItems.indexOf(rowItem.entity);
2467
- if (indx !== -1) {
2468
- self.selectedItems.splice(indx, 1);
2469
- }
2470
- }
2471
- else {
2472
- if (self.selectedItems.indexOf(rowItem.entity) === -1) {
2473
- if (!self.multi && self.selectedItems.length > 0) {
2474
- self.toggleSelectAll(false, true);
2475
- }
2476
- self.selectedItems.push(rowItem.entity);
2477
- }
2478
- }
2479
- rowItem.selected = isSelected;
2480
- if (rowItem.orig) {
2481
- rowItem.orig.selected = isSelected;
2482
- }
2483
- if (rowItem.clone) {
2484
- rowItem.clone.selected = isSelected;
2485
- }
2486
- rowItem.afterSelectionChange(rowItem);
2487
- }
2488
- };
2489
- self.toggleSelectAll = function (checkAll, bypass, selectFiltered) {
2490
- var rows = selectFiltered ? grid.filteredRows : grid.rowCache;
2491
- if (bypass || grid.config.beforeSelectionChange(rows, checkAll)) {
2492
- var selectedlength = self.selectedItems.length;
2493
- if (selectedlength > 0) {
2494
- self.selectedItems.length = 0;
2495
- }
2496
- for (var i = 0; i < rows.length; i++) {
2497
- rows[i].selected = checkAll;
2498
- if (rows[i].clone) {
2499
- rows[i].clone.selected = checkAll;
2500
- }
2501
- if (checkAll) {
2502
- self.selectedItems.push(rows[i].entity);
2503
- }
2504
- }
2505
- if (!bypass) {
2506
- grid.config.afterSelectionChange(rows, checkAll);
2507
- }
2508
- }
2509
- };
2510
- };
2511
- var ngStyleProvider = function($scope, grid) {
2512
- $scope.headerCellStyle = function(col) {
2513
- return { "height": col.headerRowHeight + "px" };
2514
- };
2515
- $scope.rowStyle = function (row) {
2516
- var ret = { "top": row.offsetTop + "px", "height": $scope.rowHeight + "px" };
2517
- if (row.isAggRow) {
2518
- ret.left = row.offsetLeft;
2519
- }
2520
- return ret;
2521
- };
2522
- $scope.canvasStyle = function() {
2523
- return { "height": grid.maxCanvasHt + "px" };
2524
- };
2525
- $scope.headerScrollerStyle = function() {
2526
- return { "height": grid.config.headerRowHeight + "px" };
2527
- };
2528
- $scope.topPanelStyle = function() {
2529
- return { "width": grid.rootDim.outerWidth + "px", "height": $scope.topPanelHeight() + "px" };
2530
- };
2531
- $scope.headerStyle = function() {
2532
- return { "width": grid.rootDim.outerWidth + "px", "height": grid.config.headerRowHeight + "px" };
2533
- };
2534
- $scope.groupPanelStyle = function () {
2535
- return { "width": grid.rootDim.outerWidth + "px", "height": "32px" };
2536
- };
2537
- $scope.viewportStyle = function() {
2538
- return { "width": grid.rootDim.outerWidth + "px", "height": $scope.viewportDimHeight() + "px" };
2539
- };
2540
- $scope.footerStyle = function() {
2541
- return { "width": grid.rootDim.outerWidth + "px", "height": $scope.footerRowHeight + "px" };
2542
- };
2543
- };
2544
- ngGridDirectives.directive('ngCellHasFocus', ['$domUtilityService',
2545
- function (domUtilityService) {
2546
- var focusOnInputElement = function($scope, elm) {
2547
- $scope.isFocused = true;
2548
- domUtilityService.digest($scope);
2549
-
2550
- $scope.$broadcast('ngGridEventStartCellEdit');
2551
-
2552
- $scope.$on('ngGridEventEndCellEdit', function() {
2553
- $scope.isFocused = false;
2554
- domUtilityService.digest($scope);
2555
- });
2556
- };
2557
-
2558
- return function($scope, elm) {
2559
- var isFocused = false;
2560
- var isCellEditableOnMouseDown = false;
2561
-
2562
- $scope.editCell = function() {
2563
- if(!$scope.enableCellEditOnFocus) {
2564
- setTimeout(function() {
2565
- focusOnInputElement($scope,elm);
2566
- }, 0);
2567
- }
2568
- };
2569
- elm.bind('mousedown', function(evt) {
2570
- if($scope.enableCellEditOnFocus) {
2571
- isCellEditableOnMouseDown = true;
2572
- } else {
2573
- elm.focus();
2574
- }
2575
- return true;
2576
- });
2577
- elm.bind('click', function(evt) {
2578
- if($scope.enableCellEditOnFocus) {
2579
- evt.preventDefault();
2580
- isCellEditableOnMouseDown = false;
2581
- focusOnInputElement($scope,elm);
2582
- }
2583
- });
2584
- elm.bind('focus', function(evt) {
2585
- isFocused = true;
2586
- if($scope.enableCellEditOnFocus && !isCellEditableOnMouseDown) {
2587
- focusOnInputElement($scope,elm);
2588
- }
2589
- return true;
2590
- });
2591
- elm.bind('blur', function() {
2592
- isFocused = false;
2593
- return true;
2594
- });
2595
- elm.bind('keydown', function(evt) {
2596
- if(!$scope.enableCellEditOnFocus) {
2597
- if (isFocused && evt.keyCode !== 37 && evt.keyCode !== 38 && evt.keyCode !== 39 && evt.keyCode !== 40 && evt.keyCode !== 9 && !evt.shiftKey && evt.keyCode !== 13) {
2598
- focusOnInputElement($scope,elm);
2599
- }
2600
- if (isFocused && evt.shiftKey && (evt.keyCode >= 65 && evt.keyCode <= 90)) {
2601
- focusOnInputElement($scope, elm);
2602
- }
2603
- if (evt.keyCode === 27) {
2604
- elm.focus();
2605
- }
2606
- }
2607
- return true;
2608
- });
2609
- };
2610
- }]);
2611
- ngGridDirectives.directive('ngCellText',
2612
- function () {
2613
- return function(scope, elm) {
2614
- elm.bind('mouseover', function(evt) {
2615
- evt.preventDefault();
2616
- elm.css({
2617
- 'cursor': 'text'
2618
- });
2619
- });
2620
- elm.bind('mouseleave', function(evt) {
2621
- evt.preventDefault();
2622
- elm.css({
2623
- 'cursor': 'default'
2624
- });
2625
- });
2626
- };
2627
- });
2628
- ngGridDirectives.directive('ngCell', ['$compile', '$domUtilityService', function ($compile, domUtilityService) {
2629
- var ngCell = {
2630
- scope: false,
2631
- compile: function() {
2632
- return {
2633
- pre: function($scope, iElement) {
2634
- var html;
2635
- var cellTemplate = $scope.col.cellTemplate.replace(COL_FIELD, 'row.entity.' + $scope.col.field);
2636
-
2637
- if ($scope.col.enableCellEdit) {
2638
- html = $scope.col.cellEditTemplate;
2639
- html = html.replace(DISPLAY_CELL_TEMPLATE, cellTemplate);
2640
- html = html.replace(EDITABLE_CELL_TEMPLATE, $scope.col.editableCellTemplate.replace(COL_FIELD, 'row.entity.' + $scope.col.field));
2641
- } else {
2642
- html = cellTemplate;
2643
- }
2644
-
2645
- var cellElement = $compile(html)($scope);
2646
-
2647
- if ($scope.enableCellSelection && cellElement[0].className.indexOf('ngSelectionCell') === -1) {
2648
- cellElement[0].setAttribute('tabindex', 0);
2649
- cellElement.addClass('ngCellElement');
2650
- }
2651
-
2652
- iElement.append(cellElement);
2653
- },
2654
- post: function($scope, iElement) {
2655
- if ($scope.enableCellSelection) {
2656
- $scope.domAccessProvider.selectionHandlers($scope, iElement);
2657
- }
2658
- $scope.$on('ngGridEventDigestCell', function() {
2659
- domUtilityService.digest($scope);
2660
- });
2661
- }
2662
- };
2663
- }
2664
- };
2665
- return ngCell;
2666
- }]);
2667
-
2668
- ngGridDirectives.directive('ngEditCellIf', [function () {
2669
- return {
2670
- transclude: 'element',
2671
- priority: 1000,
2672
- terminal: true,
2673
- restrict: 'A',
2674
- compile: function (e, a, transclude) {
2675
- return function (scope, element, attr) {
2676
-
2677
- var childElement;
2678
- var childScope;
2679
- scope.$watch(attr['ngEditCellIf'], function (newValue) {
2680
- if (childElement) {
2681
- childElement.remove();
2682
- childElement = undefined;
2683
- }
2684
- if (childScope) {
2685
- childScope.$destroy();
2686
- childScope = undefined;
2687
- }
2688
-
2689
- if (newValue) {
2690
- childScope = scope.$new();
2691
- transclude(childScope, function (clone) {
2692
- childElement = clone;
2693
- element.after(clone);
2694
- });
2695
- }
2696
- });
2697
- };
2698
- }
2699
- };
2700
- }]);
2701
- ngGridDirectives.directive('ngGridFooter', ['$compile', '$templateCache', function ($compile, $templateCache) {
2702
- var ngGridFooter = {
2703
- scope: false,
2704
- compile: function () {
2705
- return {
2706
- pre: function ($scope, iElement) {
2707
- if (iElement.children().length === 0) {
2708
- iElement.append($compile($templateCache.get($scope.gridId + 'footerTemplate.html'))($scope));
2709
- }
2710
- }
2711
- };
2712
- }
2713
- };
2714
- return ngGridFooter;
2715
- }]);
2716
- ngGridDirectives.directive('ngGridMenu', ['$compile', '$templateCache', function ($compile, $templateCache) {
2717
- var ngGridMenu = {
2718
- scope: false,
2719
- compile: function () {
2720
- return {
2721
- pre: function ($scope, iElement) {
2722
- if (iElement.children().length === 0) {
2723
- iElement.append($compile($templateCache.get($scope.gridId + 'menuTemplate.html'))($scope));
2724
- }
2725
- }
2726
- };
2727
- }
2728
- };
2729
- return ngGridMenu;
2730
- }]);
2731
- ngGridDirectives.directive('ngGrid', ['$compile', '$filter', '$templateCache', '$sortService', '$domUtilityService', '$utilityService', '$timeout', '$parse', '$http', '$q', function ($compile, $filter, $templateCache, sortService, domUtilityService, $utils, $timeout, $parse, $http, $q) {
2732
- var ngGridDirective = {
2733
- scope: true,
2734
- compile: function() {
2735
- return {
2736
- pre: function($scope, iElement, iAttrs) {
2737
- var $element = $(iElement);
2738
- var options = $scope.$eval(iAttrs.ngGrid);
2739
-
2740
- options.gridDim = new ngDimension({ outerHeight: $($element).height(), outerWidth: $($element).width() });
2741
-
2742
- var grid = new ngGrid($scope, options, sortService, domUtilityService, $filter, $templateCache, $utils, $timeout, $parse, $http, $q);
2743
- return grid.init().then(function() {
2744
- if (typeof options.columnDefs === "string") {
2745
- $scope.$parent.$watch(options.columnDefs, function (a) {
2746
- if (!a) {
2747
- grid.refreshDomSizes();
2748
- grid.buildColumns();
2749
- return;
2750
- }
2751
- grid.lateBoundColumns = false;
2752
- $scope.columns = [];
2753
- grid.config.columnDefs = a;
2754
- grid.buildColumns();
2755
- grid.eventProvider.assignEvents();
2756
- domUtilityService.RebuildGrid($scope, grid);
2757
- }, true);
2758
- }
2759
- else {
2760
- grid.buildColumns();
2761
- }
2762
- if (typeof options.totalServerItems === "string") {
2763
- $scope.$parent.$watch(options.totalServerItems, function (newTotal, oldTotal) {
2764
- if (!angular.isDefined(newTotal)) {
2765
- $scope.totalServerItems = 0;
2766
- }
2767
- else {
2768
- $scope.totalServerItems = newTotal;
2769
- }
2770
- });
2771
- }
2772
- else {
2773
- $scope.totalServerItems = 0;
2774
- }
2775
- if (typeof options.data === "string") {
2776
- var dataWatcher = function (a) {
2777
- grid.data = $.extend([], a);
2778
- grid.rowFactory.fixRowCache();
2779
- angular.forEach(grid.data, function (item, j) {
2780
- var indx = grid.rowMap[j] || j;
2781
- if (grid.rowCache[indx]) {
2782
- grid.rowCache[indx].ensureEntity(item);
2783
- }
2784
- grid.rowMap[indx] = j;
2785
- });
2786
- grid.searchProvider.evalFilter();
2787
- grid.configureColumnWidths();
2788
- grid.refreshDomSizes();
2789
- if (grid.config.sortInfo.fields.length > 0) {
2790
- grid.sortColumnsInit();
2791
- $scope.$emit('ngGridEventSorted', grid.config.sortInfo);
2792
- }
2793
- $scope.$emit("ngGridEventData", grid.gridId);
2794
- };
2795
- $scope.$parent.$watch(options.data, dataWatcher);
2796
- $scope.$parent.$watch(options.data + '.length', function() {
2797
- dataWatcher($scope.$eval(options.data));
2798
- });
2799
- }
2800
- grid.footerController = new ngFooter($scope, grid);
2801
- iElement.addClass("ngGrid").addClass(grid.gridId.toString());
2802
- if (!options.enableHighlighting) {
2803
- iElement.addClass("unselectable");
2804
- }
2805
- if (options.jqueryUITheme) {
2806
- iElement.addClass('ui-widget');
2807
- }
2808
- iElement.append($compile($templateCache.get('gridTemplate.html'))($scope));
2809
- domUtilityService.AssignGridContainers($scope, iElement, grid);
2810
- grid.eventProvider = new ngEventProvider(grid, $scope, domUtilityService, $timeout);
2811
- options.selectRow = function (rowIndex, state) {
2812
- if (grid.rowCache[rowIndex]) {
2813
- if (grid.rowCache[rowIndex].clone) {
2814
- grid.rowCache[rowIndex].clone.setSelection(state ? true : false);
2815
- }
2816
- grid.rowCache[rowIndex].setSelection(state ? true : false);
2817
- }
2818
- };
2819
- options.selectItem = function (itemIndex, state) {
2820
- options.selectRow(grid.rowMap[itemIndex], state);
2821
- };
2822
- options.selectAll = function (state) {
2823
- $scope.toggleSelectAll(state);
2824
- };
2825
- options.selectVisible = function (state) {
2826
- $scope.toggleSelectAll(state, true);
2827
- };
2828
- options.groupBy = function (field) {
2829
- if (field) {
2830
- $scope.groupBy($scope.columns.filter(function(c) {
2831
- return c.field === field;
2832
- })[0]);
2833
- } else {
2834
- var arr = $.extend(true, [], $scope.configGroups);
2835
- angular.forEach(arr, $scope.groupBy);
2836
- }
2837
- };
2838
- options.sortBy = function (field) {
2839
- var col = $scope.columns.filter(function (c) {
2840
- return c.field === field;
2841
- })[0];
2842
- if (col) {
2843
- col.sort();
2844
- }
2845
- };
2846
- options.gridId = grid.gridId;
2847
- options.ngGrid = grid;
2848
- options.$gridScope = $scope;
2849
- options.$gridServices = { SortService: sortService, DomUtilityService: domUtilityService, UtilityService: $utils };
2850
- $scope.$on('ngGridEventDigestGrid', function(){
2851
- domUtilityService.digest($scope.$parent);
2852
- });
2853
- $scope.$on('ngGridEventDigestGridParent', function(){
2854
- domUtilityService.digest($scope.$parent);
2855
- });
2856
- $scope.$evalAsync(function() {
2857
- $scope.adjustScrollLeft(0);
2858
- });
2859
- angular.forEach(options.plugins, function (p) {
2860
- if (typeof p === "function") {
2861
- p = new p();
2862
- }
2863
- p.init($scope.$new(), grid, options.$gridServices);
2864
- options.plugins[$utils.getInstanceType(p)] = p;
2865
- });
2866
- if (typeof options.init === "function") {
2867
- options.init(grid, $scope);
2868
- }
2869
- return null;
2870
- });
2871
- }
2872
- };
2873
- }
2874
- };
2875
- return ngGridDirective;
2876
- }]);
2877
-
2878
- ngGridDirectives.directive('ngHeaderCell', ['$compile', function($compile) {
2879
- var ngHeaderCell = {
2880
- scope: false,
2881
- compile: function() {
2882
- return {
2883
- pre: function($scope, iElement) {
2884
- iElement.append($compile($scope.col.headerCellTemplate)($scope));
2885
- }
2886
- };
2887
- }
2888
- };
2889
- return ngHeaderCell;
2890
- }]);
2891
- ngGridDirectives.directive('ngInput', [function() {
2892
- return {
2893
- require: 'ngModel',
2894
- link: function (scope, elm, attrs, ngModel) {
2895
- var oldCellValue;
2896
- var dereg = scope.$watch('ngModel', function() {
2897
- oldCellValue = ngModel.$modelValue;
2898
- dereg();
2899
- });
2900
- elm.bind('keydown', function(evt) {
2901
- switch (evt.keyCode) {
2902
- case 37:
2903
- case 38:
2904
- case 39:
2905
- case 40:
2906
- evt.stopPropagation();
2907
- break;
2908
- case 27:
2909
- if (!scope.$$phase) {
2910
- scope.$apply(function() {
2911
- ngModel.$setViewValue(oldCellValue);
2912
- elm.blur();
2913
- });
2914
- }
2915
- break;
2916
- case 13:
2917
- if(scope.enableCellEditOnFocus && scope.totalFilteredItemsLength() - 1 > scope.row.rowIndex && scope.row.rowIndex > 0 || scope.enableCellEdit) {
2918
- elm.blur();
2919
- }
2920
- break;
2921
- }
2922
-
2923
- return true;
2924
- });
2925
-
2926
- elm.bind('click', function(evt) {
2927
- evt.stopPropagation();
2928
- });
2929
- elm.bind('mousedown', function(evt) {
2930
- evt.stopPropagation();
2931
- });
2932
- scope.$on('ngGridEventStartCellEdit', function () {
2933
- elm.focus();
2934
- elm.select();
2935
- });
2936
-
2937
- angular.element(elm).bind('blur', function () {
2938
- scope.$emit('ngGridEventEndCellEdit');
2939
- });
2940
- }
2941
- };
2942
- }]);
2943
- ngGridDirectives.directive('ngRow', ['$compile', '$domUtilityService', '$templateCache', function ($compile, domUtilityService, $templateCache) {
2944
- var ngRow = {
2945
- scope: false,
2946
- compile: function() {
2947
- return {
2948
- pre: function($scope, iElement) {
2949
- $scope.row.elm = iElement;
2950
- if ($scope.row.clone) {
2951
- $scope.row.clone.elm = iElement;
2952
- }
2953
- if ($scope.row.isAggRow) {
2954
- var html = $templateCache.get($scope.gridId + 'aggregateTemplate.html');
2955
- if ($scope.row.aggLabelFilter) {
2956
- html = html.replace(CUSTOM_FILTERS, '| ' + $scope.row.aggLabelFilter);
2957
- } else {
2958
- html = html.replace(CUSTOM_FILTERS, "");
2959
- }
2960
- iElement.append($compile(html)($scope));
2961
- } else {
2962
- iElement.append($compile($templateCache.get($scope.gridId + 'rowTemplate.html'))($scope));
2963
- }
2964
- $scope.$on('ngGridEventDigestRow', function(){
2965
- domUtilityService.digest($scope);
2966
- });
2967
- }
2968
- };
2969
- }
2970
- };
2971
- return ngRow;
2972
- }]);
2973
- ngGridDirectives.directive('ngViewport', [function() {
2974
- return function($scope, elm) {
2975
- var isMouseWheelActive;
2976
- var prevScollLeft;
2977
- var prevScollTop = 0;
2978
- elm.bind('scroll', function(evt) {
2979
- var scrollLeft = evt.target.scrollLeft,
2980
- scrollTop = evt.target.scrollTop;
2981
- if ($scope.$headerContainer) {
2982
- $scope.$headerContainer.scrollLeft(scrollLeft);
2983
- }
2984
- $scope.adjustScrollLeft(scrollLeft);
2985
- $scope.adjustScrollTop(scrollTop);
2986
- if (!$scope.$root.$$phase) {
2987
- $scope.$digest();
2988
- }
2989
- prevScollLeft = scrollLeft;
2990
- prevScollTop = scrollTop;
2991
- isMouseWheelActive = false;
2992
- return true;
2993
- });
2994
- elm.bind("mousewheel DOMMouseScroll", function() {
2995
- isMouseWheelActive = true;
2996
- if (elm.focus) { elm.focus(); }
2997
- return true;
2998
- });
2999
- if (!$scope.enableCellSelection) {
3000
- $scope.domAccessProvider.selectionHandlers($scope, elm);
3001
- }
3002
- };
3003
- }]);
3004
- window.ngGrid.i18n['da'] = {
3005
- ngAggregateLabel: 'artikler',
3006
- ngGroupPanelDescription: 'Grupér rækker udfra en kolonne ved at trække dens overskift hertil.',
3007
- ngSearchPlaceHolder: 'Søg...',
3008
- ngMenuText: 'Vælg kolonner:',
3009
- ngShowingItemsLabel: 'Viste rækker:',
3010
- ngTotalItemsLabel: 'Rækker totalt:',
3011
- ngSelectedItemsLabel: 'Valgte rækker:',
3012
- ngPageSizeLabel: 'Side størrelse:',
3013
- ngPagerFirstTitle: 'Første side',
3014
- ngPagerNextTitle: 'Næste side',
3015
- ngPagerPrevTitle: 'Forrige side',
3016
- ngPagerLastTitle: 'Sidste side'
3017
- };
3018
- window.ngGrid.i18n['de'] = {
3019
- ngAggregateLabel: 'artikel',
3020
- ngGroupPanelDescription: 'Ziehen Sie eine Spaltenüberschrift hier und legen Sie es der Gruppe nach dieser Spalte.',
3021
- ngSearchPlaceHolder: 'Suche...',
3022
- ngMenuText: 'Spalten auswählen:',
3023
- ngShowingItemsLabel: 'Zeige Artikel:',
3024
- ngTotalItemsLabel: 'Meiste Artikel:',
3025
- ngSelectedItemsLabel: 'Ausgewählte Artikel:',
3026
- ngPageSizeLabel: 'Größe Seite:',
3027
- ngPagerFirstTitle: 'Erste Page',
3028
- ngPagerNextTitle: 'Nächste Page',
3029
- ngPagerPrevTitle: 'Vorherige Page',
3030
- ngPagerLastTitle: 'Letzte Page'
3031
- };
3032
- window.ngGrid.i18n['en'] = {
3033
- ngAggregateLabel: 'items',
3034
- ngGroupPanelDescription: 'Drag a column header here and drop it to group by that column.',
3035
- ngSearchPlaceHolder: 'Search...',
3036
- ngMenuText: 'Choose Columns:',
3037
- ngShowingItemsLabel: 'Showing Items:',
3038
- ngTotalItemsLabel: 'Total Items:',
3039
- ngSelectedItemsLabel: 'Selected Items:',
3040
- ngPageSizeLabel: 'Page Size:',
3041
- ngPagerFirstTitle: 'First Page',
3042
- ngPagerNextTitle: 'Next Page',
3043
- ngPagerPrevTitle: 'Previous Page',
3044
- ngPagerLastTitle: 'Last Page'
3045
- };
3046
- window.ngGrid.i18n['es'] = {
3047
- ngAggregateLabel: 'Artículos',
3048
- ngGroupPanelDescription: 'Arrastre un encabezado de columna aquí y soltarlo para agrupar por esa columna.',
3049
- ngSearchPlaceHolder: 'Buscar...',
3050
- ngMenuText: 'Elegir columnas:',
3051
- ngShowingItemsLabel: 'Artículos Mostrando:',
3052
- ngTotalItemsLabel: 'Artículos Totales:',
3053
- ngSelectedItemsLabel: 'Artículos Seleccionados:',
3054
- ngPageSizeLabel: 'Tamaño de Página:',
3055
- ngPagerFirstTitle: 'Primera Página',
3056
- ngPagerNextTitle: 'Página Siguiente',
3057
- ngPagerPrevTitle: 'Página Anterior',
3058
- ngPagerLastTitle: 'Última Página'
3059
- };
3060
- window.ngGrid.i18n['fr'] = {
3061
- ngAggregateLabel: 'articles',
3062
- ngGroupPanelDescription: 'Faites glisser un en-tête de colonne ici et déposez-le vers un groupe par cette colonne.',
3063
- ngSearchPlaceHolder: 'Recherche...',
3064
- ngMenuText: 'Choisir des colonnes:',
3065
- ngShowingItemsLabel: 'Articles Affichage des:',
3066
- ngTotalItemsLabel: 'Nombre total d\'articles:',
3067
- ngSelectedItemsLabel: 'Éléments Articles:',
3068
- ngPageSizeLabel: 'Taille de page:',
3069
- ngPagerFirstTitle: 'Première page',
3070
- ngPagerNextTitle: 'Page Suivante',
3071
- ngPagerPrevTitle: 'Page précédente',
3072
- ngPagerLastTitle: 'Dernière page'
3073
- };
3074
- window.ngGrid.i18n['pt-br'] = {
3075
- ngAggregateLabel: 'items',
3076
- ngGroupPanelDescription: 'Arraste e solte uma coluna aqui para agrupar por essa coluna',
3077
- ngSearchPlaceHolder: 'Procurar...',
3078
- ngMenuText: 'Selecione as colunas:',
3079
- ngShowingItemsLabel: 'Mostrando os Items:',
3080
- ngTotalItemsLabel: 'Total de Items:',
3081
- ngSelectedItemsLabel: 'Items Selecionados:',
3082
- ngPageSizeLabel: 'Tamanho da Página:',
3083
- ngPagerFirstTitle: 'Primeira Página',
3084
- ngPagerNextTitle: 'Próxima Página',
3085
- ngPagerPrevTitle: 'Página Anterior',
3086
- ngPagerLastTitle: 'Última Página'
3087
- };
3088
- window.ngGrid.i18n['zh-cn'] = {
3089
- ngAggregateLabel: '条目',
3090
- ngGroupPanelDescription: '拖曳表头到此处以进行分组',
3091
- ngSearchPlaceHolder: '搜索...',
3092
- ngMenuText: '数据分组与选择列:',
3093
- ngShowingItemsLabel: '当前显示条目:',
3094
- ngTotalItemsLabel: '条目总数:',
3095
- ngSelectedItemsLabel: '选中条目:',
3096
- ngPageSizeLabel: '每页显示数:',
3097
- ngPagerFirstTitle: '回到首页',
3098
- ngPagerNextTitle: '下一页',
3099
- ngPagerPrevTitle: '上一页',
3100
- ngPagerLastTitle: '前往尾页'
3101
- };
3102
-
3103
- window.ngGrid.i18n['zh-tw'] = {
3104
- ngAggregateLabel: '筆',
3105
- ngGroupPanelDescription: '拖拉表頭到此處以進行分組',
3106
- ngSearchPlaceHolder: '搜尋...',
3107
- ngMenuText: '選擇欄位:',
3108
- ngShowingItemsLabel: '目前顯示筆數:',
3109
- ngTotalItemsLabel: '總筆數:',
3110
- ngSelectedItemsLabel: '選取筆數:',
3111
- ngPageSizeLabel: '每頁顯示:',
3112
- ngPagerFirstTitle: '第一頁',
3113
- ngPagerNextTitle: '下一頁',
3114
- ngPagerPrevTitle: '上一頁',
3115
- ngPagerLastTitle: '最後頁'
3116
- };
3117
-
3118
- angular.module("ngGrid").run(["$templateCache", function($templateCache) {
3119
-
3120
- $templateCache.put("aggregateTemplate.html",
3121
- "<div ng-click=\"row.toggleExpand()\" ng-style=\"rowStyle(row)\" class=\"ngAggregate\">" +
3122
- " <span class=\"ngAggregateText\">{{row.label CUSTOM_FILTERS}} ({{row.totalChildren()}} {{AggItemsLabel}})</span>" +
3123
- " <div class=\"{{row.aggClass()}}\"></div>" +
3124
- "</div>" +
3125
- ""
3126
- );
3127
-
3128
- $templateCache.put("cellEditTemplate.html",
3129
- "<div ng-cell-has-focus ng-dblclick=\"editCell()\">" +
3130
- " <div ng-edit-cell-if=\"!isFocused\"> " +
3131
- " DISPLAY_CELL_TEMPLATE" +
3132
- " </div>" +
3133
- " <div ng-edit-cell-if=\"isFocused\">" +
3134
- " EDITABLE_CELL_TEMPLATE" +
3135
- " </div>" +
3136
- "</div>"
3137
- );
3138
-
3139
- $templateCache.put("cellTemplate.html",
3140
- "<div class=\"ngCellText\" ng-class=\"col.colIndex()\"><span ng-cell-text>{{COL_FIELD CUSTOM_FILTERS}}</span></div>"
3141
- );
3142
-
3143
- $templateCache.put("checkboxCellTemplate.html",
3144
- "<div class=\"ngSelectionCell\"><input tabindex=\"-1\" class=\"ngSelectionCheckbox\" type=\"checkbox\" ng-checked=\"row.selected\" /></div>"
3145
- );
3146
-
3147
- $templateCache.put("checkboxHeaderTemplate.html",
3148
- "<input class=\"ngSelectionHeader\" type=\"checkbox\" ng-show=\"multiSelect\" ng-model=\"allSelected\" ng-change=\"toggleSelectAll(allSelected, true)\"/>"
3149
- );
3150
-
3151
- $templateCache.put("editableCellTemplate.html",
3152
- "<input ng-class=\"'colt' + col.index\" ng-input=\"COL_FIELD\" ng-model=\"COL_FIELD\" />"
3153
- );
3154
-
3155
- $templateCache.put("footerTemplate.html",
3156
- "<div ng-show=\"showFooter\" class=\"ngFooterPanel\" ng-class=\"{'ui-widget-content': jqueryUITheme, 'ui-corner-bottom': jqueryUITheme}\" ng-style=\"footerStyle()\">" +
3157
- " <div class=\"ngTotalSelectContainer\" >" +
3158
- " <div class=\"ngFooterTotalItems\" ng-class=\"{'ngNoMultiSelect': !multiSelect}\" >" +
3159
- " <span class=\"ngLabel\">{{i18n.ngTotalItemsLabel}} {{maxRows()}}</span><span ng-show=\"filterText.length > 0\" class=\"ngLabel\">({{i18n.ngShowingItemsLabel}} {{totalFilteredItemsLength()}})</span>" +
3160
- " </div>" +
3161
- " <div class=\"ngFooterSelectedItems\" ng-show=\"multiSelect\">" +
3162
- " <span class=\"ngLabel\">{{i18n.ngSelectedItemsLabel}} {{selectedItems.length}}</span>" +
3163
- " </div>" +
3164
- " </div>" +
3165
- " <div class=\"ngPagerContainer\" style=\"float: right; margin-top: 10px;\" ng-show=\"enablePaging\" ng-class=\"{'ngNoMultiSelect': !multiSelect}\">" +
3166
- " <div style=\"float:left; margin-right: 10px;\" class=\"ngRowCountPicker\">" +
3167
- " <span style=\"float: left; margin-top: 3px;\" class=\"ngLabel\">{{i18n.ngPageSizeLabel}}</span>" +
3168
- " <select style=\"float: left;height: 27px; width: 100px\" ng-model=\"pagingOptions.pageSize\" >" +
3169
- " <option ng-repeat=\"size in pagingOptions.pageSizes\">{{size}}</option>" +
3170
- " </select>" +
3171
- " </div>" +
3172
- " <div style=\"float:left; margin-right: 10px; line-height:25px;\" class=\"ngPagerControl\" style=\"float: left; min-width: 135px;\">" +
3173
- " <button class=\"ngPagerButton\" ng-click=\"pageToFirst()\" ng-disabled=\"cantPageBackward()\" title=\"{{i18n.ngPagerFirstTitle}}\"><div class=\"ngPagerFirstTriangle\"><div class=\"ngPagerFirstBar\"></div></div></button>" +
3174
- " <button class=\"ngPagerButton\" ng-click=\"pageBackward()\" ng-disabled=\"cantPageBackward()\" title=\"{{i18n.ngPagerPrevTitle}}\"><div class=\"ngPagerFirstTriangle ngPagerPrevTriangle\"></div></button>" +
3175
- " <input class=\"ngPagerCurrent\" min=\"1\" max=\"{{maxPages()}}\" type=\"number\" style=\"width:50px; height: 24px; margin-top: 1px; padding: 0 4px;\" ng-model=\"pagingOptions.currentPage\"/>" +
3176
- " <button class=\"ngPagerButton\" ng-click=\"pageForward()\" ng-disabled=\"cantPageForward()\" title=\"{{i18n.ngPagerNextTitle}}\"><div class=\"ngPagerLastTriangle ngPagerNextTriangle\"></div></button>" +
3177
- " <button class=\"ngPagerButton\" ng-click=\"pageToLast()\" ng-disabled=\"cantPageToLast()\" title=\"{{i18n.ngPagerLastTitle}}\"><div class=\"ngPagerLastTriangle\"><div class=\"ngPagerLastBar\"></div></div></button>" +
3178
- " </div>" +
3179
- " </div>" +
3180
- "</div>"
3181
- );
3182
-
3183
- $templateCache.put("gridTemplate.html",
3184
- "<div class=\"ngTopPanel\" ng-class=\"{'ui-widget-header':jqueryUITheme, 'ui-corner-top': jqueryUITheme}\" ng-style=\"topPanelStyle()\">" +
3185
- " <div class=\"ngGroupPanel\" ng-show=\"showGroupPanel()\" ng-style=\"groupPanelStyle()\">" +
3186
- " <div class=\"ngGroupPanelDescription\" ng-show=\"configGroups.length == 0\">{{i18n.ngGroupPanelDescription}}</div>" +
3187
- " <ul ng-show=\"configGroups.length > 0\" class=\"ngGroupList\">" +
3188
- " <li class=\"ngGroupItem\" ng-repeat=\"group in configGroups\">" +
3189
- " <span class=\"ngGroupElement\">" +
3190
- " <span class=\"ngGroupName\">{{group.displayName}}" +
3191
- " <span ng-click=\"removeGroup($index)\" class=\"ngRemoveGroup\">x</span>" +
3192
- " </span>" +
3193
- " <span ng-hide=\"$last\" class=\"ngGroupArrow\"></span>" +
3194
- " </span>" +
3195
- " </li>" +
3196
- " </ul>" +
3197
- " </div>" +
3198
- " <div class=\"ngHeaderContainer\" ng-style=\"headerStyle()\">" +
3199
- " <div class=\"ngHeaderScroller\" ng-style=\"headerScrollerStyle()\" ng-include=\"gridId + 'headerRowTemplate.html'\"></div>" +
3200
- " </div>" +
3201
- " <div ng-grid-menu></div>" +
3202
- "</div>" +
3203
- "<div class=\"ngViewport\" unselectable=\"on\" ng-viewport ng-class=\"{'ui-widget-content': jqueryUITheme}\" ng-style=\"viewportStyle()\">" +
3204
- " <div class=\"ngCanvas\" ng-style=\"canvasStyle()\">" +
3205
- " <div ng-style=\"rowStyle(row)\" ng-repeat=\"row in renderedRows\" ng-click=\"row.toggleSelected($event)\" ng-class=\"row.alternatingRowClass()\" ng-row></div>" +
3206
- " </div>" +
3207
- "</div>" +
3208
- "<div ng-grid-footer></div>" +
3209
- ""
3210
- );
3211
-
3212
- $templateCache.put("headerCellTemplate.html",
3213
- "<div class=\"ngHeaderSortColumn {{col.headerClass}}\" ng-style=\"{'cursor': col.cursor}\" ng-class=\"{ 'ngSorted': !noSortVisible }\">" +
3214
- " <div ng-click=\"col.sort($event)\" ng-class=\"'colt' + col.index\" class=\"ngHeaderText\">{{col.displayName}}</div>" +
3215
- " <div class=\"ngSortButtonDown\" ng-show=\"col.showSortButtonDown()\"></div>" +
3216
- " <div class=\"ngSortButtonUp\" ng-show=\"col.showSortButtonUp()\"></div>" +
3217
- " <div class=\"ngSortPriority\">{{col.sortPriority}}</div>" +
3218
- " <div ng-class=\"{ ngPinnedIcon: col.pinned, ngUnPinnedIcon: !col.pinned }\" ng-click=\"togglePin(col)\" ng-show=\"col.pinnable\"></div>" +
3219
- "</div>" +
3220
- "<div ng-show=\"col.resizable\" class=\"ngHeaderGrip\" ng-click=\"col.gripClick($event)\" ng-mousedown=\"col.gripOnMouseDown($event)\"></div>"
3221
- );
3222
-
3223
- $templateCache.put("headerRowTemplate.html",
3224
- "<div ng-style=\"{ height: col.headerRowHeight }\" ng-repeat=\"col in renderedColumns\" ng-class=\"col.colIndex()\" class=\"ngHeaderCell\">" +
3225
- " <div class=\"ngVerticalBar\" ng-style=\"{height: col.headerRowHeight}\" ng-class=\"{ ngVerticalBarVisible: !$last }\">&nbsp;</div>" +
3226
- " <div ng-header-cell></div>" +
3227
- "</div>"
3228
- );
3229
-
3230
- $templateCache.put("menuTemplate.html",
3231
- "<div ng-show=\"showColumnMenu || showFilter\" class=\"ngHeaderButton\" ng-click=\"toggleShowMenu()\">" +
3232
- " <div class=\"ngHeaderButtonArrow\"></div>" +
3233
- "</div>" +
3234
- "<div ng-show=\"showMenu\" class=\"ngColMenu\">" +
3235
- " <div ng-show=\"showFilter\">" +
3236
- " <input placeholder=\"{{i18n.ngSearchPlaceHolder}}\" type=\"text\" ng-model=\"filterText\"/>" +
3237
- " </div>" +
3238
- " <div ng-show=\"showColumnMenu\">" +
3239
- " <span class=\"ngMenuText\">{{i18n.ngMenuText}}</span>" +
3240
- " <ul class=\"ngColList\">" +
3241
- " <li class=\"ngColListItem\" ng-repeat=\"col in columns | ngColumns\">" +
3242
- " <label><input ng-disabled=\"col.pinned\" type=\"checkbox\" class=\"ngColListCheckbox\" ng-model=\"col.visible\"/>{{col.displayName}}</label>" +
3243
- " <a title=\"Group By\" ng-class=\"col.groupedByClass()\" ng-show=\"col.groupable && col.visible\" ng-click=\"groupBy(col)\"></a>" +
3244
- " <span class=\"ngGroupingNumber\" ng-show=\"col.groupIndex > 0\">{{col.groupIndex}}</span> " +
3245
- " </li>" +
3246
- " </ul>" +
3247
- " </div>" +
3248
- "</div>"
3249
- );
3250
-
3251
- $templateCache.put("rowTemplate.html",
3252
- "<div ng-style=\"{ 'cursor': row.cursor }\" ng-repeat=\"col in renderedColumns\" ng-class=\"col.colIndex()\" class=\"ngCell {{col.cellClass}}\">" +
3253
- " <div class=\"ngVerticalBar\" ng-style=\"{height: rowHeight}\" ng-class=\"{ ngVerticalBarVisible: !$last }\">&nbsp;</div>" +
3254
- " <div ng-cell></div>" +
3255
- "</div>"
3256
- );
3257
-
3258
- }]);
3259
-
3260
- }(window, jQuery));