/
selectFilter.ts
128 lines (111 loc) · 4.44 KB
/
selectFilter.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { I18N } from 'aurelia-i18n';
import { inject } from 'aurelia-framework';
import {
Column,
Filter,
FilterType,
FilterArguments,
FilterCallback,
SearchTerm
} from './../models/index';
import * as $ from 'jquery';
@inject(I18N)
export class SelectFilter implements Filter {
$filterElm: any;
grid: any;
searchTerm: SearchTerm;
columnDef: Column;
callback: FilterCallback;
filterType = FilterType.select;
constructor(private i18n: I18N) { }
/**
* Initialize the Filter
*/
init(args: FilterArguments) {
if (!args) {
throw new Error('[Aurelia-SlickGrid] A filter must always have an "init()" with valid arguments.');
}
this.grid = args.grid;
this.callback = args.callback;
this.columnDef = args.columnDef;
this.searchTerm = args.searchTerm || '';
// step 1, create HTML string template
const filterTemplate = this.buildTemplateHtmlString();
// step 2, create the DOM Element of the filter & initialize it if searchTerm is filled
this.$filterElm = this.createDomElement(filterTemplate);
// step 3, subscribe to the change event and run the callback when that happens
// also add/remove "filled" class for styling purposes
this.$filterElm.change((e: any) => {
(e && e.target && e.target.value) ? this.$filterElm.addClass('filled') : this.$filterElm.removeClass('filled');
this.callback(e, { columnDef: this.columnDef, operator: 'EQ' });
});
}
/**
* Clear the filter values
*/
clear(triggerFilterChange = true) {
if (this.$filterElm) {
this.$filterElm.val('');
if (triggerFilterChange) {
this.$filterElm.trigger('change');
}
}
}
/**
* destroy the filter
*/
destroy() {
if (this.$filterElm) {
this.$filterElm.off('change').remove();
}
}
/**
* Set value(s) on the DOM element
*/
setValues(values: SearchTerm | SearchTerm[]) {
if (values) {
this.$filterElm.val(values);
}
}
//
// private functions
// ------------------
private buildTemplateHtmlString() {
if (!this.columnDef || !this.columnDef.filter || !this.columnDef.filter.collection) {
throw new Error(`[Aurelia-SlickGrid] You need to pass a "collection" for the Select Filter to work correctly. Also each option should include a value/label pair (or value/labelKey when using Locale). For example:: { filter: type: FilterType.select, collection: [{ value: true, label: 'True' }, { value: false, label: 'False'}] }`);
}
const optionCollection = this.columnDef.filter.collection || [];
const labelName = (this.columnDef.filter.customStructure) ? this.columnDef.filter.customStructure.label : 'label';
const valueName = (this.columnDef.filter.customStructure) ? this.columnDef.filter.customStructure.value : 'value';
const isEnabledTranslate = (this.columnDef.filter.enableTranslateLabel) ? this.columnDef.filter.enableTranslateLabel : false;
let options = '';
optionCollection.forEach((option: any) => {
if (!option || (option[labelName] === undefined && option.labelKey === undefined)) {
throw new Error(`A collection with value/label (or value/labelKey when using Locale) is required to populate the Select list, for example:: { filter: type: FilterType.select, collection: [ { value: '1', label: 'One' } ]')`);
}
const labelKey = option.labelKey || option[labelName];
const textLabel = ((option.labelKey || isEnabledTranslate) && this.i18n && typeof this.i18n.tr === 'function') ? this.i18n.tr(labelKey || ' ') : labelKey;
options += `<option value="${option[valueName]}">${textLabel}</option>`;
});
return `<select class="form-control search-filter">${options}</select>`;
}
/**
* From the html template string, create a DOM element
* @param filterTemplate
*/
private createDomElement(filterTemplate: string) {
const $headerElm = this.grid.getHeaderRowColumn(this.columnDef.id);
$($headerElm).empty();
// create the DOM element & add an ID and filter class
const $filterElm = $(filterTemplate);
const searchTerm = (typeof this.searchTerm === 'boolean') ? `${this.searchTerm}` : this.searchTerm;
$filterElm.val(searchTerm || '');
$filterElm.attr('id', `filter-${this.columnDef.id}`);
$filterElm.data('columnId', this.columnDef.id);
// append the new DOM element to the header row
if ($filterElm && typeof $filterElm.appendTo === 'function') {
$filterElm.appendTo($headerElm);
}
return $filterElm;
}
}