UNPKG

23.3 kBJavaScriptView Raw
1/**
2 * ag-grid - Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components
3 * @version v18.1.2
4 * @link http://www.ag-grid.com/
5 * @license MIT
6 */
7"use strict";
8var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
9 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
10 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
11 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
12 return c > 3 && r && Object.defineProperty(target, key, r), r;
13};
14var __metadata = (this && this.__metadata) || function (k, v) {
15 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
16};
17Object.defineProperty(exports, "__esModule", { value: true });
18var utils_1 = require("../utils");
19var gridOptionsWrapper_1 = require("../gridOptionsWrapper");
20var popupService_1 = require("../widgets/popupService");
21var valueService_1 = require("../valueService/valueService");
22var columnController_1 = require("../columnController/columnController");
23var columnApi_1 = require("../columnController/columnApi");
24var context_1 = require("../context/context");
25var eventService_1 = require("../eventService");
26var events_1 = require("../events");
27var gridApi_1 = require("../gridApi");
28var componentResolver_1 = require("../components/framework/componentResolver");
29var FilterManager = (function () {
30 function FilterManager() {
31 this.allFilters = {};
32 this.quickFilter = null;
33 this.quickFilterParts = null;
34 }
35 FilterManager_1 = FilterManager;
36 FilterManager.prototype.init = function () {
37 this.eventService.addEventListener(events_1.Events.EVENT_ROW_DATA_CHANGED, this.onNewRowsLoaded.bind(this));
38 this.eventService.addEventListener(events_1.Events.EVENT_NEW_COLUMNS_LOADED, this.onNewColumnsLoaded.bind(this));
39 this.quickFilter = this.parseQuickFilter(this.gridOptionsWrapper.getQuickFilterText());
40 this.setQuickFilterParts();
41 // check this here, in case there is a filter from the start
42 this.checkExternalFilter();
43 };
44 FilterManager.prototype.setQuickFilterParts = function () {
45 if (this.quickFilter) {
46 this.quickFilterParts = this.quickFilter.split(' ');
47 }
48 else {
49 this.quickFilterParts = null;
50 }
51 };
52 FilterManager.prototype.setFilterModel = function (model) {
53 var _this = this;
54 var allPromises = [];
55 if (model) {
56 // mark the filters as we set them, so any active filters left over we stop
57 var modelKeys_1 = Object.keys(model);
58 utils_1.Utils.iterateObject(this.allFilters, function (colId, filterWrapper) {
59 utils_1.Utils.removeFromArray(modelKeys_1, colId);
60 var newModel = model[colId];
61 _this.setModelOnFilterWrapper(filterWrapper.filterPromise, newModel);
62 allPromises.push(filterWrapper.filterPromise);
63 });
64 // at this point, processedFields contains data for which we don't have a filter working yet
65 utils_1.Utils.iterateArray(modelKeys_1, function (colId) {
66 var column = _this.columnController.getPrimaryColumn(colId);
67 if (!column) {
68 console.warn('Warning ag-grid setFilterModel - no column found for colId ' + colId);
69 return;
70 }
71 var filterWrapper = _this.getOrCreateFilterWrapper(column);
72 _this.setModelOnFilterWrapper(filterWrapper.filterPromise, model[colId]);
73 allPromises.push(filterWrapper.filterPromise);
74 });
75 }
76 else {
77 utils_1.Utils.iterateObject(this.allFilters, function (key, filterWrapper) {
78 _this.setModelOnFilterWrapper(filterWrapper.filterPromise, null);
79 allPromises.push(filterWrapper.filterPromise);
80 });
81 }
82 utils_1.Promise.all(allPromises).then(function (whatever) {
83 _this.onFilterChanged();
84 });
85 };
86 FilterManager.prototype.setModelOnFilterWrapper = function (filterPromise, newModel) {
87 filterPromise.then(function (filter) {
88 if (typeof filter.setModel !== 'function') {
89 console.warn('Warning ag-grid - filter missing setModel method, which is needed for setFilterModel');
90 return;
91 }
92 filter.setModel(newModel);
93 });
94 };
95 FilterManager.prototype.getFilterModel = function () {
96 var result = {};
97 utils_1.Utils.iterateObject(this.allFilters, function (key, filterWrapper) {
98 // because user can provide filters, we provide useful error checking and messages
99 var filterPromise = filterWrapper.filterPromise;
100 var filter = filterPromise.resolveNow(null, function (filter) { return filter; });
101 if (filter == null) {
102 return null;
103 }
104 if (typeof filter.getModel !== 'function') {
105 console.warn('Warning ag-grid - filter API missing getModel method, which is needed for getFilterModel');
106 return;
107 }
108 var model = filter.getModel();
109 if (utils_1.Utils.exists(model)) {
110 result[key] = model;
111 }
112 });
113 return result;
114 };
115 // returns true if any advanced filter (ie not quick filter) active
116 FilterManager.prototype.isAdvancedFilterPresent = function () {
117 return this.advancedFilterPresent;
118 };
119 FilterManager.prototype.setAdvancedFilterPresent = function () {
120 var atLeastOneActive = false;
121 utils_1.Utils.iterateObject(this.allFilters, function (key, filterWrapper) {
122 if (filterWrapper.filterPromise.resolveNow(false, function (filter) { return filter.isFilterActive(); })) {
123 atLeastOneActive = true;
124 }
125 });
126 this.advancedFilterPresent = atLeastOneActive;
127 };
128 FilterManager.prototype.updateFilterFlagInColumns = function (source) {
129 utils_1.Utils.iterateObject(this.allFilters, function (key, filterWrapper) {
130 var filterActive = filterWrapper.filterPromise.resolveNow(false, function (filter) { return filter.isFilterActive(); });
131 filterWrapper.column.setFilterActive(filterActive, source);
132 });
133 };
134 // returns true if quickFilter or advancedFilter
135 FilterManager.prototype.isAnyFilterPresent = function () {
136 return this.isQuickFilterPresent() || this.advancedFilterPresent || this.externalFilterPresent;
137 };
138 FilterManager.prototype.doesFilterPass = function (node, filterToSkip) {
139 var data = node.data;
140 var colKeys = Object.keys(this.allFilters);
141 for (var i = 0, l = colKeys.length; i < l; i++) {
142 var colId = colKeys[i];
143 var filterWrapper = this.allFilters[colId];
144 // if no filter, always pass
145 if (filterWrapper === undefined) {
146 continue;
147 }
148 var filter = filterWrapper.filterPromise.resolveNow(undefined, function (filter) { return filter; });
149 // if filter not yet there, continue
150 if (filter === undefined) {
151 continue;
152 }
153 if (filter === filterToSkip) {
154 continue;
155 }
156 // don't bother with filters that are not active
157 if (!filter.isFilterActive()) {
158 continue;
159 }
160 if (!filter.doesFilterPass) {
161 console.error('Filter is missing method doesFilterPass');
162 }
163 var params = {
164 node: node,
165 data: data
166 };
167 if (!filter.doesFilterPass(params)) {
168 return false;
169 }
170 }
171 // all filters passed
172 return true;
173 };
174 FilterManager.prototype.parseQuickFilter = function (newFilter) {
175 if (utils_1.Utils.missing(newFilter) || newFilter === "") {
176 return null;
177 }
178 if (this.gridOptionsWrapper.isRowModelInfinite()) {
179 console.warn('ag-grid: cannot do quick filtering when doing virtual paging');
180 return null;
181 }
182 return newFilter.toUpperCase();
183 };
184 // returns true if it has changed (not just same value again)
185 FilterManager.prototype.setQuickFilter = function (newFilter) {
186 var parsedFilter = this.parseQuickFilter(newFilter);
187 if (this.quickFilter !== parsedFilter) {
188 this.quickFilter = parsedFilter;
189 this.setQuickFilterParts();
190 this.onFilterChanged();
191 }
192 };
193 FilterManager.prototype.checkExternalFilter = function () {
194 this.externalFilterPresent = this.gridOptionsWrapper.isExternalFilterPresent();
195 };
196 FilterManager.prototype.onFilterChanged = function () {
197 this.setAdvancedFilterPresent();
198 this.updateFilterFlagInColumns("filterChanged");
199 this.checkExternalFilter();
200 utils_1.Utils.iterateObject(this.allFilters, function (key, filterWrapper) {
201 filterWrapper.filterPromise.then(function (filter) {
202 if (filter.onAnyFilterChanged) {
203 filter.onAnyFilterChanged();
204 }
205 });
206 });
207 var event = {
208 type: events_1.Events.EVENT_FILTER_CHANGED,
209 api: this.gridApi,
210 columnApi: this.columnApi
211 };
212 this.eventService.dispatchEvent(event);
213 };
214 FilterManager.prototype.isQuickFilterPresent = function () {
215 return this.quickFilter !== null;
216 };
217 FilterManager.prototype.doesRowPassOtherFilters = function (filterToSkip, node) {
218 return this.doesRowPassFilter(node, filterToSkip);
219 };
220 FilterManager.prototype.doesRowPassQuickFilterNoCache = function (node, filterPart) {
221 var _this = this;
222 var columns = this.columnController.getAllColumnsForQuickFilter();
223 var filterPasses = false;
224 columns.forEach(function (column) {
225 if (filterPasses) {
226 return;
227 }
228 var part = _this.getQuickFilterTextForColumn(column, node);
229 if (utils_1.Utils.exists(part)) {
230 if (part.indexOf(filterPart) >= 0) {
231 filterPasses = true;
232 }
233 }
234 });
235 return filterPasses;
236 };
237 FilterManager.prototype.doesRowPassQuickFilterCache = function (node, filterPart) {
238 if (!node.quickFilterAggregateText) {
239 this.aggregateRowForQuickFilter(node);
240 }
241 var filterPasses = node.quickFilterAggregateText.indexOf(filterPart) >= 0;
242 return filterPasses;
243 };
244 FilterManager.prototype.doesRowPassQuickFilter = function (node) {
245 var _this = this;
246 var filterPasses = true;
247 var usingCache = this.gridOptionsWrapper.isCacheQuickFilter();
248 this.quickFilterParts.forEach(function (filterPart) {
249 var partPasses = usingCache ?
250 _this.doesRowPassQuickFilterCache(node, filterPart) : _this.doesRowPassQuickFilterNoCache(node, filterPart);
251 // each part must pass, if any fails, then the whole filter fails
252 if (!partPasses) {
253 filterPasses = false;
254 }
255 });
256 return filterPasses;
257 };
258 FilterManager.prototype.doesRowPassFilter = function (node, filterToSkip) {
259 // the row must pass ALL of the filters, so if any of them fail,
260 // we return true. that means if a row passes the quick filter,
261 // but fails the column filter, it fails overall
262 // first up, check quick filter
263 if (this.isQuickFilterPresent()) {
264 if (!this.doesRowPassQuickFilter(node)) {
265 return false;
266 }
267 }
268 // secondly, give the client a chance to reject this row
269 if (this.externalFilterPresent) {
270 if (!this.gridOptionsWrapper.doesExternalFilterPass(node)) {
271 return false;
272 }
273 }
274 // lastly, check our internal advanced filter
275 if (this.advancedFilterPresent) {
276 if (!this.doesFilterPass(node, filterToSkip)) {
277 return false;
278 }
279 }
280 // got this far, all filters pass
281 return true;
282 };
283 FilterManager.prototype.getQuickFilterTextForColumn = function (column, rowNode) {
284 var value = this.valueService.getValue(column, rowNode, true);
285 var valueAfterCallback;
286 var colDef = column.getColDef();
287 if (column.getColDef().getQuickFilterText) {
288 var params = {
289 value: value,
290 node: rowNode,
291 data: rowNode.data,
292 column: column,
293 colDef: colDef
294 };
295 valueAfterCallback = column.getColDef().getQuickFilterText(params);
296 }
297 else {
298 valueAfterCallback = value;
299 }
300 if (valueAfterCallback && valueAfterCallback !== '') {
301 return valueAfterCallback.toString().toUpperCase();
302 }
303 else {
304 return null;
305 }
306 };
307 FilterManager.prototype.aggregateRowForQuickFilter = function (node) {
308 var _this = this;
309 var stringParts = [];
310 var columns = this.columnController.getAllColumnsForQuickFilter();
311 columns.forEach(function (column) {
312 var part = _this.getQuickFilterTextForColumn(column, node);
313 if (utils_1.Utils.exists(part)) {
314 stringParts.push(part);
315 }
316 });
317 node.quickFilterAggregateText = stringParts.join(FilterManager_1.QUICK_FILTER_SEPARATOR);
318 };
319 FilterManager.prototype.onNewRowsLoaded = function (source) {
320 utils_1.Utils.iterateObject(this.allFilters, function (key, filterWrapper) {
321 filterWrapper.filterPromise.then(function (filter) {
322 if (filter.onNewRowsLoaded) {
323 filter.onNewRowsLoaded();
324 }
325 });
326 });
327 this.updateFilterFlagInColumns(source);
328 this.setAdvancedFilterPresent();
329 };
330 FilterManager.prototype.createValueGetter = function (column) {
331 var _this = this;
332 return function (node) {
333 return _this.valueService.getValue(column, node, true);
334 };
335 };
336 FilterManager.prototype.getFilterComponent = function (column) {
337 var filterWrapper = this.getOrCreateFilterWrapper(column);
338 return filterWrapper.filterPromise;
339 };
340 FilterManager.prototype.getOrCreateFilterWrapper = function (column) {
341 var filterWrapper = this.cachedFilter(column);
342 if (!filterWrapper) {
343 filterWrapper = this.createFilterWrapper(column);
344 this.allFilters[column.getColId()] = filterWrapper;
345 }
346 return filterWrapper;
347 };
348 FilterManager.prototype.cachedFilter = function (column) {
349 return this.allFilters[column.getColId()];
350 };
351 FilterManager.prototype.createFilterInstance = function (column, $scope) {
352 var _this = this;
353 var defaultFilter = 'agTextColumnFilter';
354 if (this.gridOptionsWrapper.isEnterprise()) {
355 defaultFilter = 'agSetColumnFilter';
356 }
357 var sanitisedColDef = utils_1.Utils.cloneObject(column.getColDef());
358 var event = {
359 type: events_1.Events.EVENT_FILTER_MODIFIED,
360 api: this.gridApi,
361 columnApi: this.columnApi
362 };
363 var filterChangedCallback = this.onFilterChanged.bind(this);
364 var filterModifiedCallback = function () { return _this.eventService.dispatchEvent(event); };
365 var params = {
366 column: column,
367 colDef: sanitisedColDef,
368 rowModel: this.rowModel,
369 filterChangedCallback: filterChangedCallback,
370 filterModifiedCallback: filterModifiedCallback,
371 valueGetter: this.createValueGetter(column),
372 context: this.gridOptionsWrapper.getContext(),
373 doesRowPassOtherFilter: null,
374 $scope: $scope
375 };
376 return this.componentResolver.createAgGridComponent(sanitisedColDef, params, 'filter', {
377 api: this.gridApi,
378 columnApi: this.columnApi,
379 column: column,
380 colDef: sanitisedColDef
381 }, defaultFilter, true, function (params, filter) { return utils_1.Utils.assign(params, {
382 doesRowPassOtherFilter: _this.doesRowPassOtherFilters.bind(_this, filter),
383 }); });
384 };
385 FilterManager.prototype.createFilterWrapper = function (column) {
386 var filterWrapper = {
387 column: column,
388 filterPromise: null,
389 scope: null,
390 compiledElement: null,
391 guiPromise: utils_1.Promise.external()
392 };
393 filterWrapper.scope = this.gridOptionsWrapper.isAngularCompileFilters() ? this.$scope.$new() : null;
394 filterWrapper.filterPromise = this.createFilterInstance(column, filterWrapper.scope);
395 this.putIntoGui(filterWrapper);
396 return filterWrapper;
397 };
398 FilterManager.prototype.putIntoGui = function (filterWrapper) {
399 var _this = this;
400 var eFilterGui = document.createElement('div');
401 eFilterGui.className = 'ag-filter';
402 filterWrapper.filterPromise.then(function (filter) {
403 var guiFromFilter = filter.getGui();
404 if (utils_1.Utils.missing(guiFromFilter)) {
405 console.warn("getGui method from filter returned " + guiFromFilter + ", it should be a DOM element or an HTML template string.");
406 }
407 // for backwards compatibility with Angular 1 - we
408 // used to allow providing back HTML from getGui().
409 // once we move away from supporting Angular 1
410 // directly, we can change this.
411 if (typeof guiFromFilter === 'string') {
412 guiFromFilter = utils_1.Utils.loadTemplate(guiFromFilter);
413 }
414 eFilterGui.appendChild(guiFromFilter);
415 if (filterWrapper.scope) {
416 var compiledElement = _this.$compile(eFilterGui)(filterWrapper.scope);
417 filterWrapper.compiledElement = compiledElement;
418 setTimeout(function () { return filterWrapper.scope.$apply(); }, 0);
419 }
420 filterWrapper.guiPromise.resolve(eFilterGui);
421 });
422 };
423 FilterManager.prototype.onNewColumnsLoaded = function () {
424 this.destroy();
425 };
426 // destroys the filter, so it not longer takes part
427 FilterManager.prototype.destroyFilter = function (column, source) {
428 if (source === void 0) { source = "api"; }
429 var filterWrapper = this.allFilters[column.getColId()];
430 if (filterWrapper) {
431 this.disposeFilterWrapper(filterWrapper, source);
432 this.onFilterChanged();
433 }
434 };
435 FilterManager.prototype.disposeFilterWrapper = function (filterWrapper, source) {
436 var _this = this;
437 filterWrapper.filterPromise.then(function (filter) {
438 filter.setModel(null);
439 if (filter.destroy) {
440 filter.destroy();
441 }
442 filterWrapper.column.setFilterActive(false, source);
443 if (filterWrapper.scope) {
444 if (filterWrapper.compiledElement) {
445 filterWrapper.compiledElement.remove();
446 }
447 filterWrapper.scope.$destroy();
448 }
449 delete _this.allFilters[filterWrapper.column.getColId()];
450 });
451 };
452 FilterManager.prototype.destroy = function () {
453 var _this = this;
454 utils_1.Utils.iterateObject(this.allFilters, function (key, filterWrapper) {
455 _this.disposeFilterWrapper(filterWrapper, "filterDestroyed");
456 });
457 };
458 FilterManager.QUICK_FILTER_SEPARATOR = '\n';
459 __decorate([
460 context_1.Autowired('$compile'),
461 __metadata("design:type", Object)
462 ], FilterManager.prototype, "$compile", void 0);
463 __decorate([
464 context_1.Autowired('$scope'),
465 __metadata("design:type", Object)
466 ], FilterManager.prototype, "$scope", void 0);
467 __decorate([
468 context_1.Autowired('gridOptionsWrapper'),
469 __metadata("design:type", gridOptionsWrapper_1.GridOptionsWrapper)
470 ], FilterManager.prototype, "gridOptionsWrapper", void 0);
471 __decorate([
472 context_1.Autowired('gridCore'),
473 __metadata("design:type", Object)
474 ], FilterManager.prototype, "gridCore", void 0);
475 __decorate([
476 context_1.Autowired('popupService'),
477 __metadata("design:type", popupService_1.PopupService)
478 ], FilterManager.prototype, "popupService", void 0);
479 __decorate([
480 context_1.Autowired('valueService'),
481 __metadata("design:type", valueService_1.ValueService)
482 ], FilterManager.prototype, "valueService", void 0);
483 __decorate([
484 context_1.Autowired('columnController'),
485 __metadata("design:type", columnController_1.ColumnController)
486 ], FilterManager.prototype, "columnController", void 0);
487 __decorate([
488 context_1.Autowired('rowModel'),
489 __metadata("design:type", Object)
490 ], FilterManager.prototype, "rowModel", void 0);
491 __decorate([
492 context_1.Autowired('eventService'),
493 __metadata("design:type", eventService_1.EventService)
494 ], FilterManager.prototype, "eventService", void 0);
495 __decorate([
496 context_1.Autowired('enterprise'),
497 __metadata("design:type", Boolean)
498 ], FilterManager.prototype, "enterprise", void 0);
499 __decorate([
500 context_1.Autowired('context'),
501 __metadata("design:type", context_1.Context)
502 ], FilterManager.prototype, "context", void 0);
503 __decorate([
504 context_1.Autowired('columnApi'),
505 __metadata("design:type", columnApi_1.ColumnApi)
506 ], FilterManager.prototype, "columnApi", void 0);
507 __decorate([
508 context_1.Autowired('gridApi'),
509 __metadata("design:type", gridApi_1.GridApi)
510 ], FilterManager.prototype, "gridApi", void 0);
511 __decorate([
512 context_1.Autowired('componentResolver'),
513 __metadata("design:type", componentResolver_1.ComponentResolver)
514 ], FilterManager.prototype, "componentResolver", void 0);
515 __decorate([
516 context_1.PostConstruct,
517 __metadata("design:type", Function),
518 __metadata("design:paramtypes", []),
519 __metadata("design:returntype", void 0)
520 ], FilterManager.prototype, "init", null);
521 __decorate([
522 context_1.PreDestroy,
523 __metadata("design:type", Function),
524 __metadata("design:paramtypes", []),
525 __metadata("design:returntype", void 0)
526 ], FilterManager.prototype, "destroy", null);
527 FilterManager = FilterManager_1 = __decorate([
528 context_1.Bean('filterManager')
529 ], FilterManager);
530 return FilterManager;
531 var FilterManager_1;
532}());
533exports.FilterManager = FilterManager;