@syncfusion/ej2-lists 31.1.17 → 31.2.12
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.
- package/dist/ej2-lists.min.js +3 -3
- package/dist/ej2-lists.umd.min.js +3 -3
- package/dist/ej2-lists.umd.min.js.map +1 -1
- package/dist/es6/ej2-lists.es2015.js +3 -1
- package/dist/es6/ej2-lists.es2015.js.map +1 -1
- package/dist/es6/ej2-lists.es5.js +3 -1
- package/dist/es6/ej2-lists.es5.js.map +1 -1
- package/dist/global/ej2-lists.min.js +3 -3
- package/dist/global/ej2-lists.min.js.map +1 -1
- package/dist/global/index.d.ts +2 -2
- package/package.json +12 -56
- package/src/common/list-base.js +3 -1
- package/dist/ts/common/index.d.ts +0 -4
- package/dist/ts/common/index.ts +0 -4
- package/dist/ts/common/list-base.d.ts +0 -415
- package/dist/ts/common/list-base.ts +0 -1362
- package/dist/ts/component.d.ts +0 -4
- package/dist/ts/component.ts +0 -4
- package/dist/ts/index.d.ts +0 -6
- package/dist/ts/index.ts +0 -6
- package/dist/ts/list-view/index.d.ts +0 -6
- package/dist/ts/list-view/index.ts +0 -6
- package/dist/ts/list-view/list-view-model.d.ts +0 -324
- package/dist/ts/list-view/list-view.d.ts +0 -845
- package/dist/ts/list-view/list-view.ts +0 -2740
- package/dist/ts/list-view/virtualization.d.ts +0 -97
- package/dist/ts/list-view/virtualization.ts +0 -947
- package/dist/ts/sortable/index.d.ts +0 -5
- package/dist/ts/sortable/index.ts +0 -5
- package/dist/ts/sortable/sortable-model.d.ts +0 -80
- package/dist/ts/sortable/sortable.d.ts +0 -146
- package/dist/ts/sortable/sortable.ts +0 -483
|
@@ -1,2740 +0,0 @@
|
|
|
1
|
-
import { Virtualization } from './virtualization';
|
|
2
|
-
import { merge, formatUnit, isNullOrUndefined, append, detach, ModuleDeclaration, extend } from '@syncfusion/ej2-base';
|
|
3
|
-
import { attributes, addClass, removeClass, prepend, closest, remove } from '@syncfusion/ej2-base';
|
|
4
|
-
import { Component, EventHandler, BaseEventArgs, Property, Complex, Event } from '@syncfusion/ej2-base';
|
|
5
|
-
import { NotifyPropertyChanges, INotifyPropertyChanged, ChildProperty } from '@syncfusion/ej2-base';
|
|
6
|
-
import { KeyboardEventArgs, EmitType, compile, SanitizeHtmlHelper } from '@syncfusion/ej2-base';
|
|
7
|
-
import { Animation, AnimationOptions, Effect, rippleEffect, Touch, SwipeEventArgs, animationMode } from '@syncfusion/ej2-base';
|
|
8
|
-
import { DataManager, Query } from '@syncfusion/ej2-data';
|
|
9
|
-
import { createCheckBox } from '@syncfusion/ej2-buttons';
|
|
10
|
-
import { ListBase, ListBaseOptions, SortOrder, getFieldValues, FieldsMapping } from '../common/list-base';
|
|
11
|
-
import { ListViewModel, FieldSettingsModel } from './list-view-model';
|
|
12
|
-
|
|
13
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
14
|
-
// Effect Configuration Effect[] = [fromViewBackward,fromViewForward,toViewBackward,toviewForward];
|
|
15
|
-
const effectsConfig: { [key: string]: Effect[] } = {
|
|
16
|
-
'None': [],
|
|
17
|
-
'SlideLeft': ['SlideRightOut', 'SlideLeftOut', 'SlideLeftIn', 'SlideRightIn'],
|
|
18
|
-
'SlideDown': ['SlideTopOut', 'SlideBottomOut', 'SlideBottomIn', 'SlideTopIn'],
|
|
19
|
-
'Zoom': ['FadeOut', 'FadeZoomOut', 'FadeZoomIn', 'FadeIn'],
|
|
20
|
-
'Fade': ['FadeOut', 'FadeOut', 'FadeIn', 'FadeIn']
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const effectsRTLConfig: { [key: string]: Effect[] } = {
|
|
25
|
-
'None': [],
|
|
26
|
-
'SlideLeft': ['SlideLeftOut', 'SlideRightOut', 'SlideRightIn', 'SlideLeftIn'],
|
|
27
|
-
'SlideDown': ['SlideBottomOut', 'SlideTopOut', 'SlideTopIn', 'SlideBottomIn'],
|
|
28
|
-
'Zoom': ['FadeZoomOut', 'FadeOut', 'FadeIn', 'FadeZoomIn'],
|
|
29
|
-
'Fade': ['FadeOut', 'FadeOut', 'FadeIn', 'FadeIn']
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
// don't use space in classnames.
|
|
33
|
-
export const classNames: ClassNames = {
|
|
34
|
-
root: 'e-listview',
|
|
35
|
-
hover: 'e-hover',
|
|
36
|
-
selected: 'e-active',
|
|
37
|
-
focused: 'e-focused',
|
|
38
|
-
parentItem: 'e-list-parent',
|
|
39
|
-
listItem: 'e-list-item',
|
|
40
|
-
listIcon: 'e-list-icon',
|
|
41
|
-
textContent: 'e-text-content',
|
|
42
|
-
listItemText: 'e-list-text',
|
|
43
|
-
groupListItem: 'e-list-group-item',
|
|
44
|
-
hasChild: 'e-has-child',
|
|
45
|
-
view: 'e-view',
|
|
46
|
-
header: 'e-list-header',
|
|
47
|
-
headerText: 'e-headertext',
|
|
48
|
-
headerTemplateText: 'e-headertemplate-text',
|
|
49
|
-
text: 'e-text',
|
|
50
|
-
disable: 'e-disabled',
|
|
51
|
-
container: 'e-list-container',
|
|
52
|
-
icon: 'e-icons',
|
|
53
|
-
backIcon: 'e-icon-back',
|
|
54
|
-
backButton: 'e-back-button',
|
|
55
|
-
checkboxWrapper: 'e-checkbox-wrapper',
|
|
56
|
-
checkbox: 'e-checkbox',
|
|
57
|
-
checked: 'e-check',
|
|
58
|
-
checklist: 'e-checklist',
|
|
59
|
-
checkboxIcon: 'e-frame',
|
|
60
|
-
checkboxRight: 'e-checkbox-right',
|
|
61
|
-
checkboxLeft: 'e-checkbox-left',
|
|
62
|
-
listviewCheckbox: 'e-listview-checkbox',
|
|
63
|
-
itemCheckList: 'e-checklist',
|
|
64
|
-
virtualElementContainer: 'e-list-virtualcontainer',
|
|
65
|
-
listTemplate: 'e-listview-template'
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const LISTVIEW_TEMPLATE_PROPERTY: string = 'Template';
|
|
69
|
-
const LISTVIEW_GROUPTEMPLATE_PROPERTY: string = 'GroupTemplate';
|
|
70
|
-
const LISTVIEW_HEADERTEMPLATE_PROPERTY: string = 'HeaderTemplate';
|
|
71
|
-
const swipeVelocity: number = 0.5;
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* An interface that holds options of fields.
|
|
75
|
-
*/
|
|
76
|
-
export interface Fields {
|
|
77
|
-
/**
|
|
78
|
-
* Specifies the id field mapped in dataSource.
|
|
79
|
-
*/
|
|
80
|
-
id?: string | number;
|
|
81
|
-
/**
|
|
82
|
-
* The `text` property is used to map the text value from the data source for each list item.
|
|
83
|
-
*/
|
|
84
|
-
text?: string | number;
|
|
85
|
-
/**
|
|
86
|
-
* It is used to map the custom field values of list item from the dataSource.
|
|
87
|
-
*/
|
|
88
|
-
[key: string]: Object | string | number | undefined;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Represents the field settings of the ListView.
|
|
94
|
-
*/
|
|
95
|
-
|
|
96
|
-
export class FieldSettings extends ChildProperty<FieldSettings> {
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Specifies the id field mapped in dataSource.
|
|
100
|
-
*/
|
|
101
|
-
@Property('id')
|
|
102
|
-
public id: string;
|
|
103
|
-
/**
|
|
104
|
-
* The `text` property is used to map the text value from the data source for each list item.
|
|
105
|
-
*/
|
|
106
|
-
@Property('text')
|
|
107
|
-
public text: string;
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* The `isChecked` property is used to check whether the list items are in checked state or not.
|
|
111
|
-
*/
|
|
112
|
-
@Property('isChecked')
|
|
113
|
-
public isChecked: string;
|
|
114
|
-
/**
|
|
115
|
-
* The `isVisible` property is used to check whether the list items are in visible state or not.
|
|
116
|
-
*/
|
|
117
|
-
@Property('isVisible')
|
|
118
|
-
public isVisible: string;
|
|
119
|
-
/**
|
|
120
|
-
* Specifies the enabled state of the ListView component.
|
|
121
|
-
* And, we can disable the component using this property by setting its value as false.
|
|
122
|
-
*/
|
|
123
|
-
@Property('enabled')
|
|
124
|
-
public enabled: string;
|
|
125
|
-
/**
|
|
126
|
-
* The `iconCss` is used to customize the icon to the list items dynamically.
|
|
127
|
-
* We can add a specific image to the icons using `iconCss` property.
|
|
128
|
-
*/
|
|
129
|
-
@Property('iconCss')
|
|
130
|
-
public iconCss: string;
|
|
131
|
-
/**
|
|
132
|
-
* The `child` property is used for nested navigation of listed items.
|
|
133
|
-
*/
|
|
134
|
-
@Property('child')
|
|
135
|
-
public child: string;
|
|
136
|
-
/**
|
|
137
|
-
* The `tooltip` is used to display the information about the target element while hovering on list items.
|
|
138
|
-
*/
|
|
139
|
-
@Property('tooltip')
|
|
140
|
-
public tooltip: string;
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* The `groupBy` property is used to wraps the ListView elements into a group.
|
|
144
|
-
*/
|
|
145
|
-
@Property('groupBy')
|
|
146
|
-
public groupBy: string;
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* The `sortBy` property used to enable the sorting of list items to be ascending or descending order.
|
|
150
|
-
*/
|
|
151
|
-
@Property('text')
|
|
152
|
-
public sortBy: string;
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* The `htmlAttributes` allows additional attributes such as id, class, etc., and
|
|
156
|
-
* accepts n number of attributes in a key-value pair format.
|
|
157
|
-
*/
|
|
158
|
-
@Property('htmlAttributes')
|
|
159
|
-
public htmlAttributes: string;
|
|
160
|
-
/**
|
|
161
|
-
* Specifies the `tableName` used to fetch data from a specific table in the server.
|
|
162
|
-
*/
|
|
163
|
-
@Property('tableName')
|
|
164
|
-
public tableName: string;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* An interface that holds animation settings.
|
|
169
|
-
*/
|
|
170
|
-
export interface AnimationSettings {
|
|
171
|
-
/**
|
|
172
|
-
* It is used to specify the effect which is shown in sub list transform.
|
|
173
|
-
*/
|
|
174
|
-
effect?: ListViewEffect;
|
|
175
|
-
/**
|
|
176
|
-
* It is used to specify the time duration of transform object.
|
|
177
|
-
*/
|
|
178
|
-
duration?: number;
|
|
179
|
-
/**
|
|
180
|
-
* It is used to specify the easing effect applied while transform
|
|
181
|
-
*/
|
|
182
|
-
easing?: string;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* An enum type that denotes the effects of the ListView. Available options are as follows None, SlideLeft, SlideDown, Zoom, Fade;
|
|
187
|
-
* ```props
|
|
188
|
-
* None :- No animation is applied when items are added or removed from the ListView.
|
|
189
|
-
* SlideLeft :- Items slide in from the left when added and slide out to the left when removed.
|
|
190
|
-
* SlideDown :- Items slide in from the top when added and slide out to the top when removed.
|
|
191
|
-
* Zoom :- Items zoom in or out when added or removed.
|
|
192
|
-
* Fade :- Items fade in or out when added or removed.
|
|
193
|
-
* ```
|
|
194
|
-
*/
|
|
195
|
-
export type ListViewEffect = 'None' | 'SlideLeft' | 'SlideDown' | 'Zoom' | 'Fade';
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* An enum type that denotes the position of checkbox of the ListView. Available options are as follows Left and Right;
|
|
199
|
-
* ```props
|
|
200
|
-
* Left :- The checkbox is positioned on the left side of the ListView item.
|
|
201
|
-
* Right :- The checkbox is positioned on the right side of the ListView item.
|
|
202
|
-
* ```
|
|
203
|
-
*/
|
|
204
|
-
export type checkBoxPosition = 'Left' | 'Right';
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Represents the EJ2 ListView control.
|
|
208
|
-
* ```html
|
|
209
|
-
* <div id="listview">
|
|
210
|
-
* <ul>
|
|
211
|
-
* <li>Favorite</li>
|
|
212
|
-
* <li>Documents</li>
|
|
213
|
-
* <li>Downloads</li>
|
|
214
|
-
* </ul>
|
|
215
|
-
* </div>
|
|
216
|
-
* ```
|
|
217
|
-
* ```typescript
|
|
218
|
-
* var listviewObject = new ListView({});
|
|
219
|
-
* listviewObject.appendTo("#listview");
|
|
220
|
-
* ```
|
|
221
|
-
*/
|
|
222
|
-
@NotifyPropertyChanges
|
|
223
|
-
export class ListView extends Component<HTMLElement> implements INotifyPropertyChanged {
|
|
224
|
-
|
|
225
|
-
private ulElement: HTMLElement;
|
|
226
|
-
private selectedLI: Element;
|
|
227
|
-
private onUIScrolled: Function;
|
|
228
|
-
private curUL: HTMLElement;
|
|
229
|
-
private curDSLevel: string[];
|
|
230
|
-
private curViewDS: DataSource[] | string[] | number[];
|
|
231
|
-
private curDSJSON: DataSource;
|
|
232
|
-
public localData: DataSource[];
|
|
233
|
-
private liCollection: HTMLElement[];
|
|
234
|
-
private headerEle: HTMLElement;
|
|
235
|
-
private contentContainer: HTMLElement;
|
|
236
|
-
private touchModule: Touch;
|
|
237
|
-
private listBaseOption: ListBaseOptions;
|
|
238
|
-
public virtualizationModule: Virtualization;
|
|
239
|
-
private animateOptions: AnimationOptions;
|
|
240
|
-
private rippleFn: Function;
|
|
241
|
-
private isNestedList: boolean;
|
|
242
|
-
private currentLiElements: HTMLElement[];
|
|
243
|
-
private selectedData: string[] | string;
|
|
244
|
-
private selectedId: string[];
|
|
245
|
-
private isWindow: boolean;
|
|
246
|
-
private selectedItems: SelectedItem;
|
|
247
|
-
private aniObj: Animation;
|
|
248
|
-
private LISTVIEW_TEMPLATE_ID: string;
|
|
249
|
-
private LISTVIEW_GROUPTEMPLATE_ID: string;
|
|
250
|
-
private LISTVIEW_HEADERTEMPLATE_ID: string;
|
|
251
|
-
private liElement: Element;
|
|
252
|
-
private virtualCheckBox: Element | string;
|
|
253
|
-
private liElementHeight: number;
|
|
254
|
-
private previousSelectedItems: string[] = [];
|
|
255
|
-
private hiddenItems: string[] = [];
|
|
256
|
-
private enabledItems: string[] = [];
|
|
257
|
-
private disabledItems: string[] = [];
|
|
258
|
-
private isOffline: boolean;
|
|
259
|
-
private previousScrollTop: number;
|
|
260
|
-
/**
|
|
261
|
-
* The `cssClass` property is used to add a user-preferred class name in the root element of the ListView,
|
|
262
|
-
* using which we can customize the component (both CSS and functionality customization)
|
|
263
|
-
*
|
|
264
|
-
* {% codeBlock src='listview/cssClass/index.md' %}{% endcodeBlock %}
|
|
265
|
-
*
|
|
266
|
-
* @default ''
|
|
267
|
-
*/
|
|
268
|
-
@Property('')
|
|
269
|
-
public cssClass: string;
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* If `enableVirtualization` set to true, which will increase the ListView performance, while loading a large amount of data.
|
|
273
|
-
*
|
|
274
|
-
* {% codeBlock src='listview/enableVirtualization/index.md' %}{% endcodeBlock %}
|
|
275
|
-
*
|
|
276
|
-
* @default false
|
|
277
|
-
*/
|
|
278
|
-
@Property(false)
|
|
279
|
-
public enableVirtualization: boolean;
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* The `htmlAttributes` allows additional attributes such as id, class, etc., and
|
|
283
|
-
* accepts n number of attributes in a key-value pair format.
|
|
284
|
-
*
|
|
285
|
-
* {% codeBlock src='listview/htmlAttributes/index.md' %}{% endcodeBlock %}
|
|
286
|
-
*
|
|
287
|
-
* @default {}
|
|
288
|
-
*/
|
|
289
|
-
@Property({})
|
|
290
|
-
public htmlAttributes: { [key: string]: string; };
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* If `enable` set to true, the list items are enabled.
|
|
294
|
-
* And, we can disable the component using this property by setting its value as false.
|
|
295
|
-
*
|
|
296
|
-
* {% codeBlock src='listview/enable/index.md' %}{% endcodeBlock %}
|
|
297
|
-
*
|
|
298
|
-
* @default true
|
|
299
|
-
*/
|
|
300
|
-
@Property(true)
|
|
301
|
-
public enable: boolean;
|
|
302
|
-
/* es-lint disable */
|
|
303
|
-
/**
|
|
304
|
-
* The `dataSource` provides the data to render the ListView component which is mapped with the fields of ListView.
|
|
305
|
-
*
|
|
306
|
-
* @isGenericType true
|
|
307
|
-
*
|
|
308
|
-
* {% codeBlock src='listview/dataSource/index.md' %}{% endcodeBlock %}
|
|
309
|
-
*
|
|
310
|
-
* @default []
|
|
311
|
-
*/
|
|
312
|
-
@Property([])
|
|
313
|
-
public dataSource: { [key: string]: Object }[] | string[] | number[] | DataManager;
|
|
314
|
-
/* es-lint enable */
|
|
315
|
-
/**
|
|
316
|
-
* The `query` is used to fetch the specific data from dataSource by using where and select keywords.
|
|
317
|
-
*
|
|
318
|
-
* {% codeBlock src='listview/query/index.md' %}{% endcodeBlock %}
|
|
319
|
-
*
|
|
320
|
-
* @default null
|
|
321
|
-
*/
|
|
322
|
-
@Property()
|
|
323
|
-
public query: Query;
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* The `fields` is used to map keys from the dataSource which extracts the appropriate data from the dataSource
|
|
327
|
-
* with specified mapped with the column fields to render the ListView.
|
|
328
|
-
*
|
|
329
|
-
* {% codeBlock src='listview/fields/index.md' %}{% endcodeBlock %}
|
|
330
|
-
*
|
|
331
|
-
* @default defaultMappedFields
|
|
332
|
-
*/
|
|
333
|
-
@Complex<FieldSettingsModel>(ListBase.defaultMappedFields, FieldSettings)
|
|
334
|
-
public fields: FieldSettingsModel;
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* The `animation` property provides an option to apply the different
|
|
338
|
-
* animations on the ListView component.
|
|
339
|
-
*
|
|
340
|
-
* {% codeBlock src='listview/animation/index.md' %}{% endcodeBlock %}
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
* @default { effect: 'SlideLeft', duration: 400, easing: 'ease' }
|
|
344
|
-
*/
|
|
345
|
-
@Property<AnimationSettings>({ effect: 'SlideLeft', duration: 400, easing: 'ease' })
|
|
346
|
-
public animation: AnimationSettings;
|
|
347
|
-
|
|
348
|
-
/**
|
|
349
|
-
* The `sortOrder` is used to sort the data source. The available type of sort orders are,
|
|
350
|
-
* * `None` - The data source is not sorting.
|
|
351
|
-
* * `Ascending` - The data source is sorting with ascending order.
|
|
352
|
-
* * `Descending` - The data source is sorting with descending order.
|
|
353
|
-
*
|
|
354
|
-
* {% codeBlock src='listview/sortOrder/index.md' %}{% endcodeBlock %}
|
|
355
|
-
*
|
|
356
|
-
* @default 'None'
|
|
357
|
-
*/
|
|
358
|
-
@Property<SortOrder>('None')
|
|
359
|
-
public sortOrder: SortOrder;
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* If `showIcon` set to true, which will show or hide the icon of the list item.
|
|
363
|
-
*
|
|
364
|
-
* {% codeBlock src='listview/showIcon/index.md' %}{% endcodeBlock %}
|
|
365
|
-
*
|
|
366
|
-
* @default false
|
|
367
|
-
*/
|
|
368
|
-
@Property<boolean>(false)
|
|
369
|
-
public showIcon: boolean;
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* If `showCheckBox` set to true, which will show or hide the checkbox.
|
|
373
|
-
*
|
|
374
|
-
* {% codeBlock src='listview/showCheckBox/index.md' %}{% endcodeBlock %}
|
|
375
|
-
*
|
|
376
|
-
*
|
|
377
|
-
* @default false
|
|
378
|
-
*/
|
|
379
|
-
@Property<boolean>(false)
|
|
380
|
-
public showCheckBox: boolean;
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* The `checkBoxPosition` is used to set the position of check box in a list item.
|
|
384
|
-
* By default, the `checkBoxPosition` is Left, which will appear before the text content in a list item.
|
|
385
|
-
*
|
|
386
|
-
* {% codeBlock src='listview/checkBoxPosition/index.md' %}{% endcodeBlock %}
|
|
387
|
-
*
|
|
388
|
-
* @default 'Left'
|
|
389
|
-
*/
|
|
390
|
-
@Property<string>('Left')
|
|
391
|
-
public checkBoxPosition: checkBoxPosition;
|
|
392
|
-
|
|
393
|
-
/**
|
|
394
|
-
* The `headerTitle` is used to set the title of the ListView component.
|
|
395
|
-
*
|
|
396
|
-
* {% codeBlock src='listview/headerTitle/index.md' %}{% endcodeBlock %}
|
|
397
|
-
*
|
|
398
|
-
*
|
|
399
|
-
* @default ""
|
|
400
|
-
*/
|
|
401
|
-
@Property<string>('')
|
|
402
|
-
public headerTitle: string;
|
|
403
|
-
|
|
404
|
-
/**
|
|
405
|
-
* If `showHeader` set to true, which will show or hide the header of the ListView component.
|
|
406
|
-
*
|
|
407
|
-
* {% codeBlock src='listview/showHeader/index.md' %}{% endcodeBlock %}
|
|
408
|
-
*
|
|
409
|
-
* @default false
|
|
410
|
-
*/
|
|
411
|
-
@Property<boolean>(false)
|
|
412
|
-
public showHeader: boolean;
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
* Specifies whether to display or remove the untrusted HTML values in the ListView component.
|
|
416
|
-
* If 'enableHtmlSanitizer' set to true, the component will sanitize any suspected untrusted strings and scripts before rendering them.
|
|
417
|
-
*
|
|
418
|
-
* {% codeBlock src='listview/enableHtmlSanitizer/index.md' %}{% endcodeBlock %}
|
|
419
|
-
*
|
|
420
|
-
* @default true
|
|
421
|
-
*/
|
|
422
|
-
@Property(true)
|
|
423
|
-
public enableHtmlSanitizer: boolean;
|
|
424
|
-
|
|
425
|
-
/**
|
|
426
|
-
* Defines the height of the ListView component which accepts both string and number values.
|
|
427
|
-
*
|
|
428
|
-
* {% codeBlock src='listview/height/index.md' %}{% endcodeBlock %}
|
|
429
|
-
*
|
|
430
|
-
* @default ''
|
|
431
|
-
*/
|
|
432
|
-
@Property('')
|
|
433
|
-
public height: number | string;
|
|
434
|
-
|
|
435
|
-
/**
|
|
436
|
-
* Defines the width of the ListView component which accepts both string and number values.
|
|
437
|
-
*
|
|
438
|
-
* {% codeBlock src='listview/width/index.md' %}{% endcodeBlock %}
|
|
439
|
-
*
|
|
440
|
-
* @default ''
|
|
441
|
-
*/
|
|
442
|
-
@Property('')
|
|
443
|
-
public width: number | string;
|
|
444
|
-
|
|
445
|
-
/**
|
|
446
|
-
* The ListView component supports to customize the content of each list items with the help of `template` property.
|
|
447
|
-
*
|
|
448
|
-
* {% codeBlock src='listview/template/index.md' %}{% endcodeBlock %}
|
|
449
|
-
*
|
|
450
|
-
* @default null
|
|
451
|
-
* @angularType string | object
|
|
452
|
-
* @reactType string | function | JSX.Element
|
|
453
|
-
* @vueType string | function
|
|
454
|
-
* @aspType string
|
|
455
|
-
*/
|
|
456
|
-
@Property(null)
|
|
457
|
-
public template: string | Function;
|
|
458
|
-
|
|
459
|
-
/**
|
|
460
|
-
* The ListView has an option to custom design the ListView header title with the help of `headerTemplate` property.
|
|
461
|
-
*
|
|
462
|
-
* {% codeBlock src="listview/headerTemplate/index.md" %}{% endcodeBlock %}
|
|
463
|
-
*
|
|
464
|
-
* @default null
|
|
465
|
-
* @angularType string | object
|
|
466
|
-
* @reactType string | function | JSX.Element
|
|
467
|
-
* @vueType string | function
|
|
468
|
-
* @aspType string
|
|
469
|
-
*/
|
|
470
|
-
@Property(null)
|
|
471
|
-
public headerTemplate: string | Function;
|
|
472
|
-
|
|
473
|
-
/**
|
|
474
|
-
* The ListView has an option to custom design the group header title with the help of `groupTemplate` property.
|
|
475
|
-
*
|
|
476
|
-
* {% codeBlock src="listview/groupTemplate/index.md" %}{% endcodeBlock %}
|
|
477
|
-
*
|
|
478
|
-
* @default null
|
|
479
|
-
* @angularType string | object
|
|
480
|
-
* @reactType string | function | JSX.Element
|
|
481
|
-
* @vueType string | function
|
|
482
|
-
* @aspType string
|
|
483
|
-
*/
|
|
484
|
-
@Property(null)
|
|
485
|
-
public groupTemplate: string | Function;
|
|
486
|
-
|
|
487
|
-
/**
|
|
488
|
-
* Triggers when we select the list item in the component.
|
|
489
|
-
*
|
|
490
|
-
* @event 'object'
|
|
491
|
-
*/
|
|
492
|
-
@Event()
|
|
493
|
-
public select: EmitType<SelectEventArgs>;
|
|
494
|
-
|
|
495
|
-
/**
|
|
496
|
-
* Triggers when every ListView action starts.
|
|
497
|
-
*
|
|
498
|
-
* @event 'object'
|
|
499
|
-
*/
|
|
500
|
-
@Event()
|
|
501
|
-
public actionBegin: EmitType<object>;
|
|
502
|
-
|
|
503
|
-
/**
|
|
504
|
-
* Triggers when every ListView actions completed.
|
|
505
|
-
*
|
|
506
|
-
* @event 'object'
|
|
507
|
-
*/
|
|
508
|
-
/* es-lint disable */
|
|
509
|
-
@Event()
|
|
510
|
-
public actionComplete: EmitType<MouseEvent>;
|
|
511
|
-
/* es-lint enable */
|
|
512
|
-
/**
|
|
513
|
-
* Triggers, when the data fetch request from the remote server, fails.
|
|
514
|
-
*
|
|
515
|
-
* @event 'object'
|
|
516
|
-
*
|
|
517
|
-
*/
|
|
518
|
-
@Event()
|
|
519
|
-
public actionFailure: EmitType<MouseEvent>;
|
|
520
|
-
|
|
521
|
-
/**
|
|
522
|
-
* Triggers when scrollbar of the ListView component reaches to the top or bottom.
|
|
523
|
-
*
|
|
524
|
-
* @event 'object'
|
|
525
|
-
*/
|
|
526
|
-
@Event()
|
|
527
|
-
public scroll: EmitType<ScrolledEventArgs>;
|
|
528
|
-
|
|
529
|
-
/**
|
|
530
|
-
* Constructor for creating the widget
|
|
531
|
-
*
|
|
532
|
-
* @param options
|
|
533
|
-
*
|
|
534
|
-
* @param element
|
|
535
|
-
*/
|
|
536
|
-
|
|
537
|
-
constructor(options?: ListViewModel, element?: string | HTMLElement) {
|
|
538
|
-
super(options, <HTMLElement | string>element);
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
/**
|
|
542
|
-
* @param newProp
|
|
543
|
-
*
|
|
544
|
-
* @param oldProp
|
|
545
|
-
*
|
|
546
|
-
* @private
|
|
547
|
-
*/
|
|
548
|
-
|
|
549
|
-
public onPropertyChanged(newProp: ListViewModel, oldProp: ListViewModel): void {
|
|
550
|
-
for (const prop of Object.keys(newProp)) {
|
|
551
|
-
switch (prop) {
|
|
552
|
-
case 'htmlAttributes':
|
|
553
|
-
this.setHTMLAttribute();
|
|
554
|
-
break;
|
|
555
|
-
case 'cssClass':
|
|
556
|
-
this.setCSSClass(oldProp.cssClass);
|
|
557
|
-
break;
|
|
558
|
-
case 'enable':
|
|
559
|
-
this.setEnable();
|
|
560
|
-
break;
|
|
561
|
-
case 'width':
|
|
562
|
-
case 'height':
|
|
563
|
-
this.setSize();
|
|
564
|
-
break;
|
|
565
|
-
case 'enableRtl':
|
|
566
|
-
this.setEnableRTL();
|
|
567
|
-
break;
|
|
568
|
-
case 'fields':
|
|
569
|
-
this.listBaseOption.fields = (this.fields as FieldSettingsModel & { properties: object }).properties;
|
|
570
|
-
if (this.enableVirtualization) {
|
|
571
|
-
this.virtualizationModule.reRenderUiVirtualization();
|
|
572
|
-
} else {
|
|
573
|
-
this.reRender();
|
|
574
|
-
}
|
|
575
|
-
break;
|
|
576
|
-
case 'headerTitle':
|
|
577
|
-
if (!this.curDSLevel.length) {
|
|
578
|
-
this.header(this.headerTitle, false, 'header');
|
|
579
|
-
}
|
|
580
|
-
break;
|
|
581
|
-
case 'query':
|
|
582
|
-
if (this.enableVirtualization) {
|
|
583
|
-
this.virtualizationModule.reRenderUiVirtualization();
|
|
584
|
-
} else {
|
|
585
|
-
this.reRender();
|
|
586
|
-
}
|
|
587
|
-
break;
|
|
588
|
-
case 'showHeader':
|
|
589
|
-
this.header(this.headerTitle, false, 'header');
|
|
590
|
-
break;
|
|
591
|
-
case 'enableVirtualization':
|
|
592
|
-
if (!isNullOrUndefined(this.contentContainer)) {
|
|
593
|
-
detach(this.contentContainer);
|
|
594
|
-
}
|
|
595
|
-
this.refresh();
|
|
596
|
-
break;
|
|
597
|
-
case 'showCheckBox':
|
|
598
|
-
case 'checkBoxPosition':
|
|
599
|
-
if (this.enableVirtualization) {
|
|
600
|
-
this.virtualizationModule.reRenderUiVirtualization();
|
|
601
|
-
} else {
|
|
602
|
-
this.setCheckbox();
|
|
603
|
-
}
|
|
604
|
-
break;
|
|
605
|
-
case 'dataSource':
|
|
606
|
-
this.previousScrollTop = this.element.scrollTop;
|
|
607
|
-
if (this.enableVirtualization) {
|
|
608
|
-
this.virtualizationModule.reRenderUiVirtualization();
|
|
609
|
-
} else {
|
|
610
|
-
this.reRender();
|
|
611
|
-
}
|
|
612
|
-
break;
|
|
613
|
-
case 'sortOrder':
|
|
614
|
-
case 'template':
|
|
615
|
-
if (!this.enableVirtualization) {
|
|
616
|
-
this.refresh();
|
|
617
|
-
}
|
|
618
|
-
break;
|
|
619
|
-
case 'showIcon':
|
|
620
|
-
if (this.enableVirtualization) {
|
|
621
|
-
this.virtualizationModule.reRenderUiVirtualization();
|
|
622
|
-
} else {
|
|
623
|
-
this.listBaseOption.showIcon = this.showIcon;
|
|
624
|
-
this.curViewDS = this.getSubDS();
|
|
625
|
-
this.resetCurrentList();
|
|
626
|
-
}
|
|
627
|
-
break;
|
|
628
|
-
default:
|
|
629
|
-
break;
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
// Model Changes
|
|
635
|
-
private setHTMLAttribute(): void {
|
|
636
|
-
if (!isNullOrUndefined(this.htmlAttributes) && Object.keys(this.htmlAttributes).length) {
|
|
637
|
-
attributes(this.element, this.htmlAttributes);
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
private setCSSClass(oldCSSClass?: string): void {
|
|
642
|
-
if (this.cssClass) {
|
|
643
|
-
addClass([this.element], this.cssClass.split(' ').filter((css: string) => css));
|
|
644
|
-
}
|
|
645
|
-
if (oldCSSClass) {
|
|
646
|
-
removeClass([this.element], oldCSSClass.split(' ').filter((css: string) => css));
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
private setSize(): void {
|
|
651
|
-
this.element.style.height = formatUnit(this.height);
|
|
652
|
-
this.element.style.width = formatUnit(this.width);
|
|
653
|
-
this.isWindow = this.element.clientHeight ? false : true;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
private setEnable(): void {
|
|
657
|
-
this.enableElement(this.element, this.enable);
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
private setEnableRTL(): void {
|
|
661
|
-
if (this.enableRtl) {
|
|
662
|
-
this.element.classList.add('e-rtl');
|
|
663
|
-
} else {
|
|
664
|
-
this.element.classList.remove('e-rtl');
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
private enableElement(element: HTMLElement, isEnabled?: boolean): void {
|
|
669
|
-
if (isEnabled) {
|
|
670
|
-
element.classList.remove(classNames.disable);
|
|
671
|
-
} else {
|
|
672
|
-
element.classList.add(classNames.disable);
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
// Support Component Functions
|
|
677
|
-
private header(text?: string, showBack?: boolean, prop?: string): void {
|
|
678
|
-
if (this.headerEle === undefined && this.showHeader) {
|
|
679
|
-
this.headerEle = this.createElement('div', { className: classNames.header });
|
|
680
|
-
const innerHeaderEle: HTMLElement = this.createElement('span', { className: classNames.headerText });
|
|
681
|
-
if (this.enableHtmlSanitizer) {
|
|
682
|
-
this.setProperties({ headerTitle: SanitizeHtmlHelper.sanitize(this.headerTitle) }, true);
|
|
683
|
-
innerHeaderEle.innerText = this.headerTitle;
|
|
684
|
-
} else {
|
|
685
|
-
innerHeaderEle.innerHTML = this.headerTitle;
|
|
686
|
-
}
|
|
687
|
-
const textEle: HTMLElement = this.createElement('div', { className: classNames.text, innerHTML: innerHeaderEle.outerHTML });
|
|
688
|
-
const hedBackButton: HTMLElement = this.createElement('div', {
|
|
689
|
-
className: classNames.icon + ' ' + classNames.backIcon + ' ' + classNames.backButton,
|
|
690
|
-
attrs: { style: 'display:none;' }
|
|
691
|
-
});
|
|
692
|
-
this.headerEle.appendChild(hedBackButton);
|
|
693
|
-
this.headerEle.appendChild(textEle);
|
|
694
|
-
if (this.headerTemplate) {
|
|
695
|
-
const compiledString: Function = compile(this.headerTemplate);
|
|
696
|
-
const headerTemplateEle: HTMLElement = this.createElement('div', { className: classNames.headerTemplateText });
|
|
697
|
-
const compiledElement: HTMLElement[] =
|
|
698
|
-
compiledString({}, this, prop, this.LISTVIEW_HEADERTEMPLATE_ID, null, null, this.headerEle);
|
|
699
|
-
if (compiledElement) {
|
|
700
|
-
append(compiledElement, headerTemplateEle);
|
|
701
|
-
}
|
|
702
|
-
append([headerTemplateEle], this.headerEle);
|
|
703
|
-
if ((this as any).isReact) {
|
|
704
|
-
this.renderReactTemplates();
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
if (this.headerTemplate && this.headerTitle) {
|
|
708
|
-
textEle.classList.add('header');
|
|
709
|
-
}
|
|
710
|
-
this.element.classList.add('e-has-header');
|
|
711
|
-
prepend([this.headerEle], this.element);
|
|
712
|
-
} else if (this.headerEle) {
|
|
713
|
-
if (this.showHeader) {
|
|
714
|
-
this.headerEle.style.display = '';
|
|
715
|
-
const textEle: Element = this.headerEle.querySelector('.' + classNames.headerText);
|
|
716
|
-
const hedBackButton: Element = this.headerEle.querySelector('.' + classNames.backIcon);
|
|
717
|
-
if (this.enableHtmlSanitizer) {
|
|
718
|
-
text = SanitizeHtmlHelper.sanitize(text);
|
|
719
|
-
}
|
|
720
|
-
textEle.innerHTML = text;
|
|
721
|
-
if (this.headerTemplate && showBack) {
|
|
722
|
-
textEle.parentElement.classList.remove('header');
|
|
723
|
-
this.headerEle.querySelector('.' + classNames.headerTemplateText).classList.add('nested-header');
|
|
724
|
-
}
|
|
725
|
-
if (this.headerTemplate && !showBack) {
|
|
726
|
-
textEle.parentElement.classList.add('header');
|
|
727
|
-
this.headerEle.querySelector('.' + classNames.headerTemplateText).classList.remove('nested-header');
|
|
728
|
-
this.headerEle.querySelector('.' + classNames.headerTemplateText).classList.add('header');
|
|
729
|
-
}
|
|
730
|
-
if (showBack === true) {
|
|
731
|
-
(hedBackButton as HTMLElement).style.display = '';
|
|
732
|
-
} else {
|
|
733
|
-
(hedBackButton as HTMLElement).style.display = 'none';
|
|
734
|
-
}
|
|
735
|
-
} else {
|
|
736
|
-
this.headerEle.style.display = 'none';
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
// Animation Related Functions
|
|
742
|
-
private switchView(fromView: HTMLElement, toView: HTMLElement, reverse?: boolean): void {
|
|
743
|
-
if (fromView && toView) {
|
|
744
|
-
const fPos: string = fromView.style.position;
|
|
745
|
-
const overflow: string = (this.element.style.overflow !== 'hidden') ? this.element.style.overflow : '';
|
|
746
|
-
|
|
747
|
-
fromView.style.position = 'absolute';
|
|
748
|
-
fromView.classList.add('e-view');
|
|
749
|
-
let anim: Effect[];
|
|
750
|
-
let duration: number = this.animation.duration;
|
|
751
|
-
if (this.animation.effect) {
|
|
752
|
-
anim = (this.enableRtl ? effectsRTLConfig[this.animation.effect] : effectsConfig[this.animation.effect]);
|
|
753
|
-
} else {
|
|
754
|
-
const slideLeft: string = 'SlideLeft';
|
|
755
|
-
anim = effectsConfig[`${slideLeft}`];
|
|
756
|
-
reverse = this.enableRtl;
|
|
757
|
-
duration = 0;
|
|
758
|
-
}
|
|
759
|
-
this.element.style.overflow = 'hidden';
|
|
760
|
-
this.aniObj.animate(fromView, {
|
|
761
|
-
name: (reverse === true ? anim[0] : anim[1]),
|
|
762
|
-
duration: (duration === 0 && animationMode === 'Enable') ? 400 : duration,
|
|
763
|
-
timingFunction: this.animation.easing,
|
|
764
|
-
end: (): void => {
|
|
765
|
-
fromView.style.display = 'none';
|
|
766
|
-
this.element.style.overflow = overflow;
|
|
767
|
-
fromView.style.position = fPos;
|
|
768
|
-
fromView.classList.remove('e-view');
|
|
769
|
-
}
|
|
770
|
-
});
|
|
771
|
-
toView.style.display = '';
|
|
772
|
-
this.aniObj.animate(toView, {
|
|
773
|
-
name: (reverse === true ? anim[2] : anim[3]),
|
|
774
|
-
duration: (duration === 0 && animationMode === 'Enable') ? 400 : duration,
|
|
775
|
-
timingFunction: this.animation.easing,
|
|
776
|
-
end: (): void => {
|
|
777
|
-
this.trigger('actionComplete');
|
|
778
|
-
}
|
|
779
|
-
});
|
|
780
|
-
this.curUL = toView;
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
protected preRender(): void {
|
|
785
|
-
if (this.template) {
|
|
786
|
-
try {
|
|
787
|
-
if (typeof this.template !== 'function' && document.querySelectorAll(this.template).length) {
|
|
788
|
-
this.setProperties({ template: document.querySelector(this.template).innerHTML.trim() }, true);
|
|
789
|
-
}
|
|
790
|
-
} catch (e) {
|
|
791
|
-
compile(this.template);
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
this.listBaseOption = {
|
|
795
|
-
template: this.template,
|
|
796
|
-
headerTemplate: this.headerTemplate,
|
|
797
|
-
groupTemplate: this.groupTemplate, expandCollapse: true, listClass: '',
|
|
798
|
-
ariaAttributes: {
|
|
799
|
-
itemRole: 'listitem', listRole: 'list', itemText: '',
|
|
800
|
-
groupItemRole: 'presentation', wrapperRole: 'presentation'
|
|
801
|
-
},
|
|
802
|
-
fields: ((this.fields as FieldSettingsModel & { properties: Object }).properties) as FieldsMapping,
|
|
803
|
-
sortOrder: this.sortOrder,
|
|
804
|
-
showIcon: this.showIcon,
|
|
805
|
-
itemCreated: this.renderCheckbox.bind(this),
|
|
806
|
-
templateID: `${this.element.id}${LISTVIEW_TEMPLATE_PROPERTY}`,
|
|
807
|
-
groupTemplateID: `${this.element.id}${LISTVIEW_GROUPTEMPLATE_PROPERTY}`,
|
|
808
|
-
enableHtmlSanitizer: this.enableHtmlSanitizer
|
|
809
|
-
};
|
|
810
|
-
this.initialization();
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
private initialization(): void {
|
|
814
|
-
this.curDSLevel = [];
|
|
815
|
-
this.animateOptions = {};
|
|
816
|
-
this.curViewDS = [];
|
|
817
|
-
this.currentLiElements = [];
|
|
818
|
-
this.isNestedList = false;
|
|
819
|
-
this.selectedData = [];
|
|
820
|
-
this.selectedId = this.enablePersistence ? this.selectedId : [];
|
|
821
|
-
this.LISTVIEW_TEMPLATE_ID = `${this.element.id}${LISTVIEW_TEMPLATE_PROPERTY}`;
|
|
822
|
-
this.LISTVIEW_GROUPTEMPLATE_ID = `${this.element.id}${LISTVIEW_GROUPTEMPLATE_PROPERTY}`;
|
|
823
|
-
this.LISTVIEW_HEADERTEMPLATE_ID = `${this.element.id}${LISTVIEW_HEADERTEMPLATE_PROPERTY}`;
|
|
824
|
-
this.aniObj = new Animation(this.animateOptions);
|
|
825
|
-
this.removeElement(this.curUL);
|
|
826
|
-
this.removeElement(this.ulElement);
|
|
827
|
-
this.removeElement(this.headerEle);
|
|
828
|
-
this.removeElement(this.contentContainer);
|
|
829
|
-
this.curUL = this.ulElement = this.liCollection = this.headerEle = this.contentContainer = undefined;
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
private renderCheckbox(args: ItemCreatedArgs): void {
|
|
833
|
-
if (args.item.classList.contains(classNames.hasChild)) {
|
|
834
|
-
this.isNestedList = true;
|
|
835
|
-
}
|
|
836
|
-
if (this.showCheckBox && args.item.classList.contains(classNames.listItem)) {
|
|
837
|
-
let fieldData: DataSource;
|
|
838
|
-
const checkboxElement: Element = createCheckBox(this.createElement, false, {
|
|
839
|
-
checked: false, enableRtl: this.enableRtl,
|
|
840
|
-
cssClass: classNames.listviewCheckbox
|
|
841
|
-
});
|
|
842
|
-
checkboxElement.setAttribute('role', 'checkbox');
|
|
843
|
-
const frameElement: Element = checkboxElement.querySelector('.' + classNames.checkboxIcon);
|
|
844
|
-
args.item.classList.add(classNames.itemCheckList);
|
|
845
|
-
args.item.firstElementChild.classList.add(classNames.checkbox);
|
|
846
|
-
if (this.template && this.element) {
|
|
847
|
-
addClass([this.element], classNames.listTemplate);
|
|
848
|
-
} else if (this.template === null && this.element && this.element.classList && this.element.classList.contains('e-listview-template')) {
|
|
849
|
-
removeClass([this.element], classNames.listTemplate);
|
|
850
|
-
}
|
|
851
|
-
if (typeof (this.dataSource as string[])[0] !== 'string' && typeof (this.dataSource as number[])[0] !== 'number') {
|
|
852
|
-
fieldData = <DataSource>getFieldValues(args.curData, this.listBaseOption.fields);
|
|
853
|
-
if (this.enablePersistence && !isNullOrUndefined(this.selectedId)) {
|
|
854
|
-
const index: number = this.selectedId.findIndex(
|
|
855
|
-
(e: string) => e === fieldData[this.listBaseOption.fields.id].toString()
|
|
856
|
-
);
|
|
857
|
-
if (index !== -1) {
|
|
858
|
-
this.checkInternally(args, checkboxElement);
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
else if (<object>fieldData[this.listBaseOption.fields.isChecked]) {
|
|
862
|
-
this.checkInternally(args, checkboxElement);
|
|
863
|
-
}
|
|
864
|
-
} else if (((typeof (this.dataSource as string[])[0] === 'string' ||
|
|
865
|
-
typeof (this.dataSource as number[])[0] === 'number') && this.selectedData.indexOf(args.text) !== -1)) {
|
|
866
|
-
this.checkInternally(args, checkboxElement);
|
|
867
|
-
}
|
|
868
|
-
checkboxElement.setAttribute('aria-checked', frameElement.classList.contains(classNames.checked) ? 'true' : 'false');
|
|
869
|
-
checkboxElement.setAttribute('aria-label', args.text);
|
|
870
|
-
if (this.checkBoxPosition === 'Left') {
|
|
871
|
-
checkboxElement.classList.add(classNames.checkboxLeft);
|
|
872
|
-
args.item.firstElementChild.classList.add(classNames.checkboxLeft);
|
|
873
|
-
args.item.firstElementChild.insertBefore(checkboxElement, args.item.firstElementChild.childNodes[0]);
|
|
874
|
-
} else {
|
|
875
|
-
checkboxElement.classList.add(classNames.checkboxRight);
|
|
876
|
-
args.item.firstElementChild.classList.add(classNames.checkboxRight);
|
|
877
|
-
args.item.firstElementChild.appendChild(checkboxElement);
|
|
878
|
-
}
|
|
879
|
-
this.currentLiElements.push(args.item);
|
|
880
|
-
if (this.checkBoxPosition === 'Left') {
|
|
881
|
-
this.virtualCheckBox = args.item.firstElementChild.children[0];
|
|
882
|
-
}
|
|
883
|
-
else {
|
|
884
|
-
this.virtualCheckBox = args.item.firstElementChild.lastElementChild;
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
private checkInternally(args: ItemCreatedArgs, checkboxElement: Element): void {
|
|
890
|
-
args.item.classList.add(classNames.selected);
|
|
891
|
-
checkboxElement.querySelector('.' + classNames.checkboxIcon).classList.add(classNames.checked);
|
|
892
|
-
checkboxElement.setAttribute('aria-checked', 'true');
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
/**
|
|
896
|
-
* Checks the specific list item by passing the unchecked fields as an argument to this method.
|
|
897
|
-
*
|
|
898
|
-
* @param {Fields | HTMLElement | Element} item - It accepts Fields or HTML list element as an argument.
|
|
899
|
-
*/
|
|
900
|
-
|
|
901
|
-
public checkItem(item: Fields | HTMLElement | Element): void {
|
|
902
|
-
this.toggleCheckBase(item, true);
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
private toggleCheckBase(item: Fields | Element | HTMLElement, checked: boolean): void {
|
|
906
|
-
if (this.showCheckBox) {
|
|
907
|
-
let liElement: Element = item as Element;
|
|
908
|
-
if (item instanceof Object && (item as Object).constructor !== HTMLLIElement) {
|
|
909
|
-
liElement = this.getLiFromObjOrElement(item);
|
|
910
|
-
}
|
|
911
|
-
if (!isNullOrUndefined(liElement)) {
|
|
912
|
-
const checkboxIcon: Element = liElement.querySelector('.' + classNames.checkboxIcon);
|
|
913
|
-
if (checked === true) {
|
|
914
|
-
liElement.classList.add(classNames.selected);
|
|
915
|
-
}
|
|
916
|
-
else {
|
|
917
|
-
liElement.classList.remove(classNames.selected);
|
|
918
|
-
}
|
|
919
|
-
if (checked === true) {
|
|
920
|
-
checkboxIcon.classList.add(classNames.checked);
|
|
921
|
-
}
|
|
922
|
-
else {
|
|
923
|
-
checkboxIcon.classList.remove(classNames.checked);
|
|
924
|
-
}
|
|
925
|
-
checkboxIcon.parentElement.setAttribute('aria-checked', checked ? 'true' : 'false');
|
|
926
|
-
}
|
|
927
|
-
this.setSelectedItemData(liElement);
|
|
928
|
-
this.updateSelectedId();
|
|
929
|
-
}
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
/**
|
|
933
|
-
* Uncheck the specific list item by passing the checked fields as an argument to this method.
|
|
934
|
-
*
|
|
935
|
-
* @param {Fields | HTMLElement | Element} item - It accepts Fields or HTML list element as an argument.
|
|
936
|
-
*/
|
|
937
|
-
|
|
938
|
-
public uncheckItem(item: Fields | HTMLElement | Element): void {
|
|
939
|
-
this.toggleCheckBase(item, false);
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
/**
|
|
943
|
-
* Checks all the unchecked items in the ListView.
|
|
944
|
-
*/
|
|
945
|
-
|
|
946
|
-
public checkAllItems(): void {
|
|
947
|
-
this.toggleAllCheckBase(true);
|
|
948
|
-
}
|
|
949
|
-
|
|
950
|
-
/**
|
|
951
|
-
* Uncheck all the checked items in ListView.
|
|
952
|
-
*/
|
|
953
|
-
|
|
954
|
-
public uncheckAllItems(): void {
|
|
955
|
-
this.toggleAllCheckBase(false);
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
private toggleAllCheckBase(checked: boolean): void {
|
|
959
|
-
if (this.showCheckBox) {
|
|
960
|
-
for (let i: number = 0; i < this.liCollection.length; i++) {
|
|
961
|
-
const checkIcon: Element = this.liCollection[i as number].querySelector('.' + classNames.checkboxIcon);
|
|
962
|
-
if (checkIcon) {
|
|
963
|
-
if (checked) {
|
|
964
|
-
if (!checkIcon.classList.contains(classNames.checked)) {
|
|
965
|
-
this.checkItem(this.liCollection[i as number]);
|
|
966
|
-
}
|
|
967
|
-
} else {
|
|
968
|
-
if (checkIcon.classList.contains(classNames.checked)) {
|
|
969
|
-
this.uncheckItem(this.liCollection[i as number]);
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
if (this.enableVirtualization) {
|
|
975
|
-
this.virtualizationModule.checkedItem(checked);
|
|
976
|
-
}
|
|
977
|
-
this.updateSelectedId();
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
private setCheckbox(): void {
|
|
982
|
-
if (this.showCheckBox) {
|
|
983
|
-
const liCollection: HTMLElement[] = Array.prototype.slice.call(this.element.querySelectorAll('.' + classNames.listItem));
|
|
984
|
-
const args: ItemCreatedArgs = {
|
|
985
|
-
item: undefined, curData: undefined, dataSource: undefined, fields: undefined,
|
|
986
|
-
options: undefined, text: ''
|
|
987
|
-
};
|
|
988
|
-
for (let i: number = 0; i < liCollection.length; i++) {
|
|
989
|
-
const element: HTMLElement = liCollection[i as number];
|
|
990
|
-
args.item = element;
|
|
991
|
-
args.curData = this.getItemData(element) as { [key: string]: Object };
|
|
992
|
-
if (element.querySelector('.' + classNames.checkboxWrapper)) {
|
|
993
|
-
this.removeElement(element.querySelector('.' + classNames.checkboxWrapper));
|
|
994
|
-
}
|
|
995
|
-
this.renderCheckbox(args);
|
|
996
|
-
if (args.item.classList.contains(classNames.selected)) {
|
|
997
|
-
this.checkInternally(args, args.item.querySelector('.' + classNames.checkboxWrapper));
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
} else {
|
|
1001
|
-
const liCollection: HTMLElement[] = Array.prototype.slice.call(this.element.querySelectorAll('.' + classNames.itemCheckList));
|
|
1002
|
-
for (let i: number = 0; i < liCollection.length; i++) {
|
|
1003
|
-
const element: HTMLElement = liCollection[i as number];
|
|
1004
|
-
element.classList.remove(classNames.selected);
|
|
1005
|
-
element.firstElementChild.classList.remove(classNames.checkbox);
|
|
1006
|
-
this.removeElement(element.querySelector('.' + classNames.checkboxWrapper));
|
|
1007
|
-
}
|
|
1008
|
-
if (this.selectedItems) {
|
|
1009
|
-
this.selectedItems.item.classList.add(classNames.selected);
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
/**
|
|
1015
|
-
* Refresh the height of the list item only on enabling the virtualization property.
|
|
1016
|
-
*/
|
|
1017
|
-
|
|
1018
|
-
public refreshItemHeight(): void {
|
|
1019
|
-
if (this.virtualizationModule) {
|
|
1020
|
-
this.virtualizationModule.refreshItemHeight();
|
|
1021
|
-
}
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
private handleCheckboxState(
|
|
1025
|
-
li: Element, checkIcon: Element, checkboxElement: Element,
|
|
1026
|
-
isCheckedBefore: boolean, isFocusedBefore: boolean, eventArgs: Object,
|
|
1027
|
-
isSetCheckboxLI: boolean, textAreaFocus?: HTMLTextAreaElement | HTMLInputElement
|
|
1028
|
-
): void {
|
|
1029
|
-
this.trigger('select', eventArgs, (observedArgs: SelectEventArgs) => {
|
|
1030
|
-
if (observedArgs.cancel) {
|
|
1031
|
-
if (isSetCheckboxLI ? isCheckedBefore : !isCheckedBefore) {
|
|
1032
|
-
checkIcon.classList.add(classNames.checked);
|
|
1033
|
-
li.classList.add(classNames.selected);
|
|
1034
|
-
} else {
|
|
1035
|
-
checkIcon.classList.remove(classNames.checked);
|
|
1036
|
-
li.classList.remove(classNames.selected);
|
|
1037
|
-
}
|
|
1038
|
-
checkboxElement.setAttribute('aria-checked', isSetCheckboxLI ? (isCheckedBefore ? 'true' : 'false') : (isCheckedBefore ? 'false' : 'true'));
|
|
1039
|
-
merge(eventArgs, { isChecked: checkIcon.classList.contains(classNames.checked) });
|
|
1040
|
-
if (isFocusedBefore) {
|
|
1041
|
-
li.classList.remove(classNames.focused);
|
|
1042
|
-
if (textAreaFocus) {
|
|
1043
|
-
textAreaFocus.classList.remove('e-focused');
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
});
|
|
1048
|
-
}
|
|
1049
|
-
|
|
1050
|
-
targetElement: Element;
|
|
1051
|
-
private clickHandler(e: MouseEvent): void {
|
|
1052
|
-
if (Array.isArray(this.dataSource) && this.dataSource.length === 0){
|
|
1053
|
-
return;
|
|
1054
|
-
}
|
|
1055
|
-
const target: Element = <Element>e.target;
|
|
1056
|
-
this.targetElement = target;
|
|
1057
|
-
const classList: DOMTokenList = target.classList;
|
|
1058
|
-
let closestElement: HTMLElement;
|
|
1059
|
-
if (classList.contains(classNames.backIcon) || classList.contains(classNames.headerText)) {
|
|
1060
|
-
if (this.showCheckBox && this.curDSLevel[this.curDSLevel.length - 1]) {
|
|
1061
|
-
this.uncheckAllItems();
|
|
1062
|
-
}
|
|
1063
|
-
this.back();
|
|
1064
|
-
} else {
|
|
1065
|
-
let li: HTMLElement = <HTMLElement>closest(target.parentNode, '.' + classNames.listItem);
|
|
1066
|
-
if (li === null) { li = <HTMLElement>target; }
|
|
1067
|
-
this.removeFocus();
|
|
1068
|
-
if (this.enable && this.showCheckBox && this.isValidLI(li)) {
|
|
1069
|
-
if ((e.target as HTMLElement).classList.contains(classNames.checkboxIcon)) {
|
|
1070
|
-
li.classList.add(classNames.focused);
|
|
1071
|
-
if (isNullOrUndefined(li.querySelector('.' + classNames.checked))) {
|
|
1072
|
-
const args: ItemCreatedArgs = {
|
|
1073
|
-
curData: undefined, dataSource: undefined, fields: undefined, options: undefined,
|
|
1074
|
-
text: undefined, item: li
|
|
1075
|
-
};
|
|
1076
|
-
this.checkInternally(args, args.item.querySelector('.' + classNames.checkboxWrapper));
|
|
1077
|
-
} else {
|
|
1078
|
-
this.uncheckItem(li);
|
|
1079
|
-
li.classList.add(classNames.focused);
|
|
1080
|
-
}
|
|
1081
|
-
if (this.enableVirtualization) {
|
|
1082
|
-
this.virtualizationModule.setCheckboxLI(li, e);
|
|
1083
|
-
}
|
|
1084
|
-
if (e) {
|
|
1085
|
-
const eventArgs: Object = this.selectEventData(li, e);
|
|
1086
|
-
const checkIcon: Element = li.querySelector('.' + classNames.checkboxIcon);
|
|
1087
|
-
merge(eventArgs, { isChecked: checkIcon.classList.contains(classNames.checked) });
|
|
1088
|
-
const checkboxElement: Element = li.querySelector('.' + classNames.checkboxWrapper);
|
|
1089
|
-
const isCheckedBefore: boolean = checkIcon.classList.contains(classNames.checked);
|
|
1090
|
-
const isFocusedBefore: boolean = li.classList.contains(classNames.focused);
|
|
1091
|
-
this.handleCheckboxState(li, checkIcon, checkboxElement, isCheckedBefore, isFocusedBefore, eventArgs, false);
|
|
1092
|
-
}
|
|
1093
|
-
} else if (li.classList.contains(classNames.hasChild)) {
|
|
1094
|
-
this.removeHover();
|
|
1095
|
-
this.removeSelect();
|
|
1096
|
-
this.removeSelect(li);
|
|
1097
|
-
this.setSelectLI(li, e);
|
|
1098
|
-
li.classList.remove(classNames.selected);
|
|
1099
|
-
} else {
|
|
1100
|
-
this.setCheckboxLI(li, e);
|
|
1101
|
-
if ((target.nodeName === 'INPUT') || (target.nodeName === 'TEXTAREA')) {
|
|
1102
|
-
target.classList.add('e-focused');
|
|
1103
|
-
this.targetElement = target;
|
|
1104
|
-
}
|
|
1105
|
-
}
|
|
1106
|
-
} else {
|
|
1107
|
-
this.setSelectLI(li, e);
|
|
1108
|
-
if ((target.nodeName === 'INPUT') || (target.nodeName === 'TEXTAREA')) {
|
|
1109
|
-
target.classList.add('e-focused');
|
|
1110
|
-
this.targetElement = target;
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
1113
|
-
closestElement = closest((e.target as HTMLElement), 'li') as HTMLElement;
|
|
1114
|
-
if (!isNullOrUndefined(closestElement)) {
|
|
1115
|
-
if (closestElement.classList.contains('e-has-child') &&
|
|
1116
|
-
!(e.target as HTMLElement).parentElement.classList.contains('e-listview-checkbox')) {
|
|
1117
|
-
closestElement.classList.add(classNames.disable);
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
1121
|
-
this.updateSelectedId();
|
|
1122
|
-
}
|
|
1123
|
-
|
|
1124
|
-
private removeElement(element: HTMLElement | Element): HTMLElement | Element {
|
|
1125
|
-
return element && element.parentNode && element.parentNode.removeChild(element);
|
|
1126
|
-
}
|
|
1127
|
-
|
|
1128
|
-
private hoverHandler(e: MouseEvent): void {
|
|
1129
|
-
const curLi: HTMLElement = <HTMLElement>closest((<Element>e.target).parentNode, '.' + classNames.listItem);
|
|
1130
|
-
this.setHoverLI(curLi);
|
|
1131
|
-
}
|
|
1132
|
-
|
|
1133
|
-
private leaveHandler(): void {
|
|
1134
|
-
this.removeHover();
|
|
1135
|
-
}
|
|
1136
|
-
private homeKeyHandler(e: KeyboardEventArgs, end?: boolean): void {
|
|
1137
|
-
e.preventDefault();
|
|
1138
|
-
if (Object.keys(this.dataSource).length && this.curUL) {
|
|
1139
|
-
const li: Element[] = <NodeListOf<Element> & Element[]>this.curUL.querySelectorAll('.' + classNames.listItem);
|
|
1140
|
-
const focusedElement: Element = this.curUL.querySelector('.' + classNames.focused) ||
|
|
1141
|
-
this.curUL.querySelector('.' + classNames.selected);
|
|
1142
|
-
if (focusedElement) {
|
|
1143
|
-
focusedElement.classList.remove(classNames.focused);
|
|
1144
|
-
if (!this.showCheckBox) {
|
|
1145
|
-
focusedElement.classList.remove(classNames.selected);
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
const index: number = !end ? 0 : li.length - 1;
|
|
1149
|
-
if (li[index as number].classList.contains(classNames.hasChild) || this.showCheckBox) {
|
|
1150
|
-
li[index as number].classList.add(classNames.focused);
|
|
1151
|
-
} else {
|
|
1152
|
-
this.setSelectLI(li[index as number], e);
|
|
1153
|
-
}
|
|
1154
|
-
if (li[index as number]) {
|
|
1155
|
-
this.element.setAttribute('aria-activedescendant', (<HTMLElement>li[index as number]).id.toString());
|
|
1156
|
-
} else {
|
|
1157
|
-
this.element.removeAttribute('aria-activedescendant');
|
|
1158
|
-
}
|
|
1159
|
-
}
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
|
-
private onArrowKeyDown(e: KeyboardEventArgs, prev: boolean): Element {
|
|
1163
|
-
let siblingLI: Element;
|
|
1164
|
-
let li: Element;
|
|
1165
|
-
const hasChild: boolean = !isNullOrUndefined(this.curUL.querySelector('.' + classNames.hasChild)) ? true : false;
|
|
1166
|
-
if (hasChild || this.showCheckBox) {
|
|
1167
|
-
li = this.curUL.querySelector('.' + classNames.focused) || this.curUL.querySelector('.' + classNames.selected);
|
|
1168
|
-
siblingLI = ListBase.getSiblingLI(this.curUL.querySelectorAll('.' + classNames.listItem), li, prev);
|
|
1169
|
-
if (!isNullOrUndefined(siblingLI)) {
|
|
1170
|
-
if (li) {
|
|
1171
|
-
li.classList.remove(classNames.focused);
|
|
1172
|
-
if (!this.showCheckBox) {
|
|
1173
|
-
li.classList.remove(classNames.selected);
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
if (siblingLI.classList.contains(classNames.hasChild) || this.showCheckBox) {
|
|
1177
|
-
siblingLI.classList.add(classNames.focused);
|
|
1178
|
-
} else {
|
|
1179
|
-
this.setSelectLI(siblingLI, e);
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
} else {
|
|
1183
|
-
li = this.curUL.querySelector('.' + classNames.selected);
|
|
1184
|
-
siblingLI = ListBase.getSiblingLI(this.curUL.querySelectorAll('.' + classNames.listItem), li, prev);
|
|
1185
|
-
this.setSelectLI(siblingLI, e);
|
|
1186
|
-
}
|
|
1187
|
-
if (siblingLI) {
|
|
1188
|
-
this.element.setAttribute('aria-activedescendant', (<HTMLElement>siblingLI).id.toString());
|
|
1189
|
-
} else {
|
|
1190
|
-
this.element.removeAttribute('aria-activedescendant');
|
|
1191
|
-
}
|
|
1192
|
-
return siblingLI;
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
|
-
private arrowKeyHandler(e: KeyboardEventArgs, prev?: boolean): void {
|
|
1196
|
-
e.preventDefault();
|
|
1197
|
-
if (Object.keys(this.dataSource).length && this.curUL) {
|
|
1198
|
-
const siblingLI: Element = this.onArrowKeyDown(e, prev);
|
|
1199
|
-
const elementTop: number = this.element.getBoundingClientRect().top;
|
|
1200
|
-
const elementHeight: number = this.element.getBoundingClientRect().height;
|
|
1201
|
-
const firstItemBounds: ClientRect = this.curUL.querySelector('.' + classNames.listItem).getBoundingClientRect();
|
|
1202
|
-
let heightDiff: number;
|
|
1203
|
-
let groupItemBounds: ClientRect;
|
|
1204
|
-
if (this.fields.groupBy) {
|
|
1205
|
-
groupItemBounds = this.curUL.querySelector('.' + classNames.groupListItem).getBoundingClientRect();
|
|
1206
|
-
}
|
|
1207
|
-
if (siblingLI) {
|
|
1208
|
-
const siblingTop: number = siblingLI.getBoundingClientRect().top;
|
|
1209
|
-
const siblingHeight: number = siblingLI.getBoundingClientRect().height;
|
|
1210
|
-
if (!prev) {
|
|
1211
|
-
const height: number = this.isWindow ? window.innerHeight : elementHeight;
|
|
1212
|
-
heightDiff = this.isWindow ? (siblingTop + siblingHeight) :
|
|
1213
|
-
((siblingTop - elementTop) + siblingHeight);
|
|
1214
|
-
if (heightDiff > height) {
|
|
1215
|
-
if (this.isWindow === true) {
|
|
1216
|
-
window.scroll(0, pageYOffset + (heightDiff - height));
|
|
1217
|
-
}
|
|
1218
|
-
else {
|
|
1219
|
-
this.element.scrollTop = this.element.scrollTop + (heightDiff - height);
|
|
1220
|
-
}
|
|
1221
|
-
}
|
|
1222
|
-
} else {
|
|
1223
|
-
heightDiff = this.isWindow ? siblingTop : (siblingTop - elementTop);
|
|
1224
|
-
if (heightDiff < 0) {
|
|
1225
|
-
if (this.isWindow === true) {
|
|
1226
|
-
window.scroll(0, pageYOffset + heightDiff);
|
|
1227
|
-
}
|
|
1228
|
-
else {
|
|
1229
|
-
this.element.scrollTop = this.element.scrollTop + heightDiff;
|
|
1230
|
-
}
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
} else if (this.enableVirtualization && prev && this.virtualizationModule.uiFirstIndex) {
|
|
1234
|
-
this.onUIScrolled = () => {
|
|
1235
|
-
this.onArrowKeyDown(e, prev);
|
|
1236
|
-
this.onUIScrolled = undefined;
|
|
1237
|
-
};
|
|
1238
|
-
heightDiff = this.virtualizationModule.listItemHeight;
|
|
1239
|
-
if (this.isWindow === true) {
|
|
1240
|
-
window.scroll(0, pageYOffset - heightDiff);
|
|
1241
|
-
}
|
|
1242
|
-
else {
|
|
1243
|
-
this.element.scrollTop = this.element.scrollTop - heightDiff;
|
|
1244
|
-
}
|
|
1245
|
-
} else if (prev) {
|
|
1246
|
-
if (this.showHeader && this.headerEle) {
|
|
1247
|
-
const topHeight: number = groupItemBounds ? groupItemBounds.top : firstItemBounds.top;
|
|
1248
|
-
const headerBounds: ClientRect = this.headerEle.getBoundingClientRect();
|
|
1249
|
-
heightDiff = headerBounds.top < 0 ? (headerBounds.height - topHeight) : 0;
|
|
1250
|
-
if (this.isWindow === true) {
|
|
1251
|
-
window.scroll(0, pageYOffset - heightDiff);
|
|
1252
|
-
}
|
|
1253
|
-
else {
|
|
1254
|
-
this.element.scrollTop = 0;
|
|
1255
|
-
}
|
|
1256
|
-
} else if (this.fields.groupBy) {
|
|
1257
|
-
heightDiff = this.isWindow ? (groupItemBounds.top < 0 ? groupItemBounds.top : 0) :
|
|
1258
|
-
(elementTop - firstItemBounds.top) + groupItemBounds.height;
|
|
1259
|
-
if (this.isWindow === true) {
|
|
1260
|
-
window.scroll(0, pageYOffset + heightDiff);
|
|
1261
|
-
}
|
|
1262
|
-
else {
|
|
1263
|
-
this.element.scrollTop = this.element.scrollTop - heightDiff;
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1267
|
-
}
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
|
-
private enterKeyHandler(e: KeyboardEventArgs): void {
|
|
1271
|
-
if (Object.keys(this.dataSource).length && this.curUL) {
|
|
1272
|
-
const hasChild: boolean = !isNullOrUndefined(this.curUL.querySelector('.' + classNames.hasChild)) ? true : false;
|
|
1273
|
-
const li: Element = this.curUL.querySelector('.' + classNames.focused);
|
|
1274
|
-
if (hasChild && li) {
|
|
1275
|
-
li.classList.remove(classNames.focused);
|
|
1276
|
-
if (this.showCheckBox) {
|
|
1277
|
-
this.removeSelect();
|
|
1278
|
-
this.removeSelect(<HTMLElement>li);
|
|
1279
|
-
this.removeHover();
|
|
1280
|
-
}
|
|
1281
|
-
this.setSelectLI(li, e);
|
|
1282
|
-
}
|
|
1283
|
-
}
|
|
1284
|
-
}
|
|
1285
|
-
private spaceKeyHandler(e: KeyboardEventArgs): void {
|
|
1286
|
-
if (this.enable && this.showCheckBox && Object.keys(this.dataSource).length && this.curUL) {
|
|
1287
|
-
e.preventDefault();
|
|
1288
|
-
const li: Element = this.curUL.querySelector('.' + classNames.focused);
|
|
1289
|
-
let checkboxElement: Element;
|
|
1290
|
-
let checkIcon: Element;
|
|
1291
|
-
if (!isNullOrUndefined(li) && isNullOrUndefined(li.querySelector('.' + classNames.checked))) {
|
|
1292
|
-
const args: ItemCreatedArgs = {
|
|
1293
|
-
curData: undefined, dataSource: undefined, fields: undefined, options: undefined,
|
|
1294
|
-
text: undefined, item: <HTMLElement>li
|
|
1295
|
-
};
|
|
1296
|
-
checkboxElement = args.item.querySelector('.' + classNames.checkboxWrapper);
|
|
1297
|
-
this.checkInternally(args, checkboxElement);
|
|
1298
|
-
checkIcon = checkboxElement.querySelector('.' + classNames.checkboxIcon + '.' + classNames.icon);
|
|
1299
|
-
} else {
|
|
1300
|
-
this.uncheckItem(li);
|
|
1301
|
-
}
|
|
1302
|
-
const eventArgs: object = this.selectEventData(li, e);
|
|
1303
|
-
merge(eventArgs, { isChecked: checkIcon ? checkIcon.classList.contains(classNames.checked) : false });
|
|
1304
|
-
if (!isNullOrUndefined(li)) {
|
|
1305
|
-
const cbElement: Element = li.querySelector('.' + classNames.checkboxWrapper);
|
|
1306
|
-
const checkboxIcon: Element = li.querySelector('.' + classNames.checkboxIcon);
|
|
1307
|
-
const isCheckedBefore: boolean = checkboxIcon.classList.contains(classNames.checked);
|
|
1308
|
-
const isFocusedBefore: boolean = li.classList.contains(classNames.focused);
|
|
1309
|
-
this.handleCheckboxState(li, checkboxIcon, cbElement, isCheckedBefore, isFocusedBefore, eventArgs, false);
|
|
1310
|
-
}
|
|
1311
|
-
this.updateSelectedId();
|
|
1312
|
-
}
|
|
1313
|
-
}
|
|
1314
|
-
|
|
1315
|
-
private keyActionHandler(e: KeyboardEventArgs): void {
|
|
1316
|
-
switch (e.keyCode) {
|
|
1317
|
-
case 36:
|
|
1318
|
-
this.homeKeyHandler(e);
|
|
1319
|
-
break;
|
|
1320
|
-
case 35:
|
|
1321
|
-
this.homeKeyHandler(e, true);
|
|
1322
|
-
break;
|
|
1323
|
-
case 40:
|
|
1324
|
-
this.arrowKeyHandler(e);
|
|
1325
|
-
break;
|
|
1326
|
-
case 38:
|
|
1327
|
-
this.arrowKeyHandler(e, true);
|
|
1328
|
-
break;
|
|
1329
|
-
case 13:
|
|
1330
|
-
this.enterKeyHandler(e);
|
|
1331
|
-
break;
|
|
1332
|
-
case 8:
|
|
1333
|
-
if (this.showCheckBox && this.curDSLevel[this.curDSLevel.length - 1]) {
|
|
1334
|
-
this.uncheckAllItems();
|
|
1335
|
-
}
|
|
1336
|
-
this.back();
|
|
1337
|
-
break;
|
|
1338
|
-
case 32:
|
|
1339
|
-
if (isNullOrUndefined(this.targetElement) || !(this.targetElement.classList.contains('e-focused'))) {
|
|
1340
|
-
this.spaceKeyHandler(e);
|
|
1341
|
-
}
|
|
1342
|
-
break;
|
|
1343
|
-
}
|
|
1344
|
-
}
|
|
1345
|
-
|
|
1346
|
-
private swipeActionHandler(e: SwipeEventArgs): void {
|
|
1347
|
-
if (e.swipeDirection === 'Right' && e.velocity > swipeVelocity && e.originalEvent.type === 'touchend') {
|
|
1348
|
-
if (this.showCheckBox && this.curDSLevel[this.curDSLevel.length - 1]) {
|
|
1349
|
-
this.uncheckAllItems();
|
|
1350
|
-
}
|
|
1351
|
-
this.back();
|
|
1352
|
-
}
|
|
1353
|
-
}
|
|
1354
|
-
|
|
1355
|
-
private focusout(): void {
|
|
1356
|
-
if (Object.keys(this.dataSource).length && this.curUL) {
|
|
1357
|
-
const focusedElement: Element = this.curUL.querySelector('.' + classNames.focused);
|
|
1358
|
-
if (focusedElement) {
|
|
1359
|
-
focusedElement.classList.remove(classNames.focused);
|
|
1360
|
-
if (!this.showCheckBox && !isNullOrUndefined(this.selectedLI)) {
|
|
1361
|
-
this.selectedLI.classList.add(classNames.selected);
|
|
1362
|
-
}
|
|
1363
|
-
}
|
|
1364
|
-
}
|
|
1365
|
-
}
|
|
1366
|
-
|
|
1367
|
-
private wireEvents(): void {
|
|
1368
|
-
EventHandler.add(this.element, 'keydown', this.keyActionHandler, this);
|
|
1369
|
-
EventHandler.add(this.element, 'click', this.clickHandler, this);
|
|
1370
|
-
EventHandler.add(this.element, 'mouseover', this.hoverHandler, this);
|
|
1371
|
-
EventHandler.add(this.element, 'mouseout', this.leaveHandler, this);
|
|
1372
|
-
EventHandler.add(this.element, 'focusout', this.focusout, this);
|
|
1373
|
-
this.touchModule = new Touch(this.element, { swipe: this.swipeActionHandler.bind(this) });
|
|
1374
|
-
if (!isNullOrUndefined(this.scroll)) {
|
|
1375
|
-
EventHandler.add(this.element, 'scroll', this.onListScroll, this);
|
|
1376
|
-
}
|
|
1377
|
-
}
|
|
1378
|
-
|
|
1379
|
-
private unWireEvents(): void {
|
|
1380
|
-
EventHandler.remove(this.element, 'keydown', this.keyActionHandler);
|
|
1381
|
-
EventHandler.remove(this.element, 'click', this.clickHandler);
|
|
1382
|
-
EventHandler.remove(this.element, 'mouseover', this.hoverHandler);
|
|
1383
|
-
EventHandler.remove(this.element, 'mouseout', this.leaveHandler);
|
|
1384
|
-
EventHandler.remove(this.element, 'mouseover', this.hoverHandler);
|
|
1385
|
-
EventHandler.remove(this.element, 'mouseout', this.leaveHandler);
|
|
1386
|
-
EventHandler.remove(this.element, 'focusout', this.focusout);
|
|
1387
|
-
if (!isNullOrUndefined(this.scroll)) {
|
|
1388
|
-
EventHandler.remove(this.element, 'scroll', this.onListScroll);
|
|
1389
|
-
}
|
|
1390
|
-
if (this.touchModule) { this.touchModule.destroy(); }
|
|
1391
|
-
this.touchModule = null;
|
|
1392
|
-
}
|
|
1393
|
-
|
|
1394
|
-
private removeFocus(): void {
|
|
1395
|
-
const focusedLI: Element[] = <NodeListOf<Element> & Element[]>this.element.querySelectorAll('.' + classNames.focused);
|
|
1396
|
-
for (const ele of focusedLI) {
|
|
1397
|
-
ele.classList.remove(classNames.focused);
|
|
1398
|
-
}
|
|
1399
|
-
}
|
|
1400
|
-
|
|
1401
|
-
private removeHover(): void {
|
|
1402
|
-
const hoverLI: Element = this.element.querySelector('.' + classNames.hover);
|
|
1403
|
-
if (hoverLI) { hoverLI.classList.remove(classNames.hover); }
|
|
1404
|
-
}
|
|
1405
|
-
|
|
1406
|
-
private removeSelect(li?: HTMLElement): void {
|
|
1407
|
-
if (isNullOrUndefined(li)) {
|
|
1408
|
-
const selectedLI: Element[] = <NodeListOf<Element> & Element[]>this.element.querySelectorAll('.' + classNames.selected);
|
|
1409
|
-
for (const ele of selectedLI) {
|
|
1410
|
-
if (this.showCheckBox && ele.querySelector('.' + classNames.checked)) {
|
|
1411
|
-
continue;
|
|
1412
|
-
} else {
|
|
1413
|
-
ele.classList.remove(classNames.selected);
|
|
1414
|
-
}
|
|
1415
|
-
}
|
|
1416
|
-
} else {
|
|
1417
|
-
li.classList.remove(classNames.selected);
|
|
1418
|
-
}
|
|
1419
|
-
}
|
|
1420
|
-
|
|
1421
|
-
private isValidLI(li: Element | HTMLElement): boolean {
|
|
1422
|
-
return (li && li.classList.contains(classNames.listItem)
|
|
1423
|
-
&& !li.classList.contains(classNames.groupListItem)
|
|
1424
|
-
&& !li.classList.contains(classNames.disable));
|
|
1425
|
-
}
|
|
1426
|
-
|
|
1427
|
-
private setCheckboxLI(li: Element, e?: MouseEvent | KeyboardEvent | FocusEvent): void {
|
|
1428
|
-
if (this.isValidLI(li) && this.enable && this.showCheckBox) {
|
|
1429
|
-
if (this.curUL.querySelector('.' + classNames.focused)) {
|
|
1430
|
-
this.curUL.querySelector('.' + classNames.focused).classList.remove(classNames.focused);
|
|
1431
|
-
}
|
|
1432
|
-
const textAreaFocus: HTMLTextAreaElement | HTMLInputElement = li.querySelector('textarea') || li.querySelector('input');
|
|
1433
|
-
li.classList.add(classNames.focused);
|
|
1434
|
-
if (!isNullOrUndefined(e)){
|
|
1435
|
-
if (e.target === textAreaFocus){
|
|
1436
|
-
textAreaFocus.classList.add('e-focused');
|
|
1437
|
-
}
|
|
1438
|
-
}
|
|
1439
|
-
const checkboxElement: Element = li.querySelector('.' + classNames.checkboxWrapper);
|
|
1440
|
-
const checkIcon: Element = checkboxElement.querySelector('.' + classNames.checkboxIcon + '.' + classNames.icon);
|
|
1441
|
-
this.removeHover();
|
|
1442
|
-
const isCheckedBefore: boolean = checkIcon.classList.contains(classNames.checked);
|
|
1443
|
-
const isFocusedBefore: boolean = li.classList.contains(classNames.focused);
|
|
1444
|
-
if (!isCheckedBefore) {
|
|
1445
|
-
checkIcon.classList.add(classNames.checked);
|
|
1446
|
-
li.classList.add(classNames.selected);
|
|
1447
|
-
} else {
|
|
1448
|
-
checkIcon.classList.remove(classNames.checked);
|
|
1449
|
-
li.classList.remove(classNames.selected);
|
|
1450
|
-
}
|
|
1451
|
-
checkboxElement.setAttribute('aria-checked', checkIcon.classList.contains(classNames.checked) ?
|
|
1452
|
-
'true' : 'false');
|
|
1453
|
-
const eventArgs: object = this.selectEventData(li, e);
|
|
1454
|
-
merge(eventArgs, { isChecked: checkIcon.classList.contains(classNames.checked) });
|
|
1455
|
-
if (this.enableVirtualization) {
|
|
1456
|
-
this.virtualizationModule.setCheckboxLI(li, e);
|
|
1457
|
-
}
|
|
1458
|
-
this.handleCheckboxState(li, checkIcon, checkboxElement, isCheckedBefore, isFocusedBefore, eventArgs, true, textAreaFocus);
|
|
1459
|
-
this.setSelectedItemData(li);
|
|
1460
|
-
this.renderSubList(li);
|
|
1461
|
-
}
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
private selectEventData(li: Element, e?: MouseEvent | KeyboardEvent | FocusEvent): Object {
|
|
1465
|
-
const data: DataSource = this.getItemData(li);
|
|
1466
|
-
const fieldData: DataSource = getFieldValues(data as { [key: string]: Object }, this.listBaseOption.fields) as DataSource;
|
|
1467
|
-
let selectedItem: SelectedItem;
|
|
1468
|
-
if (!isNullOrUndefined(data)
|
|
1469
|
-
&& typeof (this.dataSource as string[])[0] === 'string' || typeof (this.dataSource as number[])[0] === 'number') {
|
|
1470
|
-
selectedItem = { item: li, text: li && (li as HTMLElement).innerText.trim(), data: this.dataSource as string[] | number[] };
|
|
1471
|
-
} else {
|
|
1472
|
-
selectedItem =
|
|
1473
|
-
{
|
|
1474
|
-
item: li, text: fieldData && fieldData[this.listBaseOption.fields.text] as unknown as string,
|
|
1475
|
-
data: data as { [key: string]: Object } as any
|
|
1476
|
-
};
|
|
1477
|
-
}
|
|
1478
|
-
const eventArgs: object = {};
|
|
1479
|
-
merge(eventArgs, selectedItem);
|
|
1480
|
-
if (e) {
|
|
1481
|
-
merge(
|
|
1482
|
-
eventArgs,
|
|
1483
|
-
{
|
|
1484
|
-
isInteracted: true,
|
|
1485
|
-
event: e,
|
|
1486
|
-
cancel: false,
|
|
1487
|
-
index: this.curUL && Array.prototype.indexOf.call(this.curUL.children, li)
|
|
1488
|
-
}
|
|
1489
|
-
);
|
|
1490
|
-
}
|
|
1491
|
-
return eventArgs;
|
|
1492
|
-
}
|
|
1493
|
-
|
|
1494
|
-
private setSelectedItemData(li: Element): void {
|
|
1495
|
-
const data: DataSource = this.getItemData(li);
|
|
1496
|
-
const fieldData: DataSource = <DataSource>getFieldValues(data as { [key: string]: Object }, this.listBaseOption.fields);
|
|
1497
|
-
if (!isNullOrUndefined(data) && ((typeof (this.dataSource as string[])[0] === 'string') ||
|
|
1498
|
-
(typeof (this.dataSource as number[])[0] === 'number'))) {
|
|
1499
|
-
this.selectedItems = {
|
|
1500
|
-
item: li,
|
|
1501
|
-
text: li && (li as HTMLElement).innerText.trim(),
|
|
1502
|
-
data: this.dataSource as string[]
|
|
1503
|
-
};
|
|
1504
|
-
} else {
|
|
1505
|
-
this.selectedItems = {
|
|
1506
|
-
item: li,
|
|
1507
|
-
text: fieldData && fieldData[this.listBaseOption.fields.text] as FieldsMapping as string,
|
|
1508
|
-
data: data as { [key: string]: Object }
|
|
1509
|
-
};
|
|
1510
|
-
}
|
|
1511
|
-
}
|
|
1512
|
-
|
|
1513
|
-
private setSelectLI(li: Element, e?: MouseEvent | KeyboardEvent | FocusEvent): void {
|
|
1514
|
-
if (this.isValidLI(li) && !li.classList.contains(classNames.selected) && this.enable) {
|
|
1515
|
-
if (!this.showCheckBox) {
|
|
1516
|
-
this.removeSelect();
|
|
1517
|
-
}
|
|
1518
|
-
li.classList.add(classNames.selected);
|
|
1519
|
-
this.removeHover();
|
|
1520
|
-
this.setSelectedItemData(li);
|
|
1521
|
-
if (this.enableVirtualization) {
|
|
1522
|
-
this.virtualizationModule.setSelectLI(li, e);
|
|
1523
|
-
}
|
|
1524
|
-
const eventArgs: object = this.selectEventData(li, e);
|
|
1525
|
-
this.trigger('select', eventArgs, (observedArgs: SelectEventArgs) => {
|
|
1526
|
-
if (!observedArgs.cancel) {
|
|
1527
|
-
this.selectedLI = li;
|
|
1528
|
-
this.renderSubList(li);
|
|
1529
|
-
}
|
|
1530
|
-
else {
|
|
1531
|
-
li.classList.remove(classNames.selected);
|
|
1532
|
-
this.selectedLI = li;
|
|
1533
|
-
}
|
|
1534
|
-
});
|
|
1535
|
-
}
|
|
1536
|
-
}
|
|
1537
|
-
|
|
1538
|
-
private setHoverLI(li: Element): void {
|
|
1539
|
-
if (this.isValidLI(li) && !li.classList.contains(classNames.hover) && this.enable) {
|
|
1540
|
-
const lastLi: Element[] = <NodeListOf<Element> & Element[]>this.element.querySelectorAll('.' + classNames.hover);
|
|
1541
|
-
if (lastLi && lastLi.length) { removeClass(lastLi, classNames.hover); }
|
|
1542
|
-
if (!(li as Element).classList.contains(classNames.selected) || this.showCheckBox) {
|
|
1543
|
-
(li as Element).classList.add(classNames.hover);
|
|
1544
|
-
}
|
|
1545
|
-
}
|
|
1546
|
-
}
|
|
1547
|
-
|
|
1548
|
-
//Data Source Related Functions
|
|
1549
|
-
private getSubDS(): DataSource[] {
|
|
1550
|
-
const levelKeys: string[] = this.curDSLevel;
|
|
1551
|
-
if (levelKeys.length) {
|
|
1552
|
-
let ds: DataSource[] = <DataSource[]>this.localData;
|
|
1553
|
-
for (const key of levelKeys) {
|
|
1554
|
-
const field: DataSource = {};
|
|
1555
|
-
field[this.fields.id] = key as FieldSettingsModel;
|
|
1556
|
-
this.curDSJSON = <DataSource[] & DataSource>this.findItemFromDS(ds, field);
|
|
1557
|
-
const fieldData: DataSource =
|
|
1558
|
-
<DataSource>getFieldValues(this.curDSJSON as { [key: string]: Object }, this.listBaseOption.fields);
|
|
1559
|
-
ds = this.curDSJSON ? <DataSource[] & DataSource>fieldData[this.fields.child] : ds;
|
|
1560
|
-
}
|
|
1561
|
-
return ds;
|
|
1562
|
-
}
|
|
1563
|
-
return <DataSource[]>this.localData;
|
|
1564
|
-
}
|
|
1565
|
-
|
|
1566
|
-
private getItemData(li: Element | HTMLElement | Fields): DataSource {
|
|
1567
|
-
const dataSource: DataSource[] | string[] | number[] | DataManager = this.dataSource instanceof DataManager ?
|
|
1568
|
-
this.localData : this.dataSource;
|
|
1569
|
-
const fields: Fields = this.getElementUID(li);
|
|
1570
|
-
let curDS: DataSource[];
|
|
1571
|
-
if (isNullOrUndefined(this.element.querySelector('.' + classNames.hasChild)) && this.fields.groupBy) {
|
|
1572
|
-
curDS = <DataSource[]>this.curViewDS;
|
|
1573
|
-
} else {
|
|
1574
|
-
curDS = <DataSource[]>dataSource;
|
|
1575
|
-
}
|
|
1576
|
-
|
|
1577
|
-
return <DataSource>this.findItemFromDS(curDS, <DataSource>fields);
|
|
1578
|
-
}
|
|
1579
|
-
|
|
1580
|
-
private findItemFromDS(
|
|
1581
|
-
dataSource: DataSource[],
|
|
1582
|
-
fields: DataSource,
|
|
1583
|
-
parent?: boolean): DataSource[] | DataSource {
|
|
1584
|
-
|
|
1585
|
-
let resultJSON: DataSource[] | DataSource;
|
|
1586
|
-
|
|
1587
|
-
if (dataSource && dataSource.length && fields) {
|
|
1588
|
-
dataSource.some((data: DataSource) => {
|
|
1589
|
-
const fieldData: DataSource =
|
|
1590
|
-
<DataSource>getFieldValues(data as { [key: string]: Object }, this.listBaseOption.fields);
|
|
1591
|
-
//(!(fid) || id === fid) && (!(ftext) || text === ftext) && (!!fid || !!ftext)
|
|
1592
|
-
if ((fields[this.fields.id] || fields[this.fields.text]) &&
|
|
1593
|
-
(!fields[this.fields.id] || (!isNullOrUndefined(fieldData[this.fields.id]) &&
|
|
1594
|
-
fieldData[this.fields.id].toString()) === fields[this.fields.id].toString()) &&
|
|
1595
|
-
(!fields[this.fields.text] || fieldData[this.fields.text] === fields[this.fields.text])) {
|
|
1596
|
-
resultJSON = (parent ? <DataSource[] | DataSource>dataSource : data);
|
|
1597
|
-
} else if (typeof data !== 'object' && dataSource.indexOf(data) !== -1) {
|
|
1598
|
-
resultJSON = (parent ? <DataSource[] | DataSource>dataSource : data);
|
|
1599
|
-
} else if (!isNullOrUndefined(fields[this.fields.id]) && isNullOrUndefined(fieldData[this.fields.id])) {
|
|
1600
|
-
const li: Element = this.element.querySelector('[data-uid="'
|
|
1601
|
-
+ fields[this.fields.id] + '"]');
|
|
1602
|
-
if (li && (li as HTMLElement).innerText.trim() === fieldData[this.fields.text] as FieldSettingsModel) {
|
|
1603
|
-
resultJSON = data;
|
|
1604
|
-
}
|
|
1605
|
-
} else if (Object.prototype.hasOwnProperty.call(fieldData as object, this.fields.child) &&
|
|
1606
|
-
(fieldData[this.fields.child] as object[]).length) {
|
|
1607
|
-
resultJSON = <DataSource & DataSource[]>this.findItemFromDS(
|
|
1608
|
-
<DataSource[]>fieldData[this.fields.child], fields, parent);
|
|
1609
|
-
}
|
|
1610
|
-
return !!resultJSON;
|
|
1611
|
-
});
|
|
1612
|
-
} else {
|
|
1613
|
-
resultJSON = <DataSource[] & DataSource>dataSource;
|
|
1614
|
-
}
|
|
1615
|
-
|
|
1616
|
-
return <DataSource[] & DataSource>resultJSON;
|
|
1617
|
-
}
|
|
1618
|
-
|
|
1619
|
-
private getQuery(): Query {
|
|
1620
|
-
const columns: string[] = [];
|
|
1621
|
-
const query: Query = (this.query ? this.query : new Query());
|
|
1622
|
-
if (!this.query) {
|
|
1623
|
-
for (const column of Object.keys((this.fields as FieldSettingsModel & { properties: object }).properties)) {
|
|
1624
|
-
if (column !== 'tableName' && !!((this.fields as DataSource)[`${column}`]) &&
|
|
1625
|
-
(this.fields as DataSource)[`${column}`] !==
|
|
1626
|
-
(ListBase.defaultMappedFields as DataSource)[`${column}`]
|
|
1627
|
-
&& columns.indexOf((this.fields as { [key: string]: string })[`${column}`]) === -1) {
|
|
1628
|
-
|
|
1629
|
-
columns.push((this.fields as { [key: string]: string })[`${column}`]);
|
|
1630
|
-
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
query.select(columns);
|
|
1634
|
-
if (Object.prototype.hasOwnProperty.call((this.fields as any & { properties: object }).properties, 'tableName')) {
|
|
1635
|
-
query.from(this.fields.tableName);
|
|
1636
|
-
}
|
|
1637
|
-
}
|
|
1638
|
-
|
|
1639
|
-
return query;
|
|
1640
|
-
}
|
|
1641
|
-
|
|
1642
|
-
private setViewDataSource(dataSource: DataSource[] = <DataSource[]>this.localData): void {
|
|
1643
|
-
const fieldValue: string = (isNullOrUndefined(this.fields.sortBy)) ? this.fields.text : this.fields.sortBy;
|
|
1644
|
-
const query: Query = ListBase.addSorting(this.sortOrder, fieldValue);
|
|
1645
|
-
if (dataSource && this.fields.groupBy) {
|
|
1646
|
-
if (this.sortOrder !== 'None') {
|
|
1647
|
-
this.curViewDS = ListBase.groupDataSource(
|
|
1648
|
-
ListBase.getDataSource(dataSource, query),
|
|
1649
|
-
this.listBaseOption.fields, this.sortOrder);
|
|
1650
|
-
} else {
|
|
1651
|
-
this.curViewDS = ListBase.groupDataSource(dataSource, this.listBaseOption.fields, this.sortOrder);
|
|
1652
|
-
}
|
|
1653
|
-
} else if (dataSource && this.sortOrder !== 'None') {
|
|
1654
|
-
this.curViewDS = ListBase.getDataSource(dataSource, query);
|
|
1655
|
-
} else {
|
|
1656
|
-
this.curViewDS = dataSource;
|
|
1657
|
-
}
|
|
1658
|
-
}
|
|
1659
|
-
|
|
1660
|
-
private isInAnimation(): boolean {
|
|
1661
|
-
return this.curUL.classList.contains('.e-animate');
|
|
1662
|
-
}
|
|
1663
|
-
|
|
1664
|
-
private renderRemoteLists(e: Object, listViewComponent: ListView): void {
|
|
1665
|
-
if (this.isDestroyed) { return; }
|
|
1666
|
-
this.localData = (e as ResultData).result;
|
|
1667
|
-
listViewComponent.removeElement(listViewComponent.contentContainer);
|
|
1668
|
-
this.renderList();
|
|
1669
|
-
this.trigger('actionComplete', e);
|
|
1670
|
-
}
|
|
1671
|
-
|
|
1672
|
-
private triggerActionFailure(e: Object): void {
|
|
1673
|
-
if (this.isDestroyed) { return; }
|
|
1674
|
-
this.trigger('actionFailure', e);
|
|
1675
|
-
}
|
|
1676
|
-
|
|
1677
|
-
private setLocalData(): void {
|
|
1678
|
-
this.trigger('actionBegin');
|
|
1679
|
-
if (this.dataSource instanceof DataManager) {
|
|
1680
|
-
if ((this.dataSource as DataManager).ready) {
|
|
1681
|
-
(this.dataSource as DataManager).ready.then((e: Object) => {
|
|
1682
|
-
this.isOffline = (this.dataSource as DataManager).dataSource.offline;
|
|
1683
|
-
if (this.dataSource instanceof DataManager && this.isOffline) {
|
|
1684
|
-
this.renderRemoteLists(e, this);
|
|
1685
|
-
}
|
|
1686
|
-
}).catch((e: Object) => {
|
|
1687
|
-
this.triggerActionFailure(e);
|
|
1688
|
-
});
|
|
1689
|
-
} else {
|
|
1690
|
-
(this.dataSource as DataManager).executeQuery(this.getQuery()).then((e: object) => {
|
|
1691
|
-
this.renderRemoteLists(e, this);
|
|
1692
|
-
}).catch((e: Object) => {
|
|
1693
|
-
this.triggerActionFailure(e);
|
|
1694
|
-
});
|
|
1695
|
-
}
|
|
1696
|
-
} else if (!this.dataSource || !(<DataSource[]>this.dataSource).length) {
|
|
1697
|
-
const ul: HTMLElement = <HTMLElement>this.element.querySelector('ul');
|
|
1698
|
-
if (ul) {
|
|
1699
|
-
remove(ul);
|
|
1700
|
-
this.setProperties({ dataSource: ListBase.createJsonFromElement(ul) }, true);
|
|
1701
|
-
this.localData = <DataSource[]>this.dataSource;
|
|
1702
|
-
this.renderList();
|
|
1703
|
-
this.trigger('actionComplete', { data: this.localData });
|
|
1704
|
-
}
|
|
1705
|
-
} else {
|
|
1706
|
-
this.localData = <DataSource[]>this.dataSource;
|
|
1707
|
-
this.renderList();
|
|
1708
|
-
this.trigger('actionComplete', { data: this.localData });
|
|
1709
|
-
}
|
|
1710
|
-
}
|
|
1711
|
-
|
|
1712
|
-
private reRender(): void {
|
|
1713
|
-
this.removeElement(this.headerEle);
|
|
1714
|
-
this.removeElement(this.ulElement);
|
|
1715
|
-
this.removeElement(this.contentContainer);
|
|
1716
|
-
if ((this as any).isReact) {
|
|
1717
|
-
this.clearTemplate();
|
|
1718
|
-
}
|
|
1719
|
-
if (Object.keys(window).indexOf('ejsInterop') === -1) {
|
|
1720
|
-
this.element.innerHTML = '';
|
|
1721
|
-
}
|
|
1722
|
-
this.headerEle = this.ulElement = this.liCollection = undefined;
|
|
1723
|
-
this.header();
|
|
1724
|
-
this.setLocalData();
|
|
1725
|
-
}
|
|
1726
|
-
|
|
1727
|
-
private resetCurrentList(): void {
|
|
1728
|
-
this.setViewDataSource(this.curViewDS as DataSource[]);
|
|
1729
|
-
this.contentContainer.innerHTML = '';
|
|
1730
|
-
this.createList();
|
|
1731
|
-
this.renderIntoDom(this.curUL);
|
|
1732
|
-
}
|
|
1733
|
-
|
|
1734
|
-
private setAttributes(liElements: HTMLElement[]): void {
|
|
1735
|
-
for (let i: number = 0; i < liElements.length; i++) {
|
|
1736
|
-
const element: HTMLElement = liElements[parseInt(i.toString(), 10)];
|
|
1737
|
-
if (element.classList.contains('e-list-item')) {
|
|
1738
|
-
element.setAttribute('id', this.element.id + '_' + element.getAttribute('data-uid'));
|
|
1739
|
-
element.setAttribute('tabindex', '-1');
|
|
1740
|
-
}
|
|
1741
|
-
}
|
|
1742
|
-
}
|
|
1743
|
-
|
|
1744
|
-
private createList(): void {
|
|
1745
|
-
this.currentLiElements = [];
|
|
1746
|
-
this.isNestedList = false;
|
|
1747
|
-
this.ulElement = this.curUL = ListBase.createList(
|
|
1748
|
-
this.createElement, this.curViewDS as DataSource[], this.listBaseOption, null, this);
|
|
1749
|
-
this.liCollection = <HTMLElement[] & NodeListOf<Element>>this.curUL.querySelectorAll('.' + classNames.listItem);
|
|
1750
|
-
this.setAttributes(this.liCollection);
|
|
1751
|
-
}
|
|
1752
|
-
|
|
1753
|
-
private renderSubList(li: Element): void {
|
|
1754
|
-
this.liElement = li;
|
|
1755
|
-
const uID: string = li.getAttribute('data-uid');
|
|
1756
|
-
if (li.classList.contains(classNames.hasChild) && uID) {
|
|
1757
|
-
const ul: Element = closest(li.parentNode, '.' + classNames.parentItem);
|
|
1758
|
-
let ele: Element = this.element.querySelector('[pid=\'' + uID + '\']');
|
|
1759
|
-
this.curDSLevel.push(uID);
|
|
1760
|
-
this.setViewDataSource(this.getSubDS());
|
|
1761
|
-
if (this.enableVirtualization) {
|
|
1762
|
-
this.virtualizationModule.updateDOMItemCount();
|
|
1763
|
-
}
|
|
1764
|
-
if (!ele) {
|
|
1765
|
-
const data: DataSource[] = this.curViewDS as DataSource[];
|
|
1766
|
-
ele = ListBase.createListFromJson(this.createElement, data, this.listBaseOption, this.curDSLevel.length, null, this);
|
|
1767
|
-
if ((this as any).isReact) {
|
|
1768
|
-
this.renderReactTemplates();
|
|
1769
|
-
}
|
|
1770
|
-
const lists: HTMLElement[] = <HTMLElement[] & NodeListOf<Element>>ele.querySelectorAll('.' + classNames.listItem);
|
|
1771
|
-
this.setAttributes(lists);
|
|
1772
|
-
ele.setAttribute('pID', <string>uID);
|
|
1773
|
-
(ele as HTMLElement).style.display = 'none';
|
|
1774
|
-
this.renderIntoDom(ele);
|
|
1775
|
-
}
|
|
1776
|
-
this.switchView(<HTMLElement>ul, <HTMLElement>ele);
|
|
1777
|
-
this.liCollection = <HTMLElement[] & NodeListOf<Element>>this.curUL.querySelectorAll('.' + classNames.listItem);
|
|
1778
|
-
if (this.selectedItems) {
|
|
1779
|
-
const fieldData: DataSource = <DataSource>
|
|
1780
|
-
getFieldValues(<DataSource | string>this.selectedItems.data, this.listBaseOption.fields);
|
|
1781
|
-
|
|
1782
|
-
this.header((fieldData[this.listBaseOption.fields.text]) as FieldsMapping as string, true, 'header');
|
|
1783
|
-
}
|
|
1784
|
-
this.selectedLI = undefined;
|
|
1785
|
-
}
|
|
1786
|
-
}
|
|
1787
|
-
|
|
1788
|
-
private renderIntoDom(ele: Element): void {
|
|
1789
|
-
this.contentContainer.appendChild(ele);
|
|
1790
|
-
}
|
|
1791
|
-
|
|
1792
|
-
private renderList(data?: DataSource[]): void {
|
|
1793
|
-
this.setViewDataSource(data);
|
|
1794
|
-
if (this.enableVirtualization) {
|
|
1795
|
-
if (Object.keys(this.dataSource).length) {
|
|
1796
|
-
if ((this.template || this.groupTemplate) && !this.virtualizationModule.isNgTemplate()) {
|
|
1797
|
-
this.listBaseOption.itemCreated = this.virtualizationModule.createUIItem.bind(this.virtualizationModule);
|
|
1798
|
-
}
|
|
1799
|
-
}
|
|
1800
|
-
this.virtualizationModule.uiVirtualization();
|
|
1801
|
-
} else {
|
|
1802
|
-
this.createList();
|
|
1803
|
-
this.contentContainer = this.createElement('div', { className: classNames.container });
|
|
1804
|
-
this.element.appendChild(this.contentContainer);
|
|
1805
|
-
this.renderIntoDom(this.ulElement);
|
|
1806
|
-
if ((this as any).isReact) {
|
|
1807
|
-
this.renderReactTemplates();
|
|
1808
|
-
}
|
|
1809
|
-
}
|
|
1810
|
-
}
|
|
1811
|
-
|
|
1812
|
-
private getElementUID(obj: Fields | HTMLElement | Element): Fields {
|
|
1813
|
-
let fields: DataSource = {};
|
|
1814
|
-
if (obj instanceof Element) {
|
|
1815
|
-
fields[this.fields.id] = obj.getAttribute('data-uid') as FieldSettingsModel;
|
|
1816
|
-
} else {
|
|
1817
|
-
fields = <DataSource>obj;
|
|
1818
|
-
}
|
|
1819
|
-
return fields;
|
|
1820
|
-
}
|
|
1821
|
-
|
|
1822
|
-
/**
|
|
1823
|
-
* Initializes the ListView component rendering.
|
|
1824
|
-
*/
|
|
1825
|
-
|
|
1826
|
-
public render(): void {
|
|
1827
|
-
this.element.classList.add(classNames.root);
|
|
1828
|
-
attributes(this.element, { tabindex: '0' });
|
|
1829
|
-
this.setCSSClass();
|
|
1830
|
-
this.setEnableRTL();
|
|
1831
|
-
this.setEnable();
|
|
1832
|
-
this.setSize();
|
|
1833
|
-
this.wireEvents();
|
|
1834
|
-
this.header();
|
|
1835
|
-
this.setLocalData();
|
|
1836
|
-
this.setHTMLAttribute();
|
|
1837
|
-
this.rippleFn = rippleEffect(this.element, {
|
|
1838
|
-
selector: '.' + classNames.listItem
|
|
1839
|
-
});
|
|
1840
|
-
this.renderComplete();
|
|
1841
|
-
this.previousScrollTop = this.element.scrollTop;
|
|
1842
|
-
}
|
|
1843
|
-
|
|
1844
|
-
/**
|
|
1845
|
-
* It is used to destroy the ListView component.
|
|
1846
|
-
*/
|
|
1847
|
-
|
|
1848
|
-
public destroy(): void {
|
|
1849
|
-
if ((this as any).isReact) {
|
|
1850
|
-
this.clearTemplate();
|
|
1851
|
-
}
|
|
1852
|
-
this.unWireEvents();
|
|
1853
|
-
const classAr: string[] = [classNames.root, classNames.disable, 'e-rtl',
|
|
1854
|
-
'e-has-header', 'e-lib'].concat(this.cssClass ? this.cssClass.split(' ').filter((css: string) => css) : []);
|
|
1855
|
-
removeClass([this.element], classAr);
|
|
1856
|
-
this.element.removeAttribute('role');
|
|
1857
|
-
this.element.removeAttribute('tabindex');
|
|
1858
|
-
this.curUL = this.ulElement = this.liCollection = this.headerEle = undefined;
|
|
1859
|
-
this.element.innerHTML = '';
|
|
1860
|
-
this.contentContainer = null;
|
|
1861
|
-
this.selectedItems = null;
|
|
1862
|
-
this.selectedLI = null;
|
|
1863
|
-
this.liElement = null;
|
|
1864
|
-
this.targetElement = null;
|
|
1865
|
-
this.currentLiElements = null;
|
|
1866
|
-
this.virtualCheckBox = null;
|
|
1867
|
-
super.destroy();
|
|
1868
|
-
}
|
|
1869
|
-
|
|
1870
|
-
/**
|
|
1871
|
-
* Switches back from the navigated sub list item.
|
|
1872
|
-
*/
|
|
1873
|
-
|
|
1874
|
-
public back(): void {
|
|
1875
|
-
const pID: string = this.curDSLevel[this.curDSLevel.length - 1];
|
|
1876
|
-
if (pID === undefined || this.isInAnimation()) { return; }
|
|
1877
|
-
this.curDSLevel.pop();
|
|
1878
|
-
this.setViewDataSource(this.getSubDS());
|
|
1879
|
-
if (this.enableVirtualization) {
|
|
1880
|
-
this.virtualizationModule.updateDOMItemCount();
|
|
1881
|
-
}
|
|
1882
|
-
let toUL: HTMLElement = <HTMLElement>this.element.querySelector('[data-uid=\'' + pID + '\']');
|
|
1883
|
-
const fromUL: HTMLElement = this.curUL;
|
|
1884
|
-
if (!toUL) {
|
|
1885
|
-
this.createList();
|
|
1886
|
-
this.renderIntoDom(this.ulElement);
|
|
1887
|
-
toUL = this.curUL;
|
|
1888
|
-
} else {
|
|
1889
|
-
toUL = toUL.parentElement;
|
|
1890
|
-
}
|
|
1891
|
-
const fieldData: DataSource = <DataSource>getFieldValues(this.curDSJSON, this.listBaseOption.fields);
|
|
1892
|
-
const text: string = fieldData[this.fields.text] as FieldSettingsModel as string;
|
|
1893
|
-
this.switchView(fromUL, toUL, true);
|
|
1894
|
-
this.removeFocus();
|
|
1895
|
-
const li: HTMLElement = <HTMLElement>this.element.querySelector('[data-uid=\'' + pID + '\']');
|
|
1896
|
-
li.classList.remove(classNames.disable);
|
|
1897
|
-
li.classList.add(classNames.focused);
|
|
1898
|
-
if (!(this.showCheckBox && li.querySelector('.' + classNames.checkboxIcon).classList.contains(classNames.checked))){
|
|
1899
|
-
li.classList.remove(classNames.selected);
|
|
1900
|
-
}
|
|
1901
|
-
this.liCollection = <HTMLElement[] & NodeListOf<Element>>this.curUL.querySelectorAll('.' + classNames.listItem);
|
|
1902
|
-
if (this.enableHtmlSanitizer) {
|
|
1903
|
-
this.setProperties({ headerTitle: SanitizeHtmlHelper.sanitize(this.headerTitle) }, true);
|
|
1904
|
-
}
|
|
1905
|
-
this.header((this.curDSLevel.length ? text : this.headerTitle), (this.curDSLevel.length ? true : false), 'header');
|
|
1906
|
-
}
|
|
1907
|
-
|
|
1908
|
-
/**
|
|
1909
|
-
* Selects the list item from the ListView by passing the elements or field object.
|
|
1910
|
-
*
|
|
1911
|
-
* @param {Fields | HTMLElement | Element} item - We can pass element Object or Fields as Object with ID and Text fields.
|
|
1912
|
-
*/
|
|
1913
|
-
|
|
1914
|
-
public selectItem(item: Fields | HTMLElement | Element): void {
|
|
1915
|
-
if (this.enableVirtualization) {
|
|
1916
|
-
this.virtualizationModule.selectItem(item);
|
|
1917
|
-
} else if (this.showCheckBox) {
|
|
1918
|
-
this.setCheckboxLI(this.getLiFromObjOrElement(item));
|
|
1919
|
-
} else {
|
|
1920
|
-
if (isNullOrUndefined(item) === true) {
|
|
1921
|
-
this.removeSelect();
|
|
1922
|
-
}
|
|
1923
|
-
else {
|
|
1924
|
-
this.setSelectLI(this.getLiFromObjOrElement(item));
|
|
1925
|
-
}
|
|
1926
|
-
|
|
1927
|
-
}
|
|
1928
|
-
}
|
|
1929
|
-
|
|
1930
|
-
/**
|
|
1931
|
-
* This method allows for deselecting a list item within the ListView. The item to be deselected can be specified by passing the element or field object.
|
|
1932
|
-
*
|
|
1933
|
-
* @param {Fields | HTMLElement | Element} item - We can pass an element Object or Fields as an Object with ID and Text fields.
|
|
1934
|
-
*/
|
|
1935
|
-
|
|
1936
|
-
public unselectItem(item?: Fields | HTMLElement | Element): void {
|
|
1937
|
-
if (isNullOrUndefined(item)) {
|
|
1938
|
-
this.removeSelect();
|
|
1939
|
-
} else {
|
|
1940
|
-
const li: HTMLElement = this.getLiFromObjOrElement(item);
|
|
1941
|
-
if (!isNullOrUndefined(li)) {
|
|
1942
|
-
this.removeSelect(li);
|
|
1943
|
-
}
|
|
1944
|
-
}
|
|
1945
|
-
}
|
|
1946
|
-
|
|
1947
|
-
private getLiFromObjOrElement(obj: Fields | HTMLElement | Element): HTMLElement {
|
|
1948
|
-
let li: Element;
|
|
1949
|
-
const dataSource: DataSource[] | string[] | number[] | DataManager = this.dataSource instanceof DataManager ?
|
|
1950
|
-
this.localData : this.dataSource;
|
|
1951
|
-
if (!isNullOrUndefined(obj)) {
|
|
1952
|
-
if (typeof (dataSource as string[])[0] === 'string' || typeof (dataSource as number[])[0] === 'number') {
|
|
1953
|
-
if (obj instanceof Element) {
|
|
1954
|
-
const uid: string = (obj as HTMLElement).getAttribute('data-uid').toString();
|
|
1955
|
-
for (let i: number = 0; i < this.liCollection.length; i++) {
|
|
1956
|
-
if (this.liCollection[parseInt(i.toString(), 10)].getAttribute('data-uid').toString() === uid) {
|
|
1957
|
-
li = this.liCollection[parseInt(i.toString(), 10)] as HTMLElement;
|
|
1958
|
-
break;
|
|
1959
|
-
}
|
|
1960
|
-
}
|
|
1961
|
-
} else {
|
|
1962
|
-
Array.prototype.some.call(this.curUL.querySelectorAll('.' + classNames.listItem), (item: HTMLElement) => {
|
|
1963
|
-
if (item.innerText.trim() === obj.toString()) {
|
|
1964
|
-
li = item;
|
|
1965
|
-
return true;
|
|
1966
|
-
} else {
|
|
1967
|
-
return false;
|
|
1968
|
-
}
|
|
1969
|
-
});
|
|
1970
|
-
}
|
|
1971
|
-
} else {
|
|
1972
|
-
const resultJSON: DataSource[] | DataSource = this.getItemData(obj);
|
|
1973
|
-
const fieldData: DataSource =
|
|
1974
|
-
<DataSource>getFieldValues(resultJSON, this.listBaseOption.fields);
|
|
1975
|
-
if (resultJSON) {
|
|
1976
|
-
li = this.element.querySelector('[data-uid="'
|
|
1977
|
-
+ (<DataSource>fieldData)[this.fields.id] + '"]');
|
|
1978
|
-
if (!this.enableVirtualization && isNullOrUndefined(li)) {
|
|
1979
|
-
const curLi: NodeListOf<Element> = this.element.querySelectorAll('.' + classNames.listItem);
|
|
1980
|
-
for (let i: number = 0; i < curLi.length; i++) {
|
|
1981
|
-
if ((curLi[parseInt(i.toString(), 10)] as HTMLElement).innerText.trim() ===
|
|
1982
|
-
fieldData[this.fields.text] as FieldSettingsModel) {
|
|
1983
|
-
li = curLi[parseInt(i.toString(), 10)];
|
|
1984
|
-
}
|
|
1985
|
-
}
|
|
1986
|
-
}
|
|
1987
|
-
}
|
|
1988
|
-
}
|
|
1989
|
-
}
|
|
1990
|
-
return <HTMLElement>li;
|
|
1991
|
-
}
|
|
1992
|
-
|
|
1993
|
-
/**
|
|
1994
|
-
* Selects multiple list items from the ListView.
|
|
1995
|
-
*
|
|
1996
|
-
* @param {Fields[] | HTMLElement[] | Element[]} item - We can pass array of
|
|
1997
|
-
* elements or array of fields Object with ID and Text fields.
|
|
1998
|
-
*/
|
|
1999
|
-
|
|
2000
|
-
public selectMultipleItems(item: Fields[] | HTMLElement[] | Element[]): void {
|
|
2001
|
-
if (!isNullOrUndefined(item)) {
|
|
2002
|
-
for (let i: number = 0; i < item.length; i++) {
|
|
2003
|
-
if (!isNullOrUndefined(item[parseInt(i.toString(), 10)])) {
|
|
2004
|
-
this.selectItem(item[parseInt(i.toString(), 10)]);
|
|
2005
|
-
}
|
|
2006
|
-
}
|
|
2007
|
-
}
|
|
2008
|
-
}
|
|
2009
|
-
|
|
2010
|
-
private getParentId(): string[] {
|
|
2011
|
-
const parentId: string[] = [];
|
|
2012
|
-
if (this.isNestedList) {
|
|
2013
|
-
for (let i: number = this.curDSLevel.length - 1; i >= 0; i--) {
|
|
2014
|
-
parentId.push(this.curDSLevel[parseInt(i.toString(), 10)]);
|
|
2015
|
-
}
|
|
2016
|
-
}
|
|
2017
|
-
return parentId;
|
|
2018
|
-
}
|
|
2019
|
-
|
|
2020
|
-
private updateSelectedId(): void {
|
|
2021
|
-
this.selectedId = [];
|
|
2022
|
-
const liCollection: HTMLCollectionOf<Element> = this.curUL.getElementsByClassName(classNames.selected);
|
|
2023
|
-
for (let i: number = 0; i < liCollection.length; i++) {
|
|
2024
|
-
const tempData: DataSource = this.getItemData(liCollection[parseInt(i.toString(), 10)] as HTMLElement);
|
|
2025
|
-
if (!isNullOrUndefined(tempData) && tempData[this.listBaseOption.fields.id]) {
|
|
2026
|
-
this.selectedId.push(tempData[this.listBaseOption.fields.id] as FieldsMapping as string);
|
|
2027
|
-
}
|
|
2028
|
-
}
|
|
2029
|
-
}
|
|
2030
|
-
|
|
2031
|
-
/**
|
|
2032
|
-
* Gets the details of the currently selected item from the list items.
|
|
2033
|
-
*
|
|
2034
|
-
*/
|
|
2035
|
-
|
|
2036
|
-
public getSelectedItems(): SelectedItem | SelectedCollection | UISelectedItem | NestedListData {
|
|
2037
|
-
let finalValue: any;
|
|
2038
|
-
let isCompleted: boolean = false;
|
|
2039
|
-
this.selectedId = [];
|
|
2040
|
-
const dataSource: DataSource[] | string[] | number[] | DataManager = this.dataSource instanceof DataManager ?
|
|
2041
|
-
this.localData : this.dataSource;
|
|
2042
|
-
if (this.enableVirtualization && !isCompleted) {
|
|
2043
|
-
finalValue = this.virtualizationModule.getSelectedItems();
|
|
2044
|
-
isCompleted = true;
|
|
2045
|
-
} else if (this.showCheckBox && !isCompleted) {
|
|
2046
|
-
const liCollection: any = this.curUL.getElementsByClassName(classNames.selected);
|
|
2047
|
-
const liTextCollection: string[] = []; const liDataCollection: DataSource[] = []; this.selectedId = [];
|
|
2048
|
-
const dataParent: DataAndParent[] = [];
|
|
2049
|
-
for (let i: number = 0; i < liCollection.length; i++) {
|
|
2050
|
-
if (typeof (dataSource as string[])[0] === 'string' || typeof (dataSource as number[])[0] === 'number') {
|
|
2051
|
-
liTextCollection.push((liCollection[parseInt(i.toString(), 10)] as HTMLElement).innerText.trim());
|
|
2052
|
-
} else {
|
|
2053
|
-
const tempData: DataSource = this.getItemData(liCollection[parseInt(i.toString(), 10)] as HTMLElement);
|
|
2054
|
-
const fieldData: DataSource =
|
|
2055
|
-
<DataSource>getFieldValues(tempData, this.listBaseOption.fields);
|
|
2056
|
-
if (this.isNestedList) {
|
|
2057
|
-
dataParent.push({ data: tempData, parentId: this.getParentId() });
|
|
2058
|
-
} else {
|
|
2059
|
-
liDataCollection.push(tempData);
|
|
2060
|
-
}
|
|
2061
|
-
if (fieldData) {
|
|
2062
|
-
liTextCollection.push(fieldData[this.listBaseOption.fields.text] as FieldsMapping as string);
|
|
2063
|
-
this.selectedId.push(fieldData[this.listBaseOption.fields.id] as FieldsMapping as string);
|
|
2064
|
-
} else {
|
|
2065
|
-
liTextCollection.push(undefined);
|
|
2066
|
-
this.selectedId.push(undefined);
|
|
2067
|
-
}
|
|
2068
|
-
}
|
|
2069
|
-
}
|
|
2070
|
-
if ((typeof (dataSource as string[])[0] === 'string'
|
|
2071
|
-
|| typeof (dataSource as number[])[0] === 'number')
|
|
2072
|
-
&& !isCompleted) {
|
|
2073
|
-
finalValue = { item: liCollection, data: dataSource as string[] | number[], text: liTextCollection };
|
|
2074
|
-
isCompleted = true;
|
|
2075
|
-
}
|
|
2076
|
-
if (this.isNestedList && !isCompleted) {
|
|
2077
|
-
finalValue = { item: liCollection, data: dataParent as any, text: liTextCollection };
|
|
2078
|
-
isCompleted = true;
|
|
2079
|
-
} else if (!isCompleted) {
|
|
2080
|
-
finalValue = { item: liCollection, data: liDataCollection, text: liTextCollection };
|
|
2081
|
-
isCompleted = true;
|
|
2082
|
-
}
|
|
2083
|
-
} else if (!isCompleted) {
|
|
2084
|
-
const liElement: Element = this.element.getElementsByClassName(classNames.selected)[0];
|
|
2085
|
-
const fieldData: DataSource =
|
|
2086
|
-
<DataSource>getFieldValues(this.getItemData(liElement), this.listBaseOption.fields);
|
|
2087
|
-
if ((typeof (dataSource as string[])[0] === 'string'
|
|
2088
|
-
|| typeof (dataSource as number[])[0] === 'number')
|
|
2089
|
-
&& !isCompleted) {
|
|
2090
|
-
finalValue = (!isNullOrUndefined(liElement)) ? {
|
|
2091
|
-
item: liElement, data: dataSource as string[] | number[],
|
|
2092
|
-
text: (liElement as HTMLElement).innerText.trim()
|
|
2093
|
-
} : undefined;
|
|
2094
|
-
isCompleted = true;
|
|
2095
|
-
} else if (!isCompleted) {
|
|
2096
|
-
if (isNullOrUndefined(fieldData) || isNullOrUndefined(liElement)) {
|
|
2097
|
-
finalValue = undefined;
|
|
2098
|
-
isCompleted = true;
|
|
2099
|
-
} else {
|
|
2100
|
-
this.selectedId.push(fieldData[this.listBaseOption.fields.id] as FieldsMapping as string);
|
|
2101
|
-
finalValue = {
|
|
2102
|
-
text: fieldData[this.listBaseOption.fields.text], item: liElement,
|
|
2103
|
-
data: this.getItemData(liElement)
|
|
2104
|
-
};
|
|
2105
|
-
isCompleted = true;
|
|
2106
|
-
}
|
|
2107
|
-
}
|
|
2108
|
-
}
|
|
2109
|
-
return finalValue;
|
|
2110
|
-
}
|
|
2111
|
-
|
|
2112
|
-
/**
|
|
2113
|
-
* Finds out an item details from the current list.
|
|
2114
|
-
*
|
|
2115
|
-
* @param {Fields | HTMLElement | Element} item - We can pass element Object or Fields as Object with ID and Text fields.
|
|
2116
|
-
*/
|
|
2117
|
-
|
|
2118
|
-
public findItem(item: Fields | HTMLElement | Element): SelectedItem {
|
|
2119
|
-
return <SelectedItem & DataSource>this.getItemData(item);
|
|
2120
|
-
}
|
|
2121
|
-
|
|
2122
|
-
/**
|
|
2123
|
-
* Enables the disabled list items by passing the Id and text fields.
|
|
2124
|
-
*
|
|
2125
|
-
* @param {Fields | HTMLElement | Element} item - We can pass element Object or Fields as Object with ID and Text fields.
|
|
2126
|
-
*/
|
|
2127
|
-
|
|
2128
|
-
public enableItem(item: Fields | HTMLElement | Element): void {
|
|
2129
|
-
this.setItemState(item, true);
|
|
2130
|
-
if (this.enableVirtualization) {
|
|
2131
|
-
this.virtualizationModule.enableItem(item);
|
|
2132
|
-
}
|
|
2133
|
-
}
|
|
2134
|
-
|
|
2135
|
-
/**
|
|
2136
|
-
* Disables the list items by passing the Id and text fields.
|
|
2137
|
-
*
|
|
2138
|
-
* @param {Fields | HTMLElement | Element} item - We can pass element Object or Fields as Object with ID and Text fields.
|
|
2139
|
-
*/
|
|
2140
|
-
|
|
2141
|
-
public disableItem(item: Fields | HTMLElement | Element): void {
|
|
2142
|
-
this.setItemState(item, false);
|
|
2143
|
-
if (this.enableVirtualization) {
|
|
2144
|
-
this.virtualizationModule.disableItem(item);
|
|
2145
|
-
}
|
|
2146
|
-
}
|
|
2147
|
-
|
|
2148
|
-
//A function that used to set state of the list item like enable, disable.
|
|
2149
|
-
private setItemState(item: Fields | HTMLElement | Element, isEnable: boolean): void {
|
|
2150
|
-
const resultJSON: DataSource = this.getItemData(item);
|
|
2151
|
-
const fieldData: DataSource = <DataSource>getFieldValues(resultJSON, this.listBaseOption.fields);
|
|
2152
|
-
if (resultJSON) {
|
|
2153
|
-
const li: Element = this.element.querySelector('[data-uid="' + fieldData[this.fields.id] + '"]');
|
|
2154
|
-
if (isEnable) {
|
|
2155
|
-
if (li) { li.classList.remove(classNames.disable); }
|
|
2156
|
-
delete resultJSON[this.fields.enabled];
|
|
2157
|
-
} else if (!isEnable) {
|
|
2158
|
-
if (li) { li.classList.add(classNames.disable); }
|
|
2159
|
-
resultJSON[this.fields.enabled] = false as any;
|
|
2160
|
-
}
|
|
2161
|
-
}
|
|
2162
|
-
}
|
|
2163
|
-
|
|
2164
|
-
/**
|
|
2165
|
-
* Shows the hide list item from the ListView.
|
|
2166
|
-
*
|
|
2167
|
-
* @param {Fields | HTMLElement | Element} item - We can pass element Object or Fields as Object with ID and Text fields.
|
|
2168
|
-
*/
|
|
2169
|
-
|
|
2170
|
-
public showItem(item: Fields | HTMLElement | Element): void {
|
|
2171
|
-
this.showHideItem(item, false, '');
|
|
2172
|
-
if (this.enableVirtualization) {
|
|
2173
|
-
this.virtualizationModule.showItem(item);
|
|
2174
|
-
}
|
|
2175
|
-
}
|
|
2176
|
-
|
|
2177
|
-
/**
|
|
2178
|
-
* Hides an list item from the ListView.
|
|
2179
|
-
*
|
|
2180
|
-
* @param {Fields | HTMLElement | Element} item - We can pass element Object or Fields as Object with ID and Text fields.
|
|
2181
|
-
*/
|
|
2182
|
-
|
|
2183
|
-
public hideItem(item: Fields | HTMLElement | Element): void {
|
|
2184
|
-
this.showHideItem(item, true, 'none');
|
|
2185
|
-
if (this.enableVirtualization) {
|
|
2186
|
-
this.virtualizationModule.hideItem(item);
|
|
2187
|
-
}
|
|
2188
|
-
}
|
|
2189
|
-
|
|
2190
|
-
private showHideItem(obj: Fields | HTMLElement | Element, isHide: boolean, display: string): void {
|
|
2191
|
-
const resultJSON: DataSource = this.getItemData(obj);
|
|
2192
|
-
const fieldData: DataSource = <DataSource>getFieldValues(resultJSON, this.listBaseOption.fields);
|
|
2193
|
-
if (resultJSON) {
|
|
2194
|
-
const li: HTMLElement = <HTMLElement>this.element.querySelector('[data-uid="' + fieldData[this.fields.id] + '"]');
|
|
2195
|
-
if (li) { li.style.display = display; }
|
|
2196
|
-
if (isHide) {
|
|
2197
|
-
resultJSON[this.fields.isVisible] = false as any;
|
|
2198
|
-
} else {
|
|
2199
|
-
delete resultJSON[this.fields.isVisible];
|
|
2200
|
-
}
|
|
2201
|
-
}
|
|
2202
|
-
}
|
|
2203
|
-
|
|
2204
|
-
/**
|
|
2205
|
-
* Adds the new list item(s) to the current ListView.
|
|
2206
|
-
* To add a new list item(s) in the ListView, we need to pass the `data` as an array of items that need
|
|
2207
|
-
* to be added and `fields` as the target item to which we need to add the given item(s) as its children.
|
|
2208
|
-
* For example fields: { text: 'Name', tooltip: 'Name', id:'id'}
|
|
2209
|
-
*
|
|
2210
|
-
* @param {{Object}[]} data - JSON Array Data that need to add.
|
|
2211
|
-
*
|
|
2212
|
-
* @param {Fields} fields - Target item to add the given data as its children (can be null).
|
|
2213
|
-
*
|
|
2214
|
-
* @param {number} index - Indicates the index where the data to be added.
|
|
2215
|
-
*/
|
|
2216
|
-
|
|
2217
|
-
public addItem(data: { [key: string]: Object }[], fields: Fields = undefined, index?: number): void {
|
|
2218
|
-
const dataSource: DataSource[] = this.dataSource instanceof DataManager
|
|
2219
|
-
? this.localData : this.dataSource as DataSource[];
|
|
2220
|
-
this.addItemInternally(data, fields, dataSource, index);
|
|
2221
|
-
}
|
|
2222
|
-
|
|
2223
|
-
private addItemInternally(data: DataSource[], fields: Fields, dataSource: DataSource[], index?: number): void {
|
|
2224
|
-
if (data instanceof Array) {
|
|
2225
|
-
if (this.enableVirtualization) {
|
|
2226
|
-
this.virtualizationModule.addItem(data, fields, dataSource, index);
|
|
2227
|
-
} else {
|
|
2228
|
-
const ds: DataSource = <DataSource>this.findItemFromDS(
|
|
2229
|
-
<DataSource[]>dataSource, <DataSource>fields);
|
|
2230
|
-
let child: DataSource[];
|
|
2231
|
-
if (ds) {
|
|
2232
|
-
const fieldData: DataSource = <DataSource>getFieldValues(ds, this.listBaseOption.fields);
|
|
2233
|
-
child = <DataSource[]>fieldData[this.fields.child];
|
|
2234
|
-
if (!child) {
|
|
2235
|
-
child = [];
|
|
2236
|
-
}
|
|
2237
|
-
child = child.concat(data);
|
|
2238
|
-
}
|
|
2239
|
-
// check for whether target is nested level or top level in list
|
|
2240
|
-
if (ds instanceof Array) {
|
|
2241
|
-
for (let i: number = 0; i < data.length; i++) {
|
|
2242
|
-
dataSource = this.addItemAtIndex(index, dataSource, data[parseInt(i.toString(), 10)]);
|
|
2243
|
-
this.setViewDataSource(dataSource);
|
|
2244
|
-
// since it is top level target, get the content container's first child
|
|
2245
|
-
// as it is always the top level UL
|
|
2246
|
-
const targetUL: HTMLElement = this.contentContainer
|
|
2247
|
-
? <HTMLElement>this.contentContainer.children[0]
|
|
2248
|
-
: null;
|
|
2249
|
-
// check for whether the list was previously empty or not, if it is
|
|
2250
|
-
// proceed to call initial render
|
|
2251
|
-
if (this.contentContainer && targetUL) {
|
|
2252
|
-
this.addItemIntoDom(data[parseInt(i.toString(), 10)], targetUL, this.curViewDS as DataSource[]);
|
|
2253
|
-
} else {
|
|
2254
|
-
this.reRender();
|
|
2255
|
-
}
|
|
2256
|
-
}
|
|
2257
|
-
this.liCollection = <HTMLElement[] & NodeListOf<Element>>this.curUL.querySelectorAll('.' + classNames.listItem);
|
|
2258
|
-
} else {
|
|
2259
|
-
// proceed as target item is in nested level, only if it is a valid target ds
|
|
2260
|
-
if (ds) {
|
|
2261
|
-
ds[this.fields.child] = child;
|
|
2262
|
-
this.addItemInNestedList(ds, data);
|
|
2263
|
-
}
|
|
2264
|
-
}
|
|
2265
|
-
}
|
|
2266
|
-
}
|
|
2267
|
-
}
|
|
2268
|
-
|
|
2269
|
-
private addItemAtIndex(index: number, newDataSource: DataSource[], itemData: DataSource): DataSource[] {
|
|
2270
|
-
const isIndexValid: boolean = !(isNullOrUndefined(index)) && index >= 0 &&
|
|
2271
|
-
index < newDataSource.length && isNullOrUndefined(this.listBaseOption.fields.groupBy);
|
|
2272
|
-
if (isIndexValid) {
|
|
2273
|
-
newDataSource.splice(index, 0, itemData);
|
|
2274
|
-
} else {
|
|
2275
|
-
newDataSource.push(itemData);
|
|
2276
|
-
}
|
|
2277
|
-
return newDataSource;
|
|
2278
|
-
}
|
|
2279
|
-
|
|
2280
|
-
private addItemInNestedList(targetItemData: DataSource, itemQueue: DataSource[]): void {
|
|
2281
|
-
const targetItemId: string = targetItemData[this.fields.id] as any;
|
|
2282
|
-
const targetChildDS: DataSource[] = targetItemData[this.fields.child] as DataSource[];
|
|
2283
|
-
const isAlreadyRenderedUL: HTMLElement | null = this.element.querySelector('[pid=\'' + targetItemId + '\']');
|
|
2284
|
-
const targetLi: HTMLElement | null = this.element.querySelector('[data-uid=\'' + targetItemId + '\']');
|
|
2285
|
-
const targetUL: HTMLElement | null = isAlreadyRenderedUL
|
|
2286
|
-
? isAlreadyRenderedUL
|
|
2287
|
-
: targetLi
|
|
2288
|
-
? <HTMLElement>closest(targetLi, 'ul')
|
|
2289
|
-
: null;
|
|
2290
|
-
const targetDS: DataSource[] = isAlreadyRenderedUL ? targetChildDS : [targetItemData];
|
|
2291
|
-
const isTargetEmptyChild: boolean = targetLi ? !targetLi.classList.contains(classNames.hasChild) : false;
|
|
2292
|
-
// if li element is already rendered, that element needs to be refreshed so that
|
|
2293
|
-
// it becomes child viewable due to new child items are added now
|
|
2294
|
-
if (isTargetEmptyChild) {
|
|
2295
|
-
const targetRefreshedElement: HTMLElement[] = ListBase.createListItemFromJson(
|
|
2296
|
-
this.createElement, targetDS, this.listBaseOption, null, null, this);
|
|
2297
|
-
this.setAttributes(targetRefreshedElement);
|
|
2298
|
-
targetUL.insertBefore(targetRefreshedElement[0], targetLi);
|
|
2299
|
-
detach(targetLi);
|
|
2300
|
-
}
|
|
2301
|
-
// if it is already rendered element, we need to create and append new elements
|
|
2302
|
-
if (isAlreadyRenderedUL && itemQueue) {
|
|
2303
|
-
for (let i: number = 0; i < itemQueue.length; i++) {
|
|
2304
|
-
targetDS.push(itemQueue[parseInt(i.toString(), 10)]);
|
|
2305
|
-
this.addItemIntoDom(itemQueue[parseInt(i.toString(), 10)], targetUL, targetDS);
|
|
2306
|
-
}
|
|
2307
|
-
}
|
|
2308
|
-
}
|
|
2309
|
-
|
|
2310
|
-
private addItemIntoDom(currentItem: DataSource, targetUL: HTMLElement, curViewDS: DataSource[]): void {
|
|
2311
|
-
const index: number = curViewDS.indexOf(currentItem);
|
|
2312
|
-
this.addListItem(currentItem, index, targetUL, curViewDS);
|
|
2313
|
-
const curItemDS: DataSource = curViewDS[index - 1];
|
|
2314
|
-
if (curItemDS && curItemDS.isHeader && (curItemDS.items as DataSource[]).length === 1) {
|
|
2315
|
-
this.addListItem(curItemDS, (index - 1), targetUL, curViewDS);
|
|
2316
|
-
}
|
|
2317
|
-
}
|
|
2318
|
-
|
|
2319
|
-
private addListItem(dataSource: DataSource, index: number, ulElement: HTMLElement, curViewDS: DataSource[]): void {
|
|
2320
|
-
let target: HTMLElement = this.getLiFromObjOrElement((curViewDS as DataSource[])[index + 1]) ||
|
|
2321
|
-
this.getLiFromObjOrElement((curViewDS as DataSource[])[index + 2]) || null;
|
|
2322
|
-
const li: HTMLElement[] = ListBase.createListItemFromJson(this.createElement, [dataSource], this.listBaseOption, null, null, this);
|
|
2323
|
-
this.setAttributes(li);
|
|
2324
|
-
if (this.template && (this as any).isReact) {
|
|
2325
|
-
this.renderReactTemplates();
|
|
2326
|
-
}
|
|
2327
|
-
if (this.fields.groupBy && curViewDS[index + 1] && curViewDS[index + 1].isHeader) {
|
|
2328
|
-
const targetEle: HTMLElement = this.getLiFromObjOrElement(curViewDS[index - 1]);
|
|
2329
|
-
if (targetEle) {
|
|
2330
|
-
target = targetEle.nextElementSibling as HTMLElement;
|
|
2331
|
-
}
|
|
2332
|
-
}
|
|
2333
|
-
ulElement.insertBefore(li[0], target);
|
|
2334
|
-
}
|
|
2335
|
-
|
|
2336
|
-
/**
|
|
2337
|
-
* Removes the list item from the data source based on a passed
|
|
2338
|
-
* element like fields: { text: 'Name', tooltip: 'Name', id:'id'}
|
|
2339
|
-
*
|
|
2340
|
-
* @param {Fields | HTMLElement | Element} item - We can pass element Object or Fields as Object with ID and Text fields.
|
|
2341
|
-
*/
|
|
2342
|
-
|
|
2343
|
-
public removeItem(item: Fields | HTMLElement | Element): void {
|
|
2344
|
-
const listDataSource: DataSource[] = this.dataSource instanceof DataManager
|
|
2345
|
-
? this.localData : this.dataSource as DataSource[];
|
|
2346
|
-
if (this.enableVirtualization) {
|
|
2347
|
-
this.virtualizationModule.removeItem(item);
|
|
2348
|
-
} else {
|
|
2349
|
-
this.removeItemFromList(item, listDataSource);
|
|
2350
|
-
}
|
|
2351
|
-
}
|
|
2352
|
-
|
|
2353
|
-
private removeItemFromList(obj: Fields | Element | HTMLElement, listDataSource: DataSource[]): void {
|
|
2354
|
-
const curViewDS: DataSource[] = this.curViewDS as DataSource[];
|
|
2355
|
-
const fields: Fields = obj instanceof Element ? this.getElementUID(obj) : obj;
|
|
2356
|
-
const dataSource: DataSource[] | DataSource = this.findItemFromDS(listDataSource, <DataSource>fields, true);
|
|
2357
|
-
if (dataSource) {
|
|
2358
|
-
const data: DataSource | DataSource[] = this.findItemFromDS(dataSource as DataSource[], <DataSource>fields);
|
|
2359
|
-
const index: number = curViewDS.indexOf(data as DataSource);
|
|
2360
|
-
const li: HTMLElement = this.getLiFromObjOrElement(obj);
|
|
2361
|
-
let groupLi: HTMLElement;
|
|
2362
|
-
this.validateNestedView(li);
|
|
2363
|
-
if (this.fields.groupBy && this.curViewDS[index - 1] &&
|
|
2364
|
-
curViewDS[index - 1].isHeader &&
|
|
2365
|
-
(curViewDS[index - 1].items as DataSource[]).length === 1) {
|
|
2366
|
-
if (li && (li.previousElementSibling as HTMLElement).classList.contains(classNames.groupListItem) &&
|
|
2367
|
-
(isNullOrUndefined(li.nextElementSibling) || (li.nextElementSibling &&
|
|
2368
|
-
(li.nextElementSibling as HTMLElement).classList.contains(classNames.groupListItem)))) {
|
|
2369
|
-
groupLi = li.previousElementSibling as HTMLElement;
|
|
2370
|
-
}
|
|
2371
|
-
}
|
|
2372
|
-
if (li) {
|
|
2373
|
-
detach(li);
|
|
2374
|
-
}
|
|
2375
|
-
if (groupLi) {
|
|
2376
|
-
detach(groupLi);
|
|
2377
|
-
}
|
|
2378
|
-
const foundData: any = ((<DataSource[]>dataSource).length - 1) <= 0
|
|
2379
|
-
? this.findParent(
|
|
2380
|
-
this.localData,
|
|
2381
|
-
this.fields.id,
|
|
2382
|
-
(value: string) => value === (data as DataSource)[this.fields.id] as FieldSettingsModel,
|
|
2383
|
-
null) : null;
|
|
2384
|
-
const dsIndex: number = (dataSource as DataSource[]).indexOf(data as DataSource);
|
|
2385
|
-
(dataSource as DataSource[]).splice(dsIndex, 1);
|
|
2386
|
-
this.setViewDataSource(listDataSource);
|
|
2387
|
-
if (foundData
|
|
2388
|
-
&& foundData.parent
|
|
2389
|
-
&& Array.isArray(foundData.parent[this.fields.child])
|
|
2390
|
-
&& foundData.parent[this.fields.child].length <= 0) {
|
|
2391
|
-
const parentLi: HTMLElement | null = this.getLiFromObjOrElement(foundData.parent);
|
|
2392
|
-
if (parentLi) {
|
|
2393
|
-
const li: HTMLElement[] = ListBase.createListItemFromJson(
|
|
2394
|
-
this.createElement,
|
|
2395
|
-
[foundData.parent],
|
|
2396
|
-
this.listBaseOption,
|
|
2397
|
-
null,
|
|
2398
|
-
null,
|
|
2399
|
-
this);
|
|
2400
|
-
this.setAttributes(li);
|
|
2401
|
-
parentLi.parentElement.insertBefore(li[0], parentLi);
|
|
2402
|
-
parentLi.parentElement.removeChild(parentLi);
|
|
2403
|
-
}
|
|
2404
|
-
}
|
|
2405
|
-
if ((dataSource as DataSource[]).length <= 0) {
|
|
2406
|
-
this.back();
|
|
2407
|
-
}
|
|
2408
|
-
this.liCollection = Array.prototype.slice.call(this.element.querySelectorAll('.' + classNames.listItem));
|
|
2409
|
-
}
|
|
2410
|
-
}
|
|
2411
|
-
|
|
2412
|
-
// validate before removing an element whether the current view is inside target element's child view
|
|
2413
|
-
private validateNestedView(li: HTMLElement | null): void {
|
|
2414
|
-
const liID: string = li ? li.getAttribute('data-uid').toString().toLowerCase() : null;
|
|
2415
|
-
if (liID && this.curDSLevel && this.curDSLevel.length > 0) {
|
|
2416
|
-
while (this.curDSLevel.some((id: string) => id.toString().toLowerCase() === liID)) {
|
|
2417
|
-
this.back();
|
|
2418
|
-
}
|
|
2419
|
-
}
|
|
2420
|
-
}
|
|
2421
|
-
|
|
2422
|
-
/**
|
|
2423
|
-
* Removes multiple items from the ListView by passing the array of elements or array of field objects.
|
|
2424
|
-
*
|
|
2425
|
-
* @param {Fields[] | HTMLElement[] | Element[]} item - We can pass array of elements or array of field Object with ID and Text fields.
|
|
2426
|
-
*/
|
|
2427
|
-
|
|
2428
|
-
public removeMultipleItems(item: HTMLElement[] | Element[] | Fields[]): void {
|
|
2429
|
-
if (item.length) {
|
|
2430
|
-
for (let i: number = 0; i < item.length; i++) {
|
|
2431
|
-
this.removeItem(item[parseInt(i.toString(), 10)]);
|
|
2432
|
-
}
|
|
2433
|
-
}
|
|
2434
|
-
}
|
|
2435
|
-
|
|
2436
|
-
private findParent(dataSource: any, id: string, callback: Function, parent: object): object {
|
|
2437
|
-
if (Object.prototype.hasOwnProperty.call(dataSource, id) && callback(dataSource[id as string]) === true) {
|
|
2438
|
-
return extend({}, dataSource);
|
|
2439
|
-
}
|
|
2440
|
-
|
|
2441
|
-
for (let i: number = 0; i < Object.keys(dataSource).length; i++) {
|
|
2442
|
-
if (dataSource[Object.keys(dataSource)[parseInt(i.toString(), 10)]]
|
|
2443
|
-
&& typeof dataSource[Object.keys(dataSource)[parseInt(i.toString(), 10)]] === 'object') {
|
|
2444
|
-
const result: any = this.findParent(dataSource[Object.keys(dataSource)[parseInt(i.toString(), 10)]],
|
|
2445
|
-
id, callback, dataSource);
|
|
2446
|
-
if (result != null) {
|
|
2447
|
-
if (!result.parent) { result.parent = parent; }
|
|
2448
|
-
return result;
|
|
2449
|
-
}
|
|
2450
|
-
}
|
|
2451
|
-
}
|
|
2452
|
-
return null;
|
|
2453
|
-
}
|
|
2454
|
-
|
|
2455
|
-
// Module Required function
|
|
2456
|
-
protected getModuleName(): string {
|
|
2457
|
-
return 'listview';
|
|
2458
|
-
}
|
|
2459
|
-
|
|
2460
|
-
public requiredModules(): ModuleDeclaration[] {
|
|
2461
|
-
const modules: ModuleDeclaration[] = [];
|
|
2462
|
-
if (this.enableVirtualization) {
|
|
2463
|
-
modules.push({ args: [this], member: 'virtualization', name: 'Virtualization' });
|
|
2464
|
-
}
|
|
2465
|
-
|
|
2466
|
-
return modules;
|
|
2467
|
-
}
|
|
2468
|
-
|
|
2469
|
-
private onListScroll(e: Event ): void {
|
|
2470
|
-
const args: ScrolledEventArgs = { originalEvent: e, scrollDirection: 'Bottom', distanceY: this.element.scrollHeight - this.element.scrollTop };
|
|
2471
|
-
const currentScrollTop: number = this.element.scrollTop;
|
|
2472
|
-
if (currentScrollTop > this.previousScrollTop) {
|
|
2473
|
-
args.scrollDirection = 'Bottom';
|
|
2474
|
-
args.distanceY = this.element.scrollHeight - this.element.clientHeight - this.element.scrollTop;
|
|
2475
|
-
this.trigger('scroll', args);
|
|
2476
|
-
} else if (this.previousScrollTop > currentScrollTop) {
|
|
2477
|
-
args.scrollDirection = 'Top';
|
|
2478
|
-
args.distanceY = this.element.scrollTop;
|
|
2479
|
-
this.trigger('scroll', args);
|
|
2480
|
-
}
|
|
2481
|
-
this.previousScrollTop = currentScrollTop;
|
|
2482
|
-
}
|
|
2483
|
-
|
|
2484
|
-
/**
|
|
2485
|
-
* Get the properties to be maintained in the persisted state.
|
|
2486
|
-
*/
|
|
2487
|
-
|
|
2488
|
-
protected getPersistData(): string {
|
|
2489
|
-
return this.addOnPersist(['cssClass', 'enableRtl', 'htmlAttributes',
|
|
2490
|
-
'enable', 'fields', 'animation', 'headerTitle',
|
|
2491
|
-
'sortOrder', 'showIcon', 'height', 'width', 'showCheckBox', 'checkBoxPosition', 'selectedId']);
|
|
2492
|
-
}
|
|
2493
|
-
|
|
2494
|
-
}
|
|
2495
|
-
|
|
2496
|
-
interface ResultData {
|
|
2497
|
-
result: { [key: string]: object }[];
|
|
2498
|
-
}
|
|
2499
|
-
|
|
2500
|
-
/** @hidden */
|
|
2501
|
-
export interface ClassNames {
|
|
2502
|
-
root: string;
|
|
2503
|
-
hover: string;
|
|
2504
|
-
focused: string;
|
|
2505
|
-
selected: string;
|
|
2506
|
-
parentItem: string;
|
|
2507
|
-
listItem: string;
|
|
2508
|
-
hasChild: string;
|
|
2509
|
-
view: string;
|
|
2510
|
-
header: string;
|
|
2511
|
-
text: string;
|
|
2512
|
-
headerText: string;
|
|
2513
|
-
headerTemplateText: string;
|
|
2514
|
-
listItemText: string;
|
|
2515
|
-
listIcon: string;
|
|
2516
|
-
textContent: string;
|
|
2517
|
-
groupListItem: string;
|
|
2518
|
-
disable: string;
|
|
2519
|
-
container: string;
|
|
2520
|
-
backIcon: string;
|
|
2521
|
-
backButton: string;
|
|
2522
|
-
icon: string;
|
|
2523
|
-
checkboxWrapper: string;
|
|
2524
|
-
checkbox: string;
|
|
2525
|
-
checked: string;
|
|
2526
|
-
checkboxIcon: string;
|
|
2527
|
-
checklist: string;
|
|
2528
|
-
checkboxRight: string;
|
|
2529
|
-
checkboxLeft: string;
|
|
2530
|
-
listviewCheckbox: string;
|
|
2531
|
-
itemCheckList: string;
|
|
2532
|
-
virtualElementContainer: string;
|
|
2533
|
-
listTemplate: string;
|
|
2534
|
-
|
|
2535
|
-
}
|
|
2536
|
-
|
|
2537
|
-
/**
|
|
2538
|
-
* An interface that holds list selected item.
|
|
2539
|
-
*/
|
|
2540
|
-
export interface ListSelectedItem {
|
|
2541
|
-
/**
|
|
2542
|
-
* Specifies the selected item dataSource collection.
|
|
2543
|
-
*
|
|
2544
|
-
* @isGenericType true
|
|
2545
|
-
*/
|
|
2546
|
-
data?: object[];
|
|
2547
|
-
/**
|
|
2548
|
-
* Specifies the selected item text collection.
|
|
2549
|
-
*/
|
|
2550
|
-
text?: string[];
|
|
2551
|
-
/**
|
|
2552
|
-
* Specifies index of the selected element.
|
|
2553
|
-
* Available only in virtualization.
|
|
2554
|
-
*/
|
|
2555
|
-
index?: number[];
|
|
2556
|
-
/**
|
|
2557
|
-
* Specifies the hierarchical parent id collection of the current view.
|
|
2558
|
-
* Available only in nested list with checkbox enabled.
|
|
2559
|
-
*/
|
|
2560
|
-
parentId?: string[];
|
|
2561
|
-
}
|
|
2562
|
-
|
|
2563
|
-
/**
|
|
2564
|
-
* An enum type that denotes the ListView scroll direction when it reaches the end.
|
|
2565
|
-
* ```props
|
|
2566
|
-
* Top:- The scrollbar is moved upwards.
|
|
2567
|
-
* Bottom:- The scrollbar is moved downwards.
|
|
2568
|
-
* ```
|
|
2569
|
-
*/
|
|
2570
|
-
export type direction = 'Top' | 'Bottom';
|
|
2571
|
-
|
|
2572
|
-
/**
|
|
2573
|
-
* An interface that holds selected item.
|
|
2574
|
-
*/
|
|
2575
|
-
export interface SelectedItem {
|
|
2576
|
-
/**
|
|
2577
|
-
* It denotes the selected item text.
|
|
2578
|
-
*/
|
|
2579
|
-
text: string;
|
|
2580
|
-
|
|
2581
|
-
/**
|
|
2582
|
-
* It denotes the selected item list element.
|
|
2583
|
-
*
|
|
2584
|
-
*/
|
|
2585
|
-
item: HTMLElement | Element;
|
|
2586
|
-
|
|
2587
|
-
/**
|
|
2588
|
-
* It denotes the selected item dataSource JSON object.
|
|
2589
|
-
*
|
|
2590
|
-
* @isGenericType true
|
|
2591
|
-
*/
|
|
2592
|
-
data: { [key: string]: Object } | string[] | number[];
|
|
2593
|
-
|
|
2594
|
-
}
|
|
2595
|
-
|
|
2596
|
-
/**
|
|
2597
|
-
* An interface that holds selected collection.
|
|
2598
|
-
*/
|
|
2599
|
-
export interface SelectedCollection {
|
|
2600
|
-
/**
|
|
2601
|
-
* It denotes the selected item text data or collection.
|
|
2602
|
-
*/
|
|
2603
|
-
text: string | string[];
|
|
2604
|
-
|
|
2605
|
-
/**
|
|
2606
|
-
* It denotes the selected item list element or element collection.
|
|
2607
|
-
*/
|
|
2608
|
-
item: HTMLElement | Element[] | NodeList;
|
|
2609
|
-
|
|
2610
|
-
/**
|
|
2611
|
-
* It denotes the selected item dataSource JSON object or object collection.
|
|
2612
|
-
*
|
|
2613
|
-
* @isGenericType true
|
|
2614
|
-
*/
|
|
2615
|
-
data: { [key: string]: object } | { [key: string]: object }[] | string[] | number[];
|
|
2616
|
-
}
|
|
2617
|
-
|
|
2618
|
-
/**
|
|
2619
|
-
* An interface that holds UI selected item.
|
|
2620
|
-
*/
|
|
2621
|
-
export interface UISelectedItem {
|
|
2622
|
-
/**
|
|
2623
|
-
* It denotes the selected item text data or collection.
|
|
2624
|
-
*/
|
|
2625
|
-
text: string | number | string[] | number[];
|
|
2626
|
-
|
|
2627
|
-
/**
|
|
2628
|
-
* It denotes the selected item list element or element collection.
|
|
2629
|
-
*/
|
|
2630
|
-
item?: HTMLElement | Element[] | NodeList;
|
|
2631
|
-
|
|
2632
|
-
/**
|
|
2633
|
-
* It denotes the selected item dataSource JSON object or object collection.
|
|
2634
|
-
*
|
|
2635
|
-
* @isGenericType true
|
|
2636
|
-
*/
|
|
2637
|
-
data: { [key: string]: object } | { [key: string]: object }[] | string | number | string[] | number[];
|
|
2638
|
-
/**
|
|
2639
|
-
* It is used to denote the index of the selected element.
|
|
2640
|
-
*/
|
|
2641
|
-
index?: number | number[];
|
|
2642
|
-
/**
|
|
2643
|
-
* It is used to check whether the element is checked or not.
|
|
2644
|
-
*/
|
|
2645
|
-
isChecked?: boolean;
|
|
2646
|
-
}
|
|
2647
|
-
|
|
2648
|
-
/**
|
|
2649
|
-
* An interface that holds details of data and parent.
|
|
2650
|
-
*/
|
|
2651
|
-
export interface DataAndParent {
|
|
2652
|
-
/**
|
|
2653
|
-
* It denotes the selected item dataSource JSON object or object collection.
|
|
2654
|
-
*
|
|
2655
|
-
* @isGenericType true
|
|
2656
|
-
*/
|
|
2657
|
-
data: { [key: string]: object } | { [key: string]: object }[] | string[];
|
|
2658
|
-
/**
|
|
2659
|
-
* It denotes the selected item's parent id;
|
|
2660
|
-
*/
|
|
2661
|
-
parentId: string[];
|
|
2662
|
-
}
|
|
2663
|
-
|
|
2664
|
-
/**
|
|
2665
|
-
* An interface that holds nested list data.
|
|
2666
|
-
*/
|
|
2667
|
-
export interface NestedListData {
|
|
2668
|
-
/**
|
|
2669
|
-
* It denotes the selected item text data or collection.
|
|
2670
|
-
*/
|
|
2671
|
-
text: string | string[];
|
|
2672
|
-
/**
|
|
2673
|
-
* It denotes the selected item list element or element collection.
|
|
2674
|
-
*/
|
|
2675
|
-
item: HTMLElement | Element[] | NodeList;
|
|
2676
|
-
/**
|
|
2677
|
-
* It denotes the selected item dataSource JSON object with it's parent id.
|
|
2678
|
-
*/
|
|
2679
|
-
data: DataAndParent[];
|
|
2680
|
-
}
|
|
2681
|
-
|
|
2682
|
-
/**
|
|
2683
|
-
* An interface that holds selected event arguments
|
|
2684
|
-
*/
|
|
2685
|
-
export interface SelectEventArgs extends BaseEventArgs, SelectedItem {
|
|
2686
|
-
/**
|
|
2687
|
-
* Specifies that event has triggered by user interaction.
|
|
2688
|
-
*/
|
|
2689
|
-
isInteracted: boolean;
|
|
2690
|
-
/**
|
|
2691
|
-
* Specifies that event argument when event raised by other event.
|
|
2692
|
-
*/
|
|
2693
|
-
event: MouseEvent | KeyboardEvent;
|
|
2694
|
-
/**
|
|
2695
|
-
* It is used to denote the index of the selected element.
|
|
2696
|
-
*/
|
|
2697
|
-
index: number;
|
|
2698
|
-
/**
|
|
2699
|
-
* It is used to check whether the element is checked or not.
|
|
2700
|
-
*/
|
|
2701
|
-
isChecked?: boolean;
|
|
2702
|
-
/**
|
|
2703
|
-
* Cancels the item selection if the value is true
|
|
2704
|
-
*/
|
|
2705
|
-
cancel: boolean;
|
|
2706
|
-
}
|
|
2707
|
-
|
|
2708
|
-
/**
|
|
2709
|
-
* An interface that holds scrolled event arguments
|
|
2710
|
-
*/
|
|
2711
|
-
export interface ScrolledEventArgs {
|
|
2712
|
-
/**
|
|
2713
|
-
* Specifies the direction “Top” or “Bottom” in which the scrolling occurs.
|
|
2714
|
-
*/
|
|
2715
|
-
scrollDirection: direction;
|
|
2716
|
-
/**
|
|
2717
|
-
* Specifies the default scroll event arguments.
|
|
2718
|
-
*/
|
|
2719
|
-
originalEvent: Event;
|
|
2720
|
-
/**
|
|
2721
|
-
* Specifies the distance from the scrollbar to the top and bottom ends.
|
|
2722
|
-
*/
|
|
2723
|
-
distanceY: number;
|
|
2724
|
-
}
|
|
2725
|
-
|
|
2726
|
-
/**
|
|
2727
|
-
* An interface that holds item created event arguments
|
|
2728
|
-
*/
|
|
2729
|
-
export interface ItemCreatedArgs {
|
|
2730
|
-
curData: { [key: string]: object };
|
|
2731
|
-
dataSource: { [key: string]: object } | string[];
|
|
2732
|
-
fields: FieldsMapping;
|
|
2733
|
-
item: HTMLElement;
|
|
2734
|
-
options: ListBaseOptions;
|
|
2735
|
-
text: string;
|
|
2736
|
-
}
|
|
2737
|
-
|
|
2738
|
-
interface DataSource {
|
|
2739
|
-
[key: string]: object;
|
|
2740
|
-
}
|