UNPKG

9.22 kBPlain TextView Raw
1import {Utils as _} from "../utils";
2import {IFilterParams, IDoesFilterPassParams, SerializedFilter} from "../interfaces/iFilter";
3import {
4 ComparableBaseFilter,
5 BaseFilter,
6 IScalarFilterParams,
7 FilterConditionType,
8 IComparableFilterParams
9} from "./baseFilter";
10import {QuerySelector} from "../widgets/componentAnnotations";
11
12export interface SerializedTextFilter extends SerializedFilter {
13 filter: string;
14 type: string;
15}
16
17export interface TextComparator {
18 (filter: string, gridValue: any, filterText: string): boolean;
19}
20
21export interface TextFormatter {
22 (from: string): string;
23}
24
25export interface INumberFilterParams extends IScalarFilterParams {
26 debounceMs?: number;
27}
28
29export interface ITextFilterParams extends IComparableFilterParams {
30 textCustomComparator?: TextComparator;
31 debounceMs?: number;
32 caseSensitive?: boolean;
33}
34
35export class TextFilter extends ComparableBaseFilter <string, ITextFilterParams, SerializedTextFilter> {
36 @QuerySelector('#filterText')
37 private eFilterTextField: HTMLInputElement;
38
39 @QuerySelector('#filterConditionText')
40 private eFilterConditionTextField: HTMLInputElement;
41
42 private filterText: string;
43 private filterConditionText: string;
44 private comparator: TextComparator;
45 private formatter: TextFormatter;
46 static DEFAULT_FORMATTER: TextFormatter = (from: string)=> {
47 return from;
48 };
49 static DEFAULT_LOWERCASE_FORMATTER: TextFormatter = (from: string)=> {
50 if (from == null) { return null; }
51 return from.toString().toLowerCase();
52 };
53 static DEFAULT_COMPARATOR: TextComparator = (filter: string, value: any, filterText: string)=> {
54 switch (filter) {
55 case TextFilter.CONTAINS:
56 return value.indexOf(filterText) >= 0;
57 case TextFilter.NOT_CONTAINS:
58 return value.indexOf(filterText) === -1;
59 case TextFilter.EQUALS:
60 return value === filterText;
61 case TextFilter.NOT_EQUAL:
62 return value != filterText;
63 case TextFilter.STARTS_WITH:
64 return value.indexOf(filterText) === 0;
65 case TextFilter.ENDS_WITH:
66 let index = value.lastIndexOf(filterText);
67 return index >= 0 && index === (value.length - filterText.length);
68 default:
69 // should never happen
70 console.warn('invalid filter type ' + filter);
71 return false;
72 }
73 };
74
75 public getDefaultType(): string {
76 return BaseFilter.CONTAINS;
77 }
78
79 public customInit(): void {
80 this.comparator = this.filterParams.textCustomComparator ? this.filterParams.textCustomComparator : TextFilter.DEFAULT_COMPARATOR;
81 this.formatter =
82 this.filterParams.textFormatter ? this.filterParams.textFormatter :
83 this.filterParams.caseSensitive == true ? TextFilter.DEFAULT_FORMATTER :
84 TextFilter.DEFAULT_LOWERCASE_FORMATTER;
85 super.customInit();
86 }
87
88 modelFromFloatingFilter(from: string): SerializedTextFilter {
89 return {
90 type: this.filter,
91 filter: from,
92 filterType: 'text'
93 };
94 }
95
96 public getApplicableFilterTypes(): string[] {
97 return [BaseFilter.EQUALS, BaseFilter.NOT_EQUAL, BaseFilter.STARTS_WITH, BaseFilter.ENDS_WITH,
98 BaseFilter.CONTAINS, BaseFilter.NOT_CONTAINS];
99 }
100
101 public bodyTemplate(type:FilterConditionType): string {
102 let translate = this.translate.bind(this);
103 let fieldId = type == FilterConditionType.MAIN ? "filterText" : "filterConditionText";
104 return `<div class="ag-filter-body">
105 <input class="ag-filter-filter" id=${fieldId} type="text" placeholder="${translate('filterOoo', 'Filter...')}"/>
106 </div>`;
107 }
108
109 public initialiseFilterBodyUi(type:FilterConditionType) {
110 super.initialiseFilterBodyUi(type);
111 this.addFilterChangedListener(type);
112 this.setFilter(this.filterConditionText, FilterConditionType.CONDITION);
113 this.setFilterType(this.filterCondition, FilterConditionType.CONDITION);
114 }
115
116 private addFilterChangedListener(type:FilterConditionType) {
117 let eElement = type === FilterConditionType.MAIN ? this.eFilterTextField : this.eFilterConditionTextField;
118 let debounceMs = this.getDebounceMs(this.filterParams);
119 let toDebounce: () => void = _.debounce(()=>this.onFilterTextFieldChanged(type), debounceMs);
120 this.addDestroyableEventListener(eElement, 'input', toDebounce);
121 }
122
123 public refreshFilterBodyUi(type:FilterConditionType) {
124 if (this.eFilterConditionTextField){
125 this.addFilterChangedListener(FilterConditionType.CONDITION);
126 }
127 }
128
129 public afterGuiAttached() {
130 this.eFilterTextField.focus();
131 }
132
133 public filterValues(type:FilterConditionType): string {
134 return type === FilterConditionType.MAIN ? this.filterText : this.filterConditionText;
135 }
136
137 public individualFilterPasses (params: IDoesFilterPassParams, type:FilterConditionType): boolean {
138 let filterText:string = type == FilterConditionType.MAIN ? this.filterText : this.filterConditionText;
139 let filter:string = type == FilterConditionType.MAIN ? this.filter : this.filterCondition;
140
141 if (!filterText) {
142 return type === FilterConditionType.MAIN ? true : this.conditionValue === 'AND';
143 } else {
144 return this.checkIndividualFilter (params, filter, filterText);
145 }
146 }
147
148 private checkIndividualFilter (params: IDoesFilterPassParams, filterType:string, filterText: string) {
149 let value = this.filterParams.valueGetter(params.node);
150 if (value == null || value === undefined) {
151 return filterType === BaseFilter.NOT_EQUAL || filterType === BaseFilter.NOT_CONTAINS;
152 }
153 let valueFormatted: string = this.formatter(value);
154 return this.comparator (filterType, valueFormatted, filterText);
155 }
156
157 private onFilterTextFieldChanged(type:FilterConditionType) {
158 let value:string = type === FilterConditionType.MAIN ? this.eFilterTextField.value : this.eFilterConditionTextField.value;
159 let current:string = type === FilterConditionType.MAIN ? this.filterText : this.filterConditionText;
160
161 let filterText = _.makeNull(value);
162 if (filterText && filterText.trim() === '') {
163 filterText = null;
164 }
165
166 if (current !== filterText) {
167 let newLowerCase =
168 filterText && this.filterParams.caseSensitive != true ? filterText.toLowerCase() :
169 filterText;
170 let previousLowerCase = current && this.filterParams.caseSensitive != true ? current.toLowerCase() :
171 current;
172
173 if (type === FilterConditionType.MAIN){
174 this.filterText = this.formatter(filterText);
175
176 } else {
177 this.filterConditionText = this.formatter(filterText);
178 }
179 if (previousLowerCase !== newLowerCase) {
180 this.onFilterChanged();
181 }
182 }
183 }
184
185 public setFilter(filter: string, type:FilterConditionType): void {
186 filter = _.makeNull(filter);
187
188 if (type === FilterConditionType.MAIN) {
189 if (filter) {
190 this.filterText = this.formatter(filter);
191
192 if (!this.eFilterTextField) return;
193 this.eFilterTextField.value = filter;
194 } else {
195 this.filterText = null;
196
197 if (!this.eFilterTextField) return;
198 this.eFilterTextField.value = null;
199 }
200 } else {
201 if (filter) {
202 this.filterConditionText = this.formatter(filter);
203
204 if (!this.eFilterConditionTextField) return;
205 this.eFilterConditionTextField.value = filter;
206 } else {
207 this.filterConditionText = null;
208
209 if (!this.eFilterConditionTextField) return;
210 this.eFilterConditionTextField.value = null;
211 }
212 }
213 }
214
215 public getFilter(): string {
216 return this.filterText;
217 }
218
219 public resetState(): void {
220 this.setFilter(null, FilterConditionType.MAIN);
221 this.setFilterType(this.defaultFilter, FilterConditionType.MAIN);
222
223 this.setFilter(null, FilterConditionType.CONDITION);
224 this.setFilterType(this.defaultFilter, FilterConditionType.CONDITION);
225 }
226
227 public serialize(type:FilterConditionType): SerializedTextFilter {
228 let filter = type === FilterConditionType.MAIN ? this.filter : this.filterCondition;
229 let filterText = type === FilterConditionType.MAIN ? this.filterText : this.filterConditionText;
230 return {
231 type: filter ? filter : this.defaultFilter,
232 filter: filterText,
233 filterType: 'text'
234 };
235 }
236
237 public parse(model: SerializedTextFilter, type:FilterConditionType): void {
238 this.setFilterType(model.type, type);
239 this.setFilter(model.filter, type);
240 }
241
242 public setType(filterType: string, type:FilterConditionType): void {
243 this.setFilterType(filterType, type);
244 }
245
246}