UNPKG

19.9 kBJavaScriptView Raw
1/**
2 * ngTable: Table + Angular JS
3 *
4 * @author Vitalii Savchuk <esvit666@gmail.com>
5 * @url https://github.com/esvit/ng-table/
6 * @license New BSD License <http://creativecommons.org/licenses/BSD/>
7 */
8import * as ng1 from 'angular';
9import { convertSortToOrderBy, isGroupingFun } from './util';
10/**
11 * @private
12 */
13function isNumber(n) {
14 return !isNaN(parseFloat(n)) && isFinite(n);
15}
16/**
17 * Parameters manager for an ngTable directive
18 */
19export var NgTableParams = (function () {
20 function NgTableParams(baseParameters, baseSettings) {
21 var _this = this;
22 /**
23 * The page of data rows currently being displayed in the table
24 */
25 this.data = [];
26 this.defaultSettings = NgTableParams.ngTableSettings.createDefaults();
27 this.isCommittedDataset = false;
28 this.initialEvents = [];
29 this._params = {
30 page: 1,
31 count: 10,
32 filter: {},
33 sorting: {},
34 group: {}
35 };
36 this._settings = this.defaultSettings;
37 // the ngTableController "needs" to create a dummy/null instance and it's important to know whether an instance
38 // is one of these
39 if (typeof baseParameters === "boolean") {
40 this.isNullInstance = true;
41 }
42 this.reloadPages = (function () {
43 var currentPages;
44 return function () {
45 var oldPages = currentPages;
46 var newPages = _this.generatePagesArray(_this.page(), _this.total(), _this.count());
47 if (!ng1.equals(oldPages, newPages)) {
48 currentPages = newPages;
49 NgTableParams.ngTableEventsChannel.publishPagesChanged(_this, newPages, oldPages);
50 }
51 };
52 })();
53 ng1.extend(this._params, NgTableParams.ngTableDefaults.params);
54 this.settings(baseSettings);
55 this.parameters(baseParameters, true);
56 NgTableParams.ngTableEventsChannel.publishAfterCreated(this);
57 // run events during construction after the initial create event. That way a consumer
58 // can subscribe to all events for a table without "dropping" an event
59 ng1.forEach(this.initialEvents, function (event) {
60 event();
61 });
62 this.initialEvents = null;
63 }
64 NgTableParams.prototype.count = function (count) {
65 // reset to first page because can be blank page
66 return count !== undefined ? this.parameters({
67 'count': count,
68 'page': 1
69 }) : this._params.count;
70 };
71 NgTableParams.prototype.filter = function (filter) {
72 if (filter != null && typeof filter === 'object') {
73 return this.parameters({
74 'filter': filter,
75 'page': 1
76 });
77 }
78 else if (filter === true) {
79 var keys = Object.keys(this._params.filter);
80 var significantFilter = {};
81 for (var i = 0; i < keys.length; i++) {
82 var filterValue = this._params.filter[keys[i]];
83 if (filterValue != null && filterValue !== '') {
84 significantFilter[keys[i]] = filterValue;
85 }
86 }
87 return significantFilter;
88 }
89 else {
90 return this._params.filter;
91 }
92 };
93 /**
94 * Generate array of pages.
95 * When no arguments supplied, the current parameter state of this `NgTableParams` instance will be used
96 * @param currentPage Which page must be active
97 * @param totalItems Total quantity of items
98 * @param pageSize Quantity of items on page
99 * @param maxBlocks Quantity of blocks for pagination
100 * @returns Array of pages
101 */
102 NgTableParams.prototype.generatePagesArray = function (currentPage, totalItems, pageSize, maxBlocks) {
103 if (!arguments.length) {
104 currentPage = this.page();
105 totalItems = this.total();
106 pageSize = this.count();
107 }
108 var maxPage, maxPivotPages, minPage, numPages;
109 maxBlocks = maxBlocks && maxBlocks < 6 ? 6 : maxBlocks;
110 var pages = [];
111 numPages = Math.ceil(totalItems / pageSize);
112 if (numPages > 1) {
113 pages.push({
114 type: 'prev',
115 number: Math.max(1, currentPage - 1),
116 active: currentPage > 1
117 });
118 pages.push({
119 type: 'first',
120 number: 1,
121 active: currentPage > 1,
122 current: currentPage === 1
123 });
124 maxPivotPages = Math.round((this._settings.paginationMaxBlocks - this._settings.paginationMinBlocks) / 2);
125 minPage = Math.max(2, currentPage - maxPivotPages);
126 maxPage = Math.min(numPages - 1, currentPage + maxPivotPages * 2 - (currentPage - minPage));
127 minPage = Math.max(2, minPage - (maxPivotPages * 2 - (maxPage - minPage)));
128 var i = minPage;
129 while (i <= maxPage) {
130 if ((i === minPage && i !== 2) || (i === maxPage && i !== numPages - 1)) {
131 pages.push({
132 type: 'more',
133 active: false
134 });
135 }
136 else {
137 pages.push({
138 type: 'page',
139 number: i,
140 active: currentPage !== i,
141 current: currentPage === i
142 });
143 }
144 i++;
145 }
146 pages.push({
147 type: 'last',
148 number: numPages,
149 active: currentPage !== numPages,
150 current: currentPage === numPages
151 });
152 pages.push({
153 type: 'next',
154 number: Math.min(numPages, currentPage + 1),
155 active: currentPage < numPages
156 });
157 }
158 return pages;
159 };
160 NgTableParams.prototype.group = function (group, sortDirection) {
161 if (group === undefined) {
162 return this._params.group;
163 }
164 var newParameters = {
165 page: 1
166 };
167 if (isGroupingFun(group) && sortDirection !== undefined) {
168 group.sortDirection = sortDirection;
169 newParameters.group = group;
170 }
171 else if (typeof group === 'string' && sortDirection !== undefined) {
172 newParameters.group = (_a = {}, _a[group] = sortDirection, _a);
173 }
174 else {
175 newParameters.group = group;
176 }
177 this.parameters(newParameters);
178 return this;
179 var _a;
180 };
181 /**
182 * Returns true when an attempt to `reload` the current `parameter` values have resulted in a failure.
183 * This method will continue to return true until the `reload` is successfully called or when the
184 * `parameter` values have changed
185 */
186 NgTableParams.prototype.hasErrorState = function () {
187 return !!(this.errParamsMemento && ng1.equals(this.errParamsMemento, this.createComparableParams()));
188 };
189 /**
190 * Returns true if `filter` has significant filter value(s) (any value except null, undefined, or empty string),
191 * otherwise false
192 */
193 NgTableParams.prototype.hasFilter = function () {
194 return Object.keys(this.filter(true)).length > 0;
195 };
196 /**
197 * Return true when a change to `filters` require the `reload` method
198 * to be run so as to ensure the data presented to the user reflects these filters
199 */
200 NgTableParams.prototype.hasFilterChanges = function () {
201 var previousFilter = (this.prevParamsMemento && this.prevParamsMemento.params.filter);
202 return !ng1.equals((this._params.filter), previousFilter) || this.hasGlobalSearchFieldChanges();
203 };
204 NgTableParams.prototype.hasGroup = function (group, sortDirection) {
205 if (group == null) {
206 return isGroupingFun(this._params.group) || Object.keys(this._params.group).length > 0;
207 }
208 if (isGroupingFun(group)) {
209 if (sortDirection == null) {
210 return this._params.group === group;
211 }
212 else {
213 return this._params.group === group && group.sortDirection === sortDirection;
214 }
215 }
216 else {
217 if (sortDirection == null) {
218 return Object.keys(this._params.group).indexOf(group) !== -1;
219 }
220 else {
221 return this._params.group[group] === sortDirection;
222 }
223 }
224 };
225 /**
226 * Return true when a change to this instance should require the `reload` method
227 * to be run so as to ensure the data rows presented to the user reflects the current state.
228 *
229 * Note that this method will return false when the `reload` method has run but fails. In this case
230 * `hasErrorState` will return true.
231 *
232 * The built-in `ngTable` directives will watch for when this function returns true and will then call
233 * the `reload` method to load its data rows
234 */
235 NgTableParams.prototype.isDataReloadRequired = function () {
236 // note: using != as want to treat null and undefined the same
237 return !this.isCommittedDataset || !ng1.equals(this.createComparableParams(), this.prevParamsMemento)
238 || this.hasGlobalSearchFieldChanges();
239 };
240 /**
241 * Returns true if sorting by the field supplied. Where direction supplied
242 * the field must also be sorted by that direction to return true
243 */
244 NgTableParams.prototype.isSortBy = function (field, direction) {
245 if (direction !== undefined) {
246 return this._params.sorting[field] !== undefined && this._params.sorting[field] == direction;
247 }
248 else {
249 return this._params.sorting[field] !== undefined;
250 }
251 };
252 /**
253 * Returns sorting values in a format that can be consumed by the angular `$orderBy` filter service
254 */
255 NgTableParams.prototype.orderBy = function () {
256 return convertSortToOrderBy(this._params.sorting);
257 };
258 NgTableParams.prototype.page = function (page) {
259 return page !== undefined ? this.parameters({
260 'page': page
261 }) : this._params.page;
262 };
263 NgTableParams.prototype.parameters = function (newParameters, parseParamsFromUrl) {
264 parseParamsFromUrl = parseParamsFromUrl || false;
265 if (typeof newParameters !== undefined) {
266 for (var key in newParameters) {
267 var value = newParameters[key];
268 if (parseParamsFromUrl && key.indexOf('[') >= 0) {
269 var keys = key.split(/\[(.*)\]/).reverse();
270 var lastKey = '';
271 for (var i = 0, len = keys.length; i < len; i++) {
272 var name_1 = keys[i];
273 if (name_1 !== '') {
274 var v = value;
275 value = {};
276 value[lastKey = name_1] = (isNumber(v) ? parseFloat(v) : v);
277 }
278 }
279 if (lastKey === 'sorting') {
280 this._params[lastKey] = {};
281 }
282 this._params[lastKey] = ng1.extend(this._params[lastKey] || {}, value[lastKey]);
283 }
284 else {
285 if (key === 'group') {
286 this._params[key] = this.parseGroup(newParameters[key]);
287 }
288 else {
289 this._params[key] = (isNumber(newParameters[key]) ? parseFloat(newParameters[key]) : newParameters[key]);
290 }
291 }
292 }
293 this.log('ngTable: set parameters', this._params);
294 return this;
295 }
296 return this._params;
297 };
298 /**
299 * Trigger a reload of the data rows
300 */
301 NgTableParams.prototype.reload = function () {
302 var _this = this;
303 var pData = null;
304 this._settings.$loading = true;
305 this.prevParamsMemento = ng1.copy(this.createComparableParams());
306 this.isCommittedDataset = true;
307 if (this.hasGroup()) {
308 pData = this.runInterceptorPipeline(NgTableParams.$q.when(this._settings.getGroups(this)));
309 }
310 else {
311 var fn = this._settings.getData;
312 pData = this.runInterceptorPipeline(NgTableParams.$q.when(fn(this)));
313 }
314 this.log('ngTable: reload data');
315 var oldData = this.data;
316 return pData.then(function (data) {
317 _this._settings.$loading = false;
318 _this.errParamsMemento = null;
319 _this.data = data;
320 // note: I think it makes sense to publish this event even when data === oldData
321 // subscribers can always set a filter to only receive the event when data !== oldData
322 NgTableParams.ngTableEventsChannel.publishAfterReloadData(_this, data, oldData);
323 _this.reloadPages();
324 return data;
325 }).catch(function (reason) {
326 _this.errParamsMemento = _this.prevParamsMemento;
327 // "rethrow"
328 return NgTableParams.$q.reject(reason);
329 });
330 };
331 NgTableParams.prototype.settings = function (newSettings) {
332 var _this = this;
333 if (ng1.isDefined(newSettings)) {
334 var settings = NgTableParams.ngTableSettings.merge(this._settings, newSettings);
335 var originalDataset_1 = this._settings.dataset;
336 this._settings = settings;
337 // note: using != as want null and undefined to be treated the same
338 var hasDatasetChanged = newSettings.hasOwnProperty('dataset') && (newSettings.dataset != originalDataset_1);
339 if (hasDatasetChanged) {
340 if (this.isCommittedDataset) {
341 this.page(1); // reset page as a new dataset has been supplied
342 }
343 this.isCommittedDataset = false;
344 var fireEvent = function () {
345 NgTableParams.ngTableEventsChannel.publishDatasetChanged(_this, newSettings.dataset, originalDataset_1);
346 };
347 if (this.initialEvents) {
348 this.initialEvents.push(fireEvent);
349 }
350 else {
351 fireEvent();
352 }
353 }
354 this.log('ngTable: set settings', this._settings);
355 return this;
356 }
357 return this._settings;
358 };
359 NgTableParams.prototype.sorting = function (sorting, direction) {
360 if (typeof sorting === 'string') {
361 this.parameters({
362 'sorting': (_a = {}, _a[sorting] = direction, _a)
363 });
364 return this;
365 }
366 return sorting !== undefined ? this.parameters({
367 'sorting': sorting
368 }) : this._params.sorting;
369 var _a;
370 };
371 NgTableParams.prototype.total = function (total) {
372 return total !== undefined ? this.settings({
373 'total': total
374 }) : this._settings.total;
375 };
376 /**
377 * Returns the current parameter values uri-encoded. Set `asString` to
378 * true for the parameters to be returned as an array of strings of the form 'paramName=value'
379 * otherwise parameters returned as a key-value object
380 */
381 NgTableParams.prototype.url = function (asString) {
382 // this function is an example of Typescript gone bad!!
383 asString = asString || false;
384 var pairs = (asString ? [] : {});
385 for (var key in this._params) {
386 if (this._params.hasOwnProperty(key)) {
387 var item = this._params[key], name_2 = encodeURIComponent(key);
388 if (typeof item === "object") {
389 for (var subkey in item) {
390 if (isSignificantValue(item[subkey], key)) {
391 var pname = name_2 + "[" + encodeURIComponent(subkey) + "]";
392 collectValue(item[subkey], pname);
393 }
394 }
395 }
396 else if (!ng1.isFunction(item) && isSignificantValue(item, key)) {
397 collectValue(item, name_2);
398 }
399 }
400 }
401 return pairs;
402 function collectValue(value, key) {
403 if (isArray(pairs)) {
404 pairs.push(key + "=" + encodeURIComponent(value));
405 }
406 else {
407 pairs[key] = encodeURIComponent(value);
408 }
409 }
410 function isArray(pairs) {
411 return asString;
412 }
413 function isSignificantValue(value, key) {
414 return key === "group" ? true : typeof value !== undefined && value !== "";
415 }
416 };
417 NgTableParams.prototype.createComparableParams = function () {
418 var group = this._params.group;
419 return {
420 params: this._params,
421 groupSortDirection: isGroupingFun(group) ? group.sortDirection : undefined
422 };
423 };
424 NgTableParams.prototype.hasGlobalSearchFieldChanges = function () {
425 var currentVal = (this._params.filter && this._params.filter['$']);
426 var previousVal = (this.prevParamsMemento && this.prevParamsMemento.params.filter && this.prevParamsMemento.params.filter['$']);
427 return !ng1.equals(currentVal, previousVal);
428 };
429 NgTableParams.prototype.log = function () {
430 var args = [];
431 for (var _i = 0; _i < arguments.length; _i++) {
432 args[_i - 0] = arguments[_i];
433 }
434 if (this._settings.debugMode && NgTableParams.$log.debug) {
435 (_a = NgTableParams.$log).debug.apply(_a, args);
436 }
437 var _a;
438 };
439 NgTableParams.prototype.parseGroup = function (group) {
440 var defaultSort = this._settings.groupOptions && this._settings.groupOptions.defaultSort;
441 if (!group) {
442 return group;
443 }
444 else if (isGroupingFun(group)) {
445 if (group.sortDirection == null) {
446 group.sortDirection = defaultSort;
447 }
448 return group;
449 }
450 else if (typeof group === 'object') {
451 for (var key in group) {
452 if (group[key] == null) {
453 group[key] = defaultSort;
454 }
455 }
456 return group;
457 }
458 else {
459 return (_a = {},
460 _a[group] = defaultSort,
461 _a
462 );
463 }
464 var _a;
465 };
466 NgTableParams.prototype.runInterceptorPipeline = function (fetchedData) {
467 var _this = this;
468 var interceptors = this._settings.interceptors || [];
469 return interceptors.reduce(function (result, interceptor) {
470 var thenFn = (interceptor.response && interceptor.response.bind(interceptor)) || NgTableParams.$q.when;
471 var rejectFn = (interceptor.responseError && interceptor.responseError.bind(interceptor)) || NgTableParams.$q.reject;
472 return result.then(function (data) {
473 return thenFn(data, _this);
474 }, function (reason) {
475 return rejectFn(reason, _this);
476 });
477 }, fetchedData);
478 };
479 NgTableParams.init = function ($q, $log, ngTableDefaults, ngTableEventsChannel, ngTableSettings) {
480 NgTableParams.$q = $q;
481 NgTableParams.$log = $log;
482 NgTableParams.ngTableDefaults = ngTableDefaults;
483 NgTableParams.ngTableEventsChannel = ngTableEventsChannel;
484 NgTableParams.ngTableSettings = ngTableSettings;
485 };
486 return NgTableParams;
487}());
488NgTableParams.init.$inject = ['$q', '$log', 'ngTableDefaults', 'ngTableEventsChannel', 'ngTableSettings'];
489//# sourceMappingURL=ngTableParams.js.map
\No newline at end of file