@syncfusion/ej2-lists 23.1.36 → 23.1.42
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 +2 -2
- package/dist/ej2-lists.umd.min.js +2 -2
- package/dist/global/ej2-lists.min.js +2 -2
- package/dist/global/index.d.ts +2 -2
- package/dist/ts/common/list-base.ts +1286 -0
- package/dist/ts/component.ts +4 -0
- package/dist/ts/list-view/list-view.ts +2653 -0
- package/dist/ts/list-view/virtualization.ts +1187 -0
- package/dist/ts/sortable/sortable.ts +485 -0
- package/package.json +7 -7
|
@@ -0,0 +1,1286 @@
|
|
|
1
|
+
/* eslint-disable no-inner-declarations */
|
|
2
|
+
import { extend, merge, isNullOrUndefined, getValue } from '@syncfusion/ej2-base';
|
|
3
|
+
import { attributes, prepend, isVisible, append, addClass } from '@syncfusion/ej2-base';
|
|
4
|
+
import { compile } from '@syncfusion/ej2-base';
|
|
5
|
+
import { DataManager, Query } from '@syncfusion/ej2-data';
|
|
6
|
+
|
|
7
|
+
export let cssClass: ClassList = {
|
|
8
|
+
li: 'e-list-item',
|
|
9
|
+
ul: 'e-list-parent e-ul',
|
|
10
|
+
group: 'e-list-group-item',
|
|
11
|
+
icon: 'e-list-icon',
|
|
12
|
+
text: 'e-list-text',
|
|
13
|
+
check: 'e-list-check',
|
|
14
|
+
checked: 'e-checked',
|
|
15
|
+
selected: 'e-selected',
|
|
16
|
+
expanded: 'e-expanded',
|
|
17
|
+
textContent: 'e-text-content',
|
|
18
|
+
hasChild: 'e-has-child',
|
|
19
|
+
level: 'e-level',
|
|
20
|
+
url: 'e-list-url',
|
|
21
|
+
collapsible: 'e-icon-collapsible',
|
|
22
|
+
disabled: 'e-disabled',
|
|
23
|
+
image: 'e-list-img',
|
|
24
|
+
iconWrapper: 'e-icon-wrapper',
|
|
25
|
+
anchorWrap: 'e-anchor-wrap',
|
|
26
|
+
navigable: 'e-navigable'
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* An interface that holds item class list
|
|
31
|
+
*/
|
|
32
|
+
export interface ClassList {
|
|
33
|
+
li: string;
|
|
34
|
+
ul: string;
|
|
35
|
+
group: string;
|
|
36
|
+
icon: string;
|
|
37
|
+
text: string;
|
|
38
|
+
check: string;
|
|
39
|
+
checked: string;
|
|
40
|
+
selected: string;
|
|
41
|
+
expanded: string;
|
|
42
|
+
textContent: string;
|
|
43
|
+
hasChild: string;
|
|
44
|
+
level: string;
|
|
45
|
+
url: string;
|
|
46
|
+
collapsible: string;
|
|
47
|
+
disabled: string;
|
|
48
|
+
image: string;
|
|
49
|
+
iconWrapper: string;
|
|
50
|
+
anchorWrap: string;
|
|
51
|
+
navigable: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Sorting Order
|
|
57
|
+
*/
|
|
58
|
+
export type SortOrder = 'None' | 'Ascending' | 'Descending';
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Base List Generator
|
|
62
|
+
*/
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
64
|
+
export namespace ListBase {
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
*
|
|
68
|
+
* Default mapped fields.
|
|
69
|
+
*/
|
|
70
|
+
export const defaultMappedFields: FieldsMapping = {
|
|
71
|
+
id: 'id',
|
|
72
|
+
text: 'text',
|
|
73
|
+
url: 'url',
|
|
74
|
+
value: 'value',
|
|
75
|
+
isChecked: 'isChecked',
|
|
76
|
+
enabled: 'enabled',
|
|
77
|
+
expanded: 'expanded',
|
|
78
|
+
selected: 'selected',
|
|
79
|
+
iconCss: 'iconCss',
|
|
80
|
+
child: 'child',
|
|
81
|
+
isVisible: 'isVisible',
|
|
82
|
+
hasChildren: 'hasChildren',
|
|
83
|
+
tooltip: 'tooltip',
|
|
84
|
+
htmlAttributes: 'htmlAttributes',
|
|
85
|
+
urlAttributes: 'urlAttributes',
|
|
86
|
+
imageAttributes: 'imageAttributes',
|
|
87
|
+
imageUrl: 'imageUrl',
|
|
88
|
+
groupBy: null,
|
|
89
|
+
sortBy: null
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const defaultAriaAttributes: AriaAttributesMapping = {
|
|
93
|
+
level: 1,
|
|
94
|
+
listRole: 'presentation',
|
|
95
|
+
itemRole: 'presentation',
|
|
96
|
+
groupItemRole: 'group',
|
|
97
|
+
itemText: 'list-item',
|
|
98
|
+
wrapperRole: 'presentation'
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const defaultListBaseOptions: ListBaseOptions = {
|
|
102
|
+
showCheckBox: false,
|
|
103
|
+
showIcon: false,
|
|
104
|
+
enableHtmlSanitizer: false,
|
|
105
|
+
expandCollapse: false,
|
|
106
|
+
fields: defaultMappedFields,
|
|
107
|
+
ariaAttributes: defaultAriaAttributes,
|
|
108
|
+
listClass: '',
|
|
109
|
+
itemClass: '',
|
|
110
|
+
processSubChild: false,
|
|
111
|
+
sortOrder: 'None',
|
|
112
|
+
template: null,
|
|
113
|
+
groupTemplate: null,
|
|
114
|
+
headerTemplate: null,
|
|
115
|
+
expandIconClass: 'e-icon-collapsible',
|
|
116
|
+
moduleName: 'list',
|
|
117
|
+
expandIconPosition: 'Right',
|
|
118
|
+
itemNavigable: false
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Function helps to created and return the UL Li element based on your data.
|
|
123
|
+
*
|
|
124
|
+
* @param {createElementParams} createElement - Specifies an array of JSON data.
|
|
125
|
+
*
|
|
126
|
+
* @param {{Object}[]} dataSource - Specifies an array of JSON data.
|
|
127
|
+
*
|
|
128
|
+
* @param {ListBaseOptions} options? - Specifies the list options that need to provide.
|
|
129
|
+
*
|
|
130
|
+
* @param {boolean} isSingleLevel? - Specifies the list options that need to provide.
|
|
131
|
+
*
|
|
132
|
+
* @param {any} componentInstance? - Specifies the list options that need to provide.
|
|
133
|
+
*
|
|
134
|
+
* @returns {createElement} createListFromJson - Specifies the list options that need to provide.
|
|
135
|
+
*/
|
|
136
|
+
|
|
137
|
+
export function createList(
|
|
138
|
+
createElement: createElementParams, dataSource: { [key: string]: Object }[] | string[] | number[],
|
|
139
|
+
// eslint-disable-next-line
|
|
140
|
+
options?: ListBaseOptions, isSingleLevel?: boolean, componentInstance?: any):
|
|
141
|
+
HTMLElement {
|
|
142
|
+
const curOpt: ListBaseOptions = extend({}, defaultListBaseOptions, options);
|
|
143
|
+
const ariaAttributes: AriaAttributesMapping = extend({}, defaultAriaAttributes, curOpt.ariaAttributes);
|
|
144
|
+
const type: string = typeofData(dataSource).typeof as string;
|
|
145
|
+
if (type === 'string' || type === 'number') {
|
|
146
|
+
return createListFromArray(createElement, <string[] | number[]>dataSource, isSingleLevel, options, componentInstance);
|
|
147
|
+
} else {
|
|
148
|
+
return createListFromJson(createElement, <{ [key: string]: Object }[]>dataSource, options,
|
|
149
|
+
ariaAttributes.level, isSingleLevel, componentInstance);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Function helps to created an element list based on string array input .
|
|
155
|
+
*
|
|
156
|
+
* @param {createElementParams} createElement - Specifies an array of JSON data.
|
|
157
|
+
*
|
|
158
|
+
* @param {{Object}[]} dataSource - Specifies an array of JSON data.
|
|
159
|
+
*
|
|
160
|
+
* @param {ListBaseOptions} options? - Specifies the list options that need to provide.
|
|
161
|
+
*
|
|
162
|
+
* @param {boolean} isSingleLevel? - Specifies the list options that need to provide.
|
|
163
|
+
*
|
|
164
|
+
* @param {any} componentInstance? - Specifies the list options that need to provide.
|
|
165
|
+
*
|
|
166
|
+
* @returns {createElement} generateUL - returns the list options that need to provide.
|
|
167
|
+
*/
|
|
168
|
+
|
|
169
|
+
export function createListFromArray(
|
|
170
|
+
createElement: createElementParams, dataSource: string[] | number[],
|
|
171
|
+
// tslint:disable-next-line
|
|
172
|
+
// eslint-disable-next-line
|
|
173
|
+
isSingleLevel?: boolean, options?: ListBaseOptions, componentInstance?: any): HTMLElement {
|
|
174
|
+
const subChild: HTMLElement[] = createListItemFromArray(createElement, dataSource, isSingleLevel, options, componentInstance);
|
|
175
|
+
return generateUL(createElement, subChild, null, options);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Function helps to created an element list based on string array input .
|
|
179
|
+
*
|
|
180
|
+
* @param {createElementParams} createElement - Specifies an array of JSON data.
|
|
181
|
+
*
|
|
182
|
+
* @param {{Object}[]} dataSource - Specifies an array of JSON data.
|
|
183
|
+
*
|
|
184
|
+
* @param {ListBaseOptions} options? - Specifies the list options that need to provide.
|
|
185
|
+
*
|
|
186
|
+
* @param {boolean} isSingleLevel? - Specifies the list options that need to provide.
|
|
187
|
+
*
|
|
188
|
+
* @param {any} componentInstance? - Specifies the list options that need to provide.
|
|
189
|
+
*
|
|
190
|
+
* @returns {HTMLElement[]} subChild - returns the list options that need to provide.
|
|
191
|
+
*/
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
export function createListItemFromArray(
|
|
195
|
+
createElement: createElementParams, dataSource: string[] | number[],
|
|
196
|
+
// eslint-disable-next-line
|
|
197
|
+
isSingleLevel?: boolean, options?: ListBaseOptions, componentInstance?: any): HTMLElement[] {
|
|
198
|
+
const subChild: HTMLElement[] = [];
|
|
199
|
+
const curOpt: ListBaseOptions = extend({}, defaultListBaseOptions, options);
|
|
200
|
+
cssClass = getModuleClass(curOpt.moduleName);
|
|
201
|
+
const id: string = generateId(); // generate id for drop-down-list option.
|
|
202
|
+
for (let i: number = 0; i < dataSource.length; i++) {
|
|
203
|
+
if (isNullOrUndefined(dataSource[i as number])) {
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
let li: HTMLElement;
|
|
207
|
+
if (curOpt.itemCreating && typeof curOpt.itemCreating === 'function') {
|
|
208
|
+
const curData: object = {
|
|
209
|
+
dataSource: dataSource,
|
|
210
|
+
curData: dataSource[i as number],
|
|
211
|
+
text: dataSource[i as number],
|
|
212
|
+
options: curOpt
|
|
213
|
+
};
|
|
214
|
+
curOpt.itemCreating(curData);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (isSingleLevel) {
|
|
218
|
+
li = generateSingleLevelLI(createElement, dataSource[i as number], undefined, null, null, [], null, id, i, options);
|
|
219
|
+
} else {
|
|
220
|
+
li = generateLI(createElement, dataSource[i as number], undefined, null, null, options, componentInstance);
|
|
221
|
+
}
|
|
222
|
+
if (curOpt.itemCreated && typeof curOpt.itemCreated === 'function') {
|
|
223
|
+
const curData: Object = {
|
|
224
|
+
dataSource: dataSource,
|
|
225
|
+
curData: dataSource[i as number],
|
|
226
|
+
text: dataSource[i as number],
|
|
227
|
+
item: li,
|
|
228
|
+
options: curOpt
|
|
229
|
+
};
|
|
230
|
+
curOpt.itemCreated(curData);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
subChild.push(li);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return subChild;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Function helps to created an element list based on array of JSON input .
|
|
241
|
+
*
|
|
242
|
+
* @param {createElementParams} createElement - Specifies an array of JSON data.
|
|
243
|
+
*
|
|
244
|
+
* @param {{Object}[]} dataSource - Specifies an array of JSON data.
|
|
245
|
+
*
|
|
246
|
+
* @param {ListBaseOptions} options? - Specifies the list options that need to provide.
|
|
247
|
+
*
|
|
248
|
+
* @param {boolean} isSingleLevel? - Specifies the list options that need to provide.
|
|
249
|
+
*
|
|
250
|
+
* @param {number} level? - Specifies the list options that need to provide.
|
|
251
|
+
*
|
|
252
|
+
* @param {any} componentInstance? - Specifies the list options that need to provide.
|
|
253
|
+
*
|
|
254
|
+
* @returns {HTMLElement[]} child - returns the list options that need to provide.
|
|
255
|
+
*/
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
export function createListItemFromJson(
|
|
259
|
+
createElement: createElementParams, dataSource: { [key: string]: Object }[],
|
|
260
|
+
// eslint-disable-next-line
|
|
261
|
+
options?: ListBaseOptions, level?: number, isSingleLevel?: boolean, componentInstance?: any): HTMLElement[] {
|
|
262
|
+
const curOpt: ListBaseOptions = extend({}, defaultListBaseOptions, options);
|
|
263
|
+
cssClass = getModuleClass(curOpt.moduleName);
|
|
264
|
+
const fields: FieldsMapping = (componentInstance &&
|
|
265
|
+
(componentInstance.getModuleName() === 'listview' || componentInstance.getModuleName() === 'multiselect'))
|
|
266
|
+
? curOpt.fields : extend({}, defaultMappedFields, curOpt.fields);
|
|
267
|
+
const ariaAttributes: AriaAttributesMapping = extend({}, defaultAriaAttributes, curOpt.ariaAttributes);
|
|
268
|
+
let id: string;
|
|
269
|
+
let checkboxElement: HTMLElement[] = [];
|
|
270
|
+
if (level) {
|
|
271
|
+
ariaAttributes.level = level;
|
|
272
|
+
}
|
|
273
|
+
const child: HTMLElement[] = [];
|
|
274
|
+
let li: HTMLElement;
|
|
275
|
+
let anchorElement: HTMLElement;
|
|
276
|
+
if (dataSource && dataSource.length && !isNullOrUndefined(typeofData(dataSource).item) &&
|
|
277
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
278
|
+
!typeofData(dataSource).item.hasOwnProperty(fields.id)) {
|
|
279
|
+
id = generateId(); // generate id for drop-down-list option.
|
|
280
|
+
}
|
|
281
|
+
for (let i: number = 0; i < dataSource.length; i++) {
|
|
282
|
+
let fieldData: { [key: string]: Object } = <{ [key: string]: Object }>getFieldValues(dataSource[i as number], fields);
|
|
283
|
+
if (isNullOrUndefined(dataSource[i as number])) { continue; }
|
|
284
|
+
if (curOpt.itemCreating && typeof curOpt.itemCreating === 'function') {
|
|
285
|
+
const curData: { [key: string]: object | string } = {
|
|
286
|
+
dataSource: dataSource,
|
|
287
|
+
curData: dataSource[i as number],
|
|
288
|
+
text: fieldData[fields.text],
|
|
289
|
+
options: curOpt,
|
|
290
|
+
fields: fields
|
|
291
|
+
};
|
|
292
|
+
curOpt.itemCreating(curData);
|
|
293
|
+
}
|
|
294
|
+
const curItem: { [key: string]: Object } = dataSource[i as number];
|
|
295
|
+
if (curOpt.itemCreating && typeof curOpt.itemCreating === 'function') {
|
|
296
|
+
fieldData = <{ [key: string]: Object }>getFieldValues(dataSource[i as number], fields);
|
|
297
|
+
}
|
|
298
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
299
|
+
if (fieldData.hasOwnProperty(fields.id) && !isNullOrUndefined(fieldData[fields.id])) {
|
|
300
|
+
id = <string>fieldData[fields.id];
|
|
301
|
+
}
|
|
302
|
+
const innerEle: HTMLElement[] = [];
|
|
303
|
+
if (curOpt.showCheckBox) {
|
|
304
|
+
if (curOpt.itemNavigable && (fieldData[fields.url] || fieldData[fields.urlAttributes])) {
|
|
305
|
+
checkboxElement.push(createElement('input', { className: cssClass.check, attrs: { type: 'checkbox' } }));
|
|
306
|
+
} else {
|
|
307
|
+
innerEle.push(createElement('input', { className: cssClass.check, attrs: { type: 'checkbox' } }));
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
if (isSingleLevel === true) {
|
|
311
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
312
|
+
if (curOpt.showIcon && fieldData.hasOwnProperty(fields.iconCss) && !isNullOrUndefined(fieldData[fields.iconCss])) {
|
|
313
|
+
innerEle.push(createElement('span', { className: cssClass.icon + ' ' + <string>fieldData[fields.iconCss] }));
|
|
314
|
+
}
|
|
315
|
+
li = generateSingleLevelLI(
|
|
316
|
+
createElement,
|
|
317
|
+
curItem,
|
|
318
|
+
fieldData,
|
|
319
|
+
fields,
|
|
320
|
+
curOpt.itemClass,
|
|
321
|
+
innerEle,
|
|
322
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
323
|
+
(curItem.hasOwnProperty('isHeader') &&
|
|
324
|
+
(curItem as { isHeader: Object } & { [key: string]: Object }).isHeader) ? true : false,
|
|
325
|
+
id,
|
|
326
|
+
i, options);
|
|
327
|
+
anchorElement = li.querySelector('.' + cssClass.anchorWrap);
|
|
328
|
+
if (curOpt.itemNavigable && checkboxElement.length) {
|
|
329
|
+
prepend(checkboxElement, li.firstElementChild);
|
|
330
|
+
}
|
|
331
|
+
} else {
|
|
332
|
+
li = generateLI(createElement, curItem, fieldData, fields, curOpt.itemClass, options, componentInstance);
|
|
333
|
+
li.classList.add(cssClass.level + '-' + ariaAttributes.level);
|
|
334
|
+
li.setAttribute('aria-level', ariaAttributes.level.toString());
|
|
335
|
+
if(ariaAttributes.groupItemRole =='presentation'){
|
|
336
|
+
li.removeAttribute('aria-level');
|
|
337
|
+
}
|
|
338
|
+
anchorElement = li.querySelector('.' + cssClass.anchorWrap);
|
|
339
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
340
|
+
if (fieldData.hasOwnProperty(fields.tooltip)) {
|
|
341
|
+
li.setAttribute('title', <string>fieldData[fields.tooltip]);
|
|
342
|
+
}
|
|
343
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
344
|
+
if (fieldData.hasOwnProperty(fields.htmlAttributes) && fieldData[fields.htmlAttributes]) {
|
|
345
|
+
setAttribute(li, <{ [key: string]: string }>fieldData[fields.htmlAttributes]);
|
|
346
|
+
}
|
|
347
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
348
|
+
if (fieldData.hasOwnProperty(fields.enabled) && fieldData[fields.enabled] === false) {
|
|
349
|
+
li.classList.add(cssClass.disabled);
|
|
350
|
+
}
|
|
351
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
352
|
+
if (fieldData.hasOwnProperty(fields.isVisible) && fieldData[fields.isVisible] === false) {
|
|
353
|
+
li.style.display = 'none';
|
|
354
|
+
}
|
|
355
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
356
|
+
if (fieldData.hasOwnProperty(fields.imageUrl) && !isNullOrUndefined(fieldData[fields.imageUrl])
|
|
357
|
+
&& !curOpt.template) {
|
|
358
|
+
const attr: { [key: string]: string } = { src: <string>fieldData[fields.imageUrl] };
|
|
359
|
+
merge(attr, fieldData[fields.imageAttributes]);
|
|
360
|
+
const imageElemnt: HTMLElement = createElement('img', { className: cssClass.image, attrs: attr });
|
|
361
|
+
if (anchorElement) {
|
|
362
|
+
anchorElement.insertAdjacentElement('afterbegin', imageElemnt);
|
|
363
|
+
} else {
|
|
364
|
+
prepend([imageElemnt], li.firstElementChild);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
368
|
+
if (curOpt.showIcon && fieldData.hasOwnProperty(fields.iconCss) &&
|
|
369
|
+
!isNullOrUndefined(fieldData[fields.iconCss]) && !curOpt.template) {
|
|
370
|
+
const iconElement: HTMLElement = createElement('div', { className: cssClass.icon + ' ' + <string>fieldData[fields.iconCss] });
|
|
371
|
+
if (anchorElement) {
|
|
372
|
+
anchorElement.insertAdjacentElement('afterbegin', iconElement);
|
|
373
|
+
} else {
|
|
374
|
+
prepend([iconElement], li.firstElementChild);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
if (innerEle.length) {
|
|
378
|
+
prepend(innerEle, li.firstElementChild);
|
|
379
|
+
}
|
|
380
|
+
if (curOpt.itemNavigable && checkboxElement.length) {
|
|
381
|
+
prepend(checkboxElement, li.firstElementChild);
|
|
382
|
+
}
|
|
383
|
+
processSubChild(createElement, fieldData, fields, dataSource, curOpt, li, ariaAttributes.level);
|
|
384
|
+
}
|
|
385
|
+
if (anchorElement) {
|
|
386
|
+
addClass([li], [cssClass.navigable]);
|
|
387
|
+
}
|
|
388
|
+
if (curOpt.itemCreated && typeof curOpt.itemCreated === 'function') {
|
|
389
|
+
const curData: { [key: string]: object | string } = {
|
|
390
|
+
dataSource: dataSource,
|
|
391
|
+
curData: dataSource[i as number],
|
|
392
|
+
text: fieldData[fields.text],
|
|
393
|
+
item: li,
|
|
394
|
+
options: curOpt,
|
|
395
|
+
fields: fields
|
|
396
|
+
};
|
|
397
|
+
curOpt.itemCreated(curData);
|
|
398
|
+
}
|
|
399
|
+
checkboxElement = [];
|
|
400
|
+
child.push(li);
|
|
401
|
+
}
|
|
402
|
+
return child;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Function helps to created an element list based on array of JSON input .
|
|
407
|
+
*
|
|
408
|
+
* @param {createElementParams} createElement - Specifies an array of JSON data.
|
|
409
|
+
*
|
|
410
|
+
* @param {{Object}[]} dataSource - Specifies an array of JSON data.
|
|
411
|
+
*
|
|
412
|
+
* @param {ListBaseOptions} options? - Specifies the list options that need to provide.
|
|
413
|
+
*
|
|
414
|
+
* @param {number} level? - Specifies the list options that need to provide.
|
|
415
|
+
*
|
|
416
|
+
* @param {boolean} isSingleLevel? - Specifies the list options that need to provide.
|
|
417
|
+
*
|
|
418
|
+
* @param {any} componentInstance? - Specifies the list options that need to provide.
|
|
419
|
+
*
|
|
420
|
+
* @returns {createElement} generateUL - Specifies the list options that need to provide.
|
|
421
|
+
*/
|
|
422
|
+
|
|
423
|
+
export function createListFromJson(
|
|
424
|
+
createElement: createElementParams, dataSource: { [key: string]: Object }[],
|
|
425
|
+
// eslint-disable-next-line
|
|
426
|
+
options?: ListBaseOptions, level?: number, isSingleLevel?: boolean, componentInstance?: any): HTMLElement {
|
|
427
|
+
const curOpt: ListBaseOptions = extend({}, defaultListBaseOptions, options);
|
|
428
|
+
const li: HTMLElement[] = createListItemFromJson(createElement, dataSource, options, level, isSingleLevel, componentInstance);
|
|
429
|
+
return generateUL(createElement, li, curOpt.listClass, options);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Return the next or previous visible element.
|
|
435
|
+
*
|
|
436
|
+
* @param {Element[]|NodeList} elementArray - An element array to find next or previous element.
|
|
437
|
+
* @param {Element} li - An element to find next or previous after this element.
|
|
438
|
+
* @param {boolean} isPrevious? - Specify when the need get previous element from array.
|
|
439
|
+
*/
|
|
440
|
+
|
|
441
|
+
export function getSiblingLI(elementArray: Element[] | NodeList, element: Element, isPrevious?: boolean): Element {
|
|
442
|
+
|
|
443
|
+
cssClass = getModuleClass(defaultListBaseOptions.moduleName);
|
|
444
|
+
if (!elementArray || !elementArray.length) { return void 0; }
|
|
445
|
+
let siblingLI: Element;
|
|
446
|
+
let liIndex: number;
|
|
447
|
+
const liCollections: Element[] = Array.prototype.slice.call(elementArray);
|
|
448
|
+
if (element) {
|
|
449
|
+
liIndex = indexOf(element, liCollections);
|
|
450
|
+
} else {
|
|
451
|
+
liIndex = (isPrevious === true ? liCollections.length : -1);
|
|
452
|
+
}
|
|
453
|
+
siblingLI = liCollections[liIndex + (isPrevious === true ? -1 : 1)];
|
|
454
|
+
while (siblingLI && (!isVisible(siblingLI) || siblingLI.classList.contains(cssClass.disabled))) {
|
|
455
|
+
liIndex = liIndex + (isPrevious === true ? -1 : 1);
|
|
456
|
+
siblingLI = liCollections[liIndex as number];
|
|
457
|
+
}
|
|
458
|
+
return siblingLI;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Return the index of the li element
|
|
463
|
+
*
|
|
464
|
+
* @param {Element} item - An element to find next or previous after this element.
|
|
465
|
+
* @param {Element[]} elementArray - An element array to find index of given li.
|
|
466
|
+
*/
|
|
467
|
+
|
|
468
|
+
export function indexOf(item: Element, elementArray: Element[] | NodeList): number {
|
|
469
|
+
if (!elementArray || !item) { return void 0; } else {
|
|
470
|
+
let liCollections: Element[] = <Element[]>elementArray;
|
|
471
|
+
liCollections = Array.prototype.slice.call(elementArray);
|
|
472
|
+
return liCollections.indexOf(item);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Returns the grouped data from given dataSource.
|
|
479
|
+
*
|
|
480
|
+
* @param {{Object}[]} dataSource - The JSON data which is necessary to process.
|
|
481
|
+
* @param {FieldsMapping} fields - Fields that are mapped from the data source.
|
|
482
|
+
* @param {SortOrder} sortOrder- Specifies final result sort order.
|
|
483
|
+
*/
|
|
484
|
+
|
|
485
|
+
export function groupDataSource(
|
|
486
|
+
dataSource: { [key: string]: Object }[],
|
|
487
|
+
fields: FieldsMapping,
|
|
488
|
+
sortOrder: SortOrder = 'None'): { [key: string]: Object }[] {
|
|
489
|
+
const curFields: FieldsMapping = extend({}, defaultMappedFields, fields);
|
|
490
|
+
let cusQuery: Query = new Query().group(curFields.groupBy);
|
|
491
|
+
|
|
492
|
+
// need to remove once sorting issues fixed in DataManager
|
|
493
|
+
cusQuery = addSorting(sortOrder, 'key', cusQuery);
|
|
494
|
+
|
|
495
|
+
const ds: { [key: string]: Object }[] = getDataSource(dataSource, cusQuery);
|
|
496
|
+
dataSource = [];
|
|
497
|
+
|
|
498
|
+
for (let j: number = 0; j < ds.length; j++) {
|
|
499
|
+
const itemObj: { [key: string]: Object }[]
|
|
500
|
+
= (ds[j as number] as { items: { [key: string]: Object }[] } & { [key: string]: Object }).items;
|
|
501
|
+
const grpItem: { [key: string]: Object } = {};
|
|
502
|
+
const hdr: string = 'isHeader';
|
|
503
|
+
grpItem[curFields.text] = (ds[j as number] as { key: string } & { [key: string]: Object }).key;
|
|
504
|
+
grpItem[`${hdr}`] = true;
|
|
505
|
+
let newtext: string = curFields.text;
|
|
506
|
+
if (newtext === 'id') {
|
|
507
|
+
newtext = 'text';
|
|
508
|
+
grpItem[`${newtext}`] = ds[j as number].key;
|
|
509
|
+
}
|
|
510
|
+
grpItem._id = 'group-list-item-' + ((ds[j as number] as { [key: string]: Object }).key ?
|
|
511
|
+
(ds[j as number] as { [key: string]: Object }).key.toString().trim() : 'undefined');
|
|
512
|
+
grpItem.items = itemObj;
|
|
513
|
+
dataSource.push(grpItem);
|
|
514
|
+
for (let k: number = 0; k < itemObj.length; k++) {
|
|
515
|
+
dataSource.push(itemObj[k as number]);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
return dataSource;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Returns a sorted query object.
|
|
523
|
+
*
|
|
524
|
+
* @param {SortOrder} sortOrder - Specifies that sort order.
|
|
525
|
+
* @param {string} sortBy - Specifies sortBy fields.
|
|
526
|
+
* @param {Query} query - Pass if any existing query.
|
|
527
|
+
*/
|
|
528
|
+
|
|
529
|
+
export function addSorting(sortOrder: SortOrder, sortBy: string, query: Query = new Query()): Query {
|
|
530
|
+
if (sortOrder === 'Ascending') {
|
|
531
|
+
query.sortBy(sortBy, 'ascending', true);
|
|
532
|
+
} else if (sortOrder === 'Descending') {
|
|
533
|
+
query.sortBy(sortBy, 'descending', true);
|
|
534
|
+
} else {
|
|
535
|
+
for (let i: number = 0; i < query.queries.length; i++) {
|
|
536
|
+
if (query.queries[i as number].fn === 'onSortBy') {
|
|
537
|
+
query.queries.splice(i, 1);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
return query;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Return an array of JSON Data that processed based on queries.
|
|
547
|
+
*
|
|
548
|
+
* @param {{Object}[]} dataSource - Specifies local JSON data source.
|
|
549
|
+
*
|
|
550
|
+
* @param {Query} query - Specifies query that need to process.
|
|
551
|
+
*/
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
export function getDataSource(dataSource: { [key: string]: Object }[], query: Query): { [key: string]: Object }[] {
|
|
555
|
+
// eslint-disable-next-line
|
|
556
|
+
return <{ [key: string]: Object }[]>new DataManager(<any[]>dataSource)
|
|
557
|
+
.executeLocal(query);
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Created JSON data based the UL and LI element
|
|
561
|
+
*
|
|
562
|
+
* @param {HTMLElement|Element} element - UL element that need to convert as a JSON
|
|
563
|
+
* @param {ListBaseOptions} options? - Specifies listbase option for fields.
|
|
564
|
+
*/
|
|
565
|
+
|
|
566
|
+
export function createJsonFromElement(
|
|
567
|
+
element: HTMLElement | Element, options?: ListBaseOptions): { [key: string]: Object }[] {
|
|
568
|
+
|
|
569
|
+
const curOpt: ListBaseOptions = extend({}, defaultListBaseOptions, options);
|
|
570
|
+
const fields: FieldsMapping = extend({}, defaultMappedFields, curOpt.fields);
|
|
571
|
+
const curEle: HTMLElement = <HTMLElement>element.cloneNode(true);
|
|
572
|
+
// eslint-disable-next-line
|
|
573
|
+
const jsonAr: { [key: string]: {} }[] = [];
|
|
574
|
+
|
|
575
|
+
curEle.classList.add('json-parent');
|
|
576
|
+
const childs: HTMLElement[] = <HTMLElement[] & NodeListOf<HTMLElement>>curEle.querySelectorAll('.json-parent>li');
|
|
577
|
+
curEle.classList.remove('json-parent');
|
|
578
|
+
|
|
579
|
+
for (let i: number = 0; i < childs.length; i++) {
|
|
580
|
+
const li: HTMLElement = childs[i as number];
|
|
581
|
+
const anchor: HTMLElement = li.querySelector('a');
|
|
582
|
+
const ul: Element = li.querySelector('ul');
|
|
583
|
+
// eslint-disable-next-line
|
|
584
|
+
const json: { [key: string]: {} } = {};
|
|
585
|
+
const childNodes: NodeList = anchor ? anchor.childNodes : li.childNodes;
|
|
586
|
+
const keys: string[] = Object.keys(childNodes);
|
|
587
|
+
for (let i: number = 0; i < childNodes.length; i++) {
|
|
588
|
+
if (!(childNodes[Number(keys[i as number])]).hasChildNodes()) {
|
|
589
|
+
json[fields.text] = childNodes[Number(keys[i as number])].textContent;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
let attributes: { [key: string]: string } = getAllAttributes(li);
|
|
593
|
+
if (attributes.id) {
|
|
594
|
+
json[fields.id] = attributes.id;
|
|
595
|
+
delete attributes.id;
|
|
596
|
+
} else {
|
|
597
|
+
json[fields.id] = generateId();
|
|
598
|
+
}
|
|
599
|
+
if (Object.keys(attributes).length) {
|
|
600
|
+
json[fields.htmlAttributes] = attributes;
|
|
601
|
+
}
|
|
602
|
+
if (anchor) {
|
|
603
|
+
attributes = getAllAttributes(anchor);
|
|
604
|
+
if (Object.keys(attributes).length) {
|
|
605
|
+
json[fields.urlAttributes] = attributes;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
if (ul) {
|
|
609
|
+
json[fields.child] = createJsonFromElement(ul, options);
|
|
610
|
+
}
|
|
611
|
+
jsonAr.push(json);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
return jsonAr;
|
|
615
|
+
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
function typeofData(data: { [key: string]: Object }[] | string[] | number[]): { [key: string]: Object } {
|
|
619
|
+
let match: { [key: string]: Object } = <{ [key: string]: Object }>{ typeof: null, item: null };
|
|
620
|
+
for (let i: number = 0; i < data.length; i++) {
|
|
621
|
+
if (!isNullOrUndefined(data[i as number])) {
|
|
622
|
+
return match = { typeof: typeof data[i as number], item: data[i as number] };
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
return match;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
function setAttribute(element: HTMLElement, elementAttributes: { [key: string]: string }): void {
|
|
629
|
+
const attr: { [key: string]: string } = {};
|
|
630
|
+
merge(attr, elementAttributes);
|
|
631
|
+
if (attr.class) {
|
|
632
|
+
addClass([element], attr.class.split(' '));
|
|
633
|
+
delete attr.class;
|
|
634
|
+
}
|
|
635
|
+
attributes(element, attr);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
function getAllAttributes(element: HTMLElement): { [key: string]: string } {
|
|
639
|
+
const attributes: { [key: string]: string } = {};
|
|
640
|
+
const attr: NamedNodeMap = element.attributes;
|
|
641
|
+
for (let index: number = 0; index < attr.length; index++) {
|
|
642
|
+
attributes[attr[index as number].nodeName] = attr[index as number].nodeValue;
|
|
643
|
+
}
|
|
644
|
+
return attributes;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* Created UL element from content template.
|
|
650
|
+
*
|
|
651
|
+
* @param {string} template - that need to convert and generate li element.
|
|
652
|
+
* @param {{Object}[]} dataSource - Specifies local JSON data source.
|
|
653
|
+
* @param {ListBaseOptions} options? - Specifies listbase option for fields.
|
|
654
|
+
*/
|
|
655
|
+
|
|
656
|
+
export function renderContentTemplate(
|
|
657
|
+
createElement: createElementParams, template: string | Function, dataSource: { [key: string]: Object }[] | string[] | number[],
|
|
658
|
+
// eslint-disable-next-line
|
|
659
|
+
fields?: FieldsMapping, options?: ListBaseOptions, componentInstance?: any): HTMLElement {
|
|
660
|
+
cssClass = getModuleClass(defaultListBaseOptions.moduleName);
|
|
661
|
+
const ulElement: HTMLElement = createElement('ul', { className: cssClass.ul, attrs: { role: 'presentation' } });
|
|
662
|
+
const curOpt: ListBaseOptions = extend({}, defaultListBaseOptions, options);
|
|
663
|
+
const curFields: FieldsMapping = extend({}, defaultMappedFields, fields);
|
|
664
|
+
// eslint-disable-next-line
|
|
665
|
+
const compiledString: Function = compileTemplate(template);
|
|
666
|
+
const liCollection: HTMLElement[] = [];
|
|
667
|
+
let value: string;
|
|
668
|
+
const id: string = generateId(); // generate id for drop-down-list option.
|
|
669
|
+
for (let i: number = 0; i < dataSource.length; i++) {
|
|
670
|
+
let fieldData: { [key: string]: Object } = <{ [key: string]: Object }>getFieldValues(dataSource[i as number], curFields);
|
|
671
|
+
const curItem: { [key: string]: Object } | string | number = dataSource[i as number];
|
|
672
|
+
const isHeader: Object = (curItem as { isHeader: Object } & { [key: string]: Object }).isHeader;
|
|
673
|
+
if (typeof dataSource[i as number] === 'string' || typeof dataSource[i as number] === 'number') {
|
|
674
|
+
value = curItem as string;
|
|
675
|
+
} else {
|
|
676
|
+
value = fieldData[curFields.value] as string;
|
|
677
|
+
}
|
|
678
|
+
if (curOpt.itemCreating && typeof curOpt.itemCreating === 'function') {
|
|
679
|
+
const curData: object = {
|
|
680
|
+
dataSource: dataSource,
|
|
681
|
+
curData: curItem,
|
|
682
|
+
text: value,
|
|
683
|
+
options: curOpt,
|
|
684
|
+
fields: curFields
|
|
685
|
+
};
|
|
686
|
+
curOpt.itemCreating(curData);
|
|
687
|
+
}
|
|
688
|
+
if (curOpt.itemCreating && typeof curOpt.itemCreating === 'function') {
|
|
689
|
+
fieldData = <{ [key: string]: Object }>getFieldValues(dataSource[i as number], curFields);
|
|
690
|
+
if (typeof dataSource[i as number] === 'string' || typeof dataSource[i as number] === 'number') {
|
|
691
|
+
value = curItem as string;
|
|
692
|
+
} else {
|
|
693
|
+
value = fieldData[curFields.value] as string;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
const li: HTMLElement = createElement('li', {
|
|
697
|
+
id: id + '-' + i,
|
|
698
|
+
className: isHeader ? cssClass.group : cssClass.li, attrs: { role: 'presentation' }
|
|
699
|
+
});
|
|
700
|
+
if (isHeader) {
|
|
701
|
+
if (typeof dataSource[i as number] === 'string' || typeof dataSource[i as number] === 'number') {
|
|
702
|
+
li.innerText = curItem as string;
|
|
703
|
+
} else {
|
|
704
|
+
li.innerText = fieldData[curFields.text] as string;
|
|
705
|
+
}
|
|
706
|
+
} else {
|
|
707
|
+
const currentID: string = isHeader ? curOpt.groupTemplateID : curOpt.templateID;
|
|
708
|
+
if (isHeader) {
|
|
709
|
+
if (componentInstance && componentInstance.getModuleName() != 'listview') {
|
|
710
|
+
// eslint-disable-next-line
|
|
711
|
+
const compiledElement: any = compiledString(
|
|
712
|
+
curItem,
|
|
713
|
+
componentInstance,
|
|
714
|
+
'headerTemplate',
|
|
715
|
+
currentID,
|
|
716
|
+
!!curOpt.isStringTemplate,
|
|
717
|
+
null,
|
|
718
|
+
li);
|
|
719
|
+
if (compiledElement) {
|
|
720
|
+
append(compiledElement, li);
|
|
721
|
+
}
|
|
722
|
+
} else {
|
|
723
|
+
append(compiledString(curItem, componentInstance, 'headerTemplate', currentID, !!curOpt.isStringTemplate), li);
|
|
724
|
+
}
|
|
725
|
+
} else {
|
|
726
|
+
if (componentInstance && componentInstance.getModuleName() !== 'listview') {
|
|
727
|
+
// eslint-disable-next-line
|
|
728
|
+
const compiledElement: any = compiledString(
|
|
729
|
+
curItem,
|
|
730
|
+
componentInstance,
|
|
731
|
+
'template',
|
|
732
|
+
currentID,
|
|
733
|
+
!!curOpt.isStringTemplate,
|
|
734
|
+
null,
|
|
735
|
+
li);
|
|
736
|
+
if (compiledElement) {
|
|
737
|
+
append(compiledElement, li);
|
|
738
|
+
}
|
|
739
|
+
} else {
|
|
740
|
+
append(compiledString(curItem, componentInstance, 'template', currentID, !!curOpt.isStringTemplate), li);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
li.setAttribute('data-value', isNullOrUndefined(value) ? 'null' : value);
|
|
744
|
+
li.setAttribute('role', 'option');
|
|
745
|
+
}
|
|
746
|
+
if (curOpt.itemCreated && typeof curOpt.itemCreated === 'function') {
|
|
747
|
+
const curData: Object = {
|
|
748
|
+
dataSource: dataSource,
|
|
749
|
+
curData: curItem,
|
|
750
|
+
text: value,
|
|
751
|
+
item: li,
|
|
752
|
+
options: curOpt,
|
|
753
|
+
fields: curFields
|
|
754
|
+
};
|
|
755
|
+
curOpt.itemCreated(curData);
|
|
756
|
+
}
|
|
757
|
+
liCollection.push(li);
|
|
758
|
+
}
|
|
759
|
+
append(liCollection, ulElement);
|
|
760
|
+
return ulElement;
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* Created header items from group template.
|
|
764
|
+
*
|
|
765
|
+
* @param {string} template - that need to convert and generate li element.
|
|
766
|
+
*
|
|
767
|
+
* @param {{Object}[]} dataSource - Specifies local JSON data source.
|
|
768
|
+
*
|
|
769
|
+
* @param {FieldsMapping} fields - Specifies fields for mapping the dataSource.
|
|
770
|
+
*
|
|
771
|
+
* @param {Element[]} headerItems? - Specifies listbase header items.
|
|
772
|
+
*/
|
|
773
|
+
|
|
774
|
+
// tslint:disable-next-line
|
|
775
|
+
export function renderGroupTemplate(
|
|
776
|
+
groupTemplate: string | Function,
|
|
777
|
+
groupDataSource: { [key: string]: Object }[],
|
|
778
|
+
fields: FieldsMapping,
|
|
779
|
+
// eslint-disable-next-line
|
|
780
|
+
headerItems: Element[], options?: ListBaseOptions, componentInstance?: any): Element[] {
|
|
781
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
782
|
+
const compiledString: Function = compileTemplate(groupTemplate);
|
|
783
|
+
const curFields: FieldsMapping = extend({}, defaultMappedFields, fields);
|
|
784
|
+
const curOpt: ListBaseOptions = extend({}, defaultListBaseOptions, options);
|
|
785
|
+
const category: string = curFields.groupBy;
|
|
786
|
+
for (const header of headerItems) {
|
|
787
|
+
const headerData: { [key: string]: string; } = {};
|
|
788
|
+
headerData[`${category}`] = header.textContent;
|
|
789
|
+
header.innerHTML = '';
|
|
790
|
+
if (componentInstance && componentInstance.getModuleName() !== "listview") {
|
|
791
|
+
// eslint-disable-next-line
|
|
792
|
+
const compiledElement: any = compiledString(
|
|
793
|
+
headerData,
|
|
794
|
+
componentInstance,
|
|
795
|
+
'groupTemplate',
|
|
796
|
+
curOpt.groupTemplateID,
|
|
797
|
+
!!curOpt.isStringTemplate, null, header);
|
|
798
|
+
if (compiledElement) {
|
|
799
|
+
append(compiledElement, header);
|
|
800
|
+
}
|
|
801
|
+
} else {
|
|
802
|
+
append(compiledString(headerData, componentInstance, 'groupTemplate', curOpt.groupTemplateID, !!curOpt.isStringTemplate), header);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
return headerItems;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
export function generateId(): string {
|
|
809
|
+
return Math.floor((1 + Math.random()) * 0x10000)
|
|
810
|
+
.toString(16)
|
|
811
|
+
.substring(1);
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
function processSubChild(
|
|
815
|
+
createElement: createElementParams, fieldData: { [key: string]: Object }, fields: FieldsMapping, ds: { [key: string]: Object }[],
|
|
816
|
+
options: ListBaseOptions, element: HTMLElement, level: number): void {
|
|
817
|
+
// Get SubList
|
|
818
|
+
const subDS: { [key: string]: Object }[] = <{ [key: string]: Object }[]>fieldData[fields.child] || [];
|
|
819
|
+
let hasChildren: boolean = <boolean>fieldData[fields.hasChildren];
|
|
820
|
+
//Create Sub child
|
|
821
|
+
if (subDS.length) {
|
|
822
|
+
hasChildren = true;
|
|
823
|
+
element.classList.add(cssClass.hasChild);
|
|
824
|
+
if (options.processSubChild) {
|
|
825
|
+
const subLi: HTMLElement = <HTMLElement>createListFromJson(createElement, subDS, options, ++level);
|
|
826
|
+
element.appendChild(subLi);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
// Create expand and collapse node
|
|
831
|
+
if (!!options.expandCollapse && hasChildren && !options.template) {
|
|
832
|
+
element.firstElementChild.classList.add(cssClass.iconWrapper);
|
|
833
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
834
|
+
const expandElement: Function = options.expandIconPosition === 'Left' ? prepend : append;
|
|
835
|
+
expandElement(
|
|
836
|
+
[createElement('div', { className: 'e-icons ' + options.expandIconClass })],
|
|
837
|
+
element.querySelector('.' + cssClass.textContent));
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
function generateSingleLevelLI(
|
|
842
|
+
createElement: createElementParams, item: string | { [key: string]: Object } | number,
|
|
843
|
+
fieldData: { [key: string]: Object }, fields?: FieldsMapping, className?: string, innerElements?: HTMLElement[],
|
|
844
|
+
grpLI?: boolean, id?: string, index?: number, options?: ListBaseOptions):
|
|
845
|
+
HTMLElement {
|
|
846
|
+
const curOpt: ListBaseOptions = extend({}, defaultListBaseOptions, options);
|
|
847
|
+
const ariaAttributes: AriaAttributesMapping = extend({}, defaultAriaAttributes, curOpt.ariaAttributes);
|
|
848
|
+
let text: string = <string>item;
|
|
849
|
+
let value: string = <string>item;
|
|
850
|
+
let dataSource: { [key: string]: string } | { [key: string]: object };
|
|
851
|
+
if (typeof item !== 'string' && typeof item !== 'number' && typeof item !== 'boolean') {
|
|
852
|
+
dataSource = <{ [key: string]: Object }>item;
|
|
853
|
+
text = (typeof fieldData[fields.text] === 'boolean' || typeof fieldData[fields.text] === 'number') ?
|
|
854
|
+
<string>fieldData[fields.text] : (<string>fieldData[fields.text] || '');
|
|
855
|
+
value = <string>fieldData[fields.value];
|
|
856
|
+
}
|
|
857
|
+
let elementID: string;
|
|
858
|
+
if (!isNullOrUndefined(dataSource) && !isNullOrUndefined(fieldData[fields.id])
|
|
859
|
+
&& fieldData[fields.id] !== '') {
|
|
860
|
+
elementID = id;
|
|
861
|
+
} else {
|
|
862
|
+
elementID = id + '-' + index;
|
|
863
|
+
}
|
|
864
|
+
const li: HTMLElement = createElement('li', {
|
|
865
|
+
className: (grpLI === true ? cssClass.group : cssClass.li) + ' ' + (isNullOrUndefined(className) ? '' : className),
|
|
866
|
+
id: elementID, attrs: (ariaAttributes.groupItemRole !== '' && ariaAttributes.itemRole !== '' ?
|
|
867
|
+
{ role: (grpLI === true ? ariaAttributes.groupItemRole : ariaAttributes.itemRole) } : {})
|
|
868
|
+
});
|
|
869
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
870
|
+
if (dataSource && fieldData.hasOwnProperty(fields.enabled) && fieldData[fields.enabled].toString() === 'false') {
|
|
871
|
+
li.classList.add(cssClass.disabled);
|
|
872
|
+
}
|
|
873
|
+
if (grpLI) {
|
|
874
|
+
li.innerText = text;
|
|
875
|
+
} else {
|
|
876
|
+
li.setAttribute('data-value', isNullOrUndefined(value) ? 'null' : value);
|
|
877
|
+
|
|
878
|
+
li.setAttribute('role', 'option');
|
|
879
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
880
|
+
if (dataSource && fieldData.hasOwnProperty(fields.htmlAttributes) && fieldData[fields.htmlAttributes]) {
|
|
881
|
+
setAttribute(li, <{ [key: string]: string }>fieldData[fields.htmlAttributes]);
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
if (innerElements.length && !curOpt.itemNavigable) { append(innerElements, li); }
|
|
885
|
+
|
|
886
|
+
if (dataSource && (fieldData[fields.url] || (fieldData[fields.urlAttributes] &&
|
|
887
|
+
(fieldData[fields.urlAttributes] as { [key: string]: Object }).href))) {
|
|
888
|
+
li.appendChild(anchorTag(createElement, dataSource, fields, text, innerElements, curOpt.itemNavigable));
|
|
889
|
+
} else {
|
|
890
|
+
if (innerElements.length && curOpt.itemNavigable) { append(innerElements, li); }
|
|
891
|
+
li.appendChild(document.createTextNode(text));
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
return li;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
function getModuleClass(moduleName: string): ClassList {
|
|
898
|
+
let moduleClass: ClassList;
|
|
899
|
+
// eslint-disable-next-line
|
|
900
|
+
return moduleClass = {
|
|
901
|
+
li: `e-${moduleName}-item`,
|
|
902
|
+
ul: `e-${moduleName}-parent e-ul`,
|
|
903
|
+
group: `e-${moduleName}-group-item`,
|
|
904
|
+
icon: `e-${moduleName}-icon`,
|
|
905
|
+
text: `e-${moduleName}-text`,
|
|
906
|
+
check: `e-${moduleName}-check`,
|
|
907
|
+
checked: 'e-checked',
|
|
908
|
+
selected: 'e-selected',
|
|
909
|
+
expanded: 'e-expanded',
|
|
910
|
+
textContent: 'e-text-content',
|
|
911
|
+
hasChild: 'e-has-child',
|
|
912
|
+
level: 'e-level',
|
|
913
|
+
url: `e-${moduleName}-url`,
|
|
914
|
+
collapsible: 'e-icon-collapsible',
|
|
915
|
+
disabled: 'e-disabled',
|
|
916
|
+
image: `e-${moduleName}-img`,
|
|
917
|
+
iconWrapper: 'e-icon-wrapper',
|
|
918
|
+
anchorWrap: 'e-anchor-wrap',
|
|
919
|
+
navigable: 'e-navigable'
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
function anchorTag(
|
|
924
|
+
createElement: createElementParams, dataSource: { [key: string]: object } | { [key: string]: string },
|
|
925
|
+
fields: FieldsMapping, text: string, innerElements: HTMLElement[], isFullNavigation: boolean): HTMLElement {
|
|
926
|
+
const fieldData: { [key: string]: Object } = <{ [key: string]: Object }>getFieldValues(dataSource, fields);
|
|
927
|
+
const attr: { [key: string]: string } = { href: <string>fieldData[fields.url] };
|
|
928
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
929
|
+
if (fieldData.hasOwnProperty(fields.urlAttributes) && fieldData[fields.urlAttributes]) {
|
|
930
|
+
merge(attr, fieldData[fields.urlAttributes]);
|
|
931
|
+
attr.href = <string>fieldData[fields.url] ? <string>fieldData[fields.url] :
|
|
932
|
+
(fieldData[fields.urlAttributes] as { [key: string]: Object }).href as string;
|
|
933
|
+
}
|
|
934
|
+
let anchorTag: HTMLElement;
|
|
935
|
+
if (!isFullNavigation) {
|
|
936
|
+
anchorTag = createElement('a', { className: cssClass.text + ' ' + cssClass.url, innerHTML: text });
|
|
937
|
+
} else {
|
|
938
|
+
anchorTag = createElement('a', { className: cssClass.text + ' ' + cssClass.url });
|
|
939
|
+
const anchorWrapper: HTMLElement = createElement('div', { className: cssClass.anchorWrap });
|
|
940
|
+
if (innerElements && innerElements.length) {
|
|
941
|
+
append(innerElements, anchorWrapper);
|
|
942
|
+
}
|
|
943
|
+
anchorWrapper.appendChild(document.createTextNode(text));
|
|
944
|
+
append([anchorWrapper], anchorTag);
|
|
945
|
+
}
|
|
946
|
+
setAttribute(anchorTag, attr);
|
|
947
|
+
return anchorTag;
|
|
948
|
+
}
|
|
949
|
+
// tslint:disable-next-line
|
|
950
|
+
/* tslint:disable:align */
|
|
951
|
+
function generateLI(
|
|
952
|
+
createElement: createElementParams, item: string | { [key: string]: Object } | number, fieldData: { [key: string]: Object },
|
|
953
|
+
// eslint-disable-next-line
|
|
954
|
+
fields: FieldsMapping, className?: string, options?: ListBaseOptions, componentInstance?: any): HTMLElement {
|
|
955
|
+
const curOpt: ListBaseOptions = extend({}, defaultListBaseOptions, options);
|
|
956
|
+
const ariaAttributes: AriaAttributesMapping = extend({}, defaultAriaAttributes, curOpt.ariaAttributes);
|
|
957
|
+
let text: string = <string>item;
|
|
958
|
+
let uID: string;
|
|
959
|
+
let grpLI: boolean;
|
|
960
|
+
let dataSource: { [key: string]: string } | { [key: string]: object };
|
|
961
|
+
if (typeof item !== 'string' && typeof item !== 'number') {
|
|
962
|
+
dataSource = <{ [key: string]: Object }>item;
|
|
963
|
+
text = <string>fieldData[fields.text] || '';
|
|
964
|
+
// tslint:disable-next-line
|
|
965
|
+
uID = (isNullOrUndefined(<string>fieldData['_id'])) ? <string>fieldData[fields.id] : <string>fieldData['_id'];
|
|
966
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
967
|
+
grpLI = (item.hasOwnProperty('isHeader') && (item as { isHeader: Object } & { [key: string]: Object }).isHeader)
|
|
968
|
+
? true : false;
|
|
969
|
+
}
|
|
970
|
+
if (options && options.enableHtmlSanitizer) {
|
|
971
|
+
// eslint-disable-next-line no-self-assign
|
|
972
|
+
text = text;
|
|
973
|
+
}
|
|
974
|
+
const li: HTMLElement = createElement('li', {
|
|
975
|
+
className: (grpLI === true ? cssClass.group : cssClass.li) + ' ' + (isNullOrUndefined(className) ? '' : className),
|
|
976
|
+
attrs: (ariaAttributes.groupItemRole !== '' && ariaAttributes.itemRole !== '' ?
|
|
977
|
+
{ role: (grpLI === true ? ariaAttributes.groupItemRole : ariaAttributes.itemRole) } : {})
|
|
978
|
+
});
|
|
979
|
+
|
|
980
|
+
if (!isNullOrUndefined(uID) === true) {
|
|
981
|
+
li.setAttribute('data-uid', uID);
|
|
982
|
+
}
|
|
983
|
+
else {
|
|
984
|
+
li.setAttribute('data-uid', generateId());
|
|
985
|
+
}
|
|
986
|
+
if (grpLI && options && options.groupTemplate) {
|
|
987
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
988
|
+
const compiledString: Function = compileTemplate(options.groupTemplate);
|
|
989
|
+
if (componentInstance && componentInstance.getModuleName() !== "listview") {
|
|
990
|
+
// eslint-disable-next-line
|
|
991
|
+
const compiledElement: any = compiledString(
|
|
992
|
+
item,
|
|
993
|
+
componentInstance,
|
|
994
|
+
'groupTemplate',
|
|
995
|
+
curOpt.groupTemplateID,
|
|
996
|
+
!!curOpt.isStringTemplate,
|
|
997
|
+
null,
|
|
998
|
+
li);
|
|
999
|
+
if (compiledElement) {
|
|
1000
|
+
append(compiledElement, li);
|
|
1001
|
+
}
|
|
1002
|
+
} else {
|
|
1003
|
+
append(compiledString(item, componentInstance, 'groupTemplate', curOpt.groupTemplateID, !!curOpt.isStringTemplate), li);
|
|
1004
|
+
}
|
|
1005
|
+
} else if (!grpLI && options && options.template) {
|
|
1006
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
1007
|
+
const compiledString: Function = compileTemplate(options.template);
|
|
1008
|
+
if (componentInstance && componentInstance.getModuleName() !== 'listview') {
|
|
1009
|
+
// eslint-disable-next-line
|
|
1010
|
+
const compiledElement: any = compiledString(
|
|
1011
|
+
item,
|
|
1012
|
+
componentInstance,
|
|
1013
|
+
'template',
|
|
1014
|
+
curOpt.templateID,
|
|
1015
|
+
!!curOpt.isStringTemplate,
|
|
1016
|
+
null,
|
|
1017
|
+
li);
|
|
1018
|
+
if (compiledElement) {
|
|
1019
|
+
append(compiledElement, li);
|
|
1020
|
+
}
|
|
1021
|
+
} else {
|
|
1022
|
+
append(compiledString(item, componentInstance, 'template', curOpt.templateID, !!curOpt.isStringTemplate), li);
|
|
1023
|
+
}
|
|
1024
|
+
} else {
|
|
1025
|
+
const innerDiv: HTMLElement = createElement('div', {
|
|
1026
|
+
className: cssClass.textContent,
|
|
1027
|
+
attrs: (ariaAttributes.wrapperRole !== '' ? { role: ariaAttributes.wrapperRole } : {})
|
|
1028
|
+
});
|
|
1029
|
+
if (dataSource && (fieldData[fields.url] || (fieldData[fields.urlAttributes] &&
|
|
1030
|
+
(fieldData[fields.urlAttributes] as { [key: string]: Object }).href))) {
|
|
1031
|
+
innerDiv.appendChild(anchorTag(createElement, dataSource, fields, text, null, curOpt.itemNavigable));
|
|
1032
|
+
} else {
|
|
1033
|
+
const element: HTMLElement = createElement('span', {
|
|
1034
|
+
className: cssClass.text,
|
|
1035
|
+
attrs: (ariaAttributes.itemText !== '' ? { role: ariaAttributes.itemText } : {})
|
|
1036
|
+
});
|
|
1037
|
+
if (options && options.enableHtmlSanitizer) {
|
|
1038
|
+
element.innerText = text;
|
|
1039
|
+
} else {
|
|
1040
|
+
element.innerHTML = text;
|
|
1041
|
+
}
|
|
1042
|
+
innerDiv.appendChild(element);
|
|
1043
|
+
}
|
|
1044
|
+
li.appendChild(innerDiv);
|
|
1045
|
+
}
|
|
1046
|
+
return li;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
/**
|
|
1050
|
+
* Returns UL element based on the given LI element.
|
|
1051
|
+
*
|
|
1052
|
+
* @param {HTMLElement[]} liElement - Specifies array of LI element.
|
|
1053
|
+
*
|
|
1054
|
+
* @param {string} className? - Specifies class name that need to be added in UL element.
|
|
1055
|
+
*
|
|
1056
|
+
* @param {ListBaseOptions} options? - Specifies ListBase options.
|
|
1057
|
+
*/
|
|
1058
|
+
|
|
1059
|
+
export function generateUL(
|
|
1060
|
+
createElement: createElementParams, liElement: HTMLElement[], className?: string, options?: ListBaseOptions): HTMLElement {
|
|
1061
|
+
const curOpt: ListBaseOptions = extend({}, defaultListBaseOptions, options);
|
|
1062
|
+
const ariaAttributes: AriaAttributesMapping = extend({}, defaultAriaAttributes, curOpt.ariaAttributes);
|
|
1063
|
+
cssClass = getModuleClass(curOpt.moduleName);
|
|
1064
|
+
const ulElement: HTMLElement = createElement('ul', {
|
|
1065
|
+
className: cssClass.ul + ' ' + (isNullOrUndefined(className) ? '' : className),
|
|
1066
|
+
attrs: (ariaAttributes.listRole !== '' ? { role: ariaAttributes.listRole } : {})
|
|
1067
|
+
});
|
|
1068
|
+
|
|
1069
|
+
append(liElement, ulElement);
|
|
1070
|
+
|
|
1071
|
+
return ulElement;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
/**
|
|
1075
|
+
* Returns LI element with additional DIV tag based on the given LI element.
|
|
1076
|
+
*
|
|
1077
|
+
* @param {liElement} liElement - Specifies LI element.
|
|
1078
|
+
*
|
|
1079
|
+
* @param {string} className? - Specifies class name that need to be added in created DIV element.
|
|
1080
|
+
*
|
|
1081
|
+
* @param {ListBaseOptions} options? - Specifies ListBase options.
|
|
1082
|
+
*/
|
|
1083
|
+
|
|
1084
|
+
export function generateIcon(
|
|
1085
|
+
createElement: createElementParams, liElement: HTMLElement, className?: string, options?: ListBaseOptions): HTMLElement {
|
|
1086
|
+
const curOpt: ListBaseOptions = extend({}, defaultListBaseOptions, options);
|
|
1087
|
+
cssClass = getModuleClass(curOpt.moduleName);
|
|
1088
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
1089
|
+
const expandElement: Function = curOpt.expandIconPosition === 'Left' ? prepend : append;
|
|
1090
|
+
expandElement(
|
|
1091
|
+
[createElement('div', {
|
|
1092
|
+
className: 'e-icons ' + curOpt.expandIconClass + ' ' +
|
|
1093
|
+
(isNullOrUndefined(className) ? '' : className)
|
|
1094
|
+
})],
|
|
1095
|
+
liElement.querySelector('.' + cssClass.textContent));
|
|
1096
|
+
|
|
1097
|
+
return liElement;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
export type createElementParams = (
|
|
1103
|
+
tag: string,
|
|
1104
|
+
prop?: { id?: string, className?: string, innerHTML?: string, styles?: string, attrs?: { [key: string]: string } }
|
|
1105
|
+
) => HTMLElement;
|
|
1106
|
+
|
|
1107
|
+
/**
|
|
1108
|
+
* An interface that holds the field mappings
|
|
1109
|
+
*/
|
|
1110
|
+
export interface FieldsMapping {
|
|
1111
|
+
id?: string;
|
|
1112
|
+
text?: string;
|
|
1113
|
+
value?: string;
|
|
1114
|
+
isChecked?: string;
|
|
1115
|
+
isVisible?: string;
|
|
1116
|
+
url?: string;
|
|
1117
|
+
enabled?: string;
|
|
1118
|
+
groupBy?: string;
|
|
1119
|
+
expanded?: string;
|
|
1120
|
+
selected?: string;
|
|
1121
|
+
iconCss?: string;
|
|
1122
|
+
child?: string;
|
|
1123
|
+
tooltip?: string;
|
|
1124
|
+
hasChildren?: string;
|
|
1125
|
+
htmlAttributes?: string;
|
|
1126
|
+
urlAttributes?: string;
|
|
1127
|
+
imageUrl?: string;
|
|
1128
|
+
imageAttributes?: string;
|
|
1129
|
+
sortBy?: string
|
|
1130
|
+
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
/**
|
|
1134
|
+
* An enum type that denotes the Expand Icon Position. Available options are as follows Right, Left;
|
|
1135
|
+
*/
|
|
1136
|
+
export type Position = 'Right' | 'Left';
|
|
1137
|
+
|
|
1138
|
+
/**
|
|
1139
|
+
* An interface that holds item aria attributes mapping
|
|
1140
|
+
*/
|
|
1141
|
+
export interface AriaAttributesMapping {
|
|
1142
|
+
level?: number;
|
|
1143
|
+
listRole?: string;
|
|
1144
|
+
itemRole?: string;
|
|
1145
|
+
groupItemRole?: string;
|
|
1146
|
+
itemText?: string;
|
|
1147
|
+
wrapperRole?: string;
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
/**
|
|
1151
|
+
* Basic ListBase Options
|
|
1152
|
+
*/
|
|
1153
|
+
export interface ListBaseOptions {
|
|
1154
|
+
/**
|
|
1155
|
+
* Specifies that fields that mapped in dataSource
|
|
1156
|
+
*/
|
|
1157
|
+
fields?: FieldsMapping;
|
|
1158
|
+
/**
|
|
1159
|
+
* Specifies the aria attributes
|
|
1160
|
+
*/
|
|
1161
|
+
ariaAttributes?: AriaAttributesMapping;
|
|
1162
|
+
/**
|
|
1163
|
+
* Specifies to show checkBox
|
|
1164
|
+
*/
|
|
1165
|
+
showCheckBox?: boolean;
|
|
1166
|
+
/**
|
|
1167
|
+
* Specifies to show icon
|
|
1168
|
+
*/
|
|
1169
|
+
showIcon?: boolean;
|
|
1170
|
+
/**
|
|
1171
|
+
* Specifies to show collapsible icon
|
|
1172
|
+
*/
|
|
1173
|
+
expandCollapse?: boolean;
|
|
1174
|
+
/**
|
|
1175
|
+
* Specifies when need to add additional UL list class
|
|
1176
|
+
*/
|
|
1177
|
+
listClass?: string;
|
|
1178
|
+
/**
|
|
1179
|
+
* Specifies when need to add additional LI item class
|
|
1180
|
+
*/
|
|
1181
|
+
itemClass?: string;
|
|
1182
|
+
/**
|
|
1183
|
+
* Enables when need process depth child processing.
|
|
1184
|
+
*/
|
|
1185
|
+
processSubChild?: boolean;
|
|
1186
|
+
/**
|
|
1187
|
+
* Specifies the sort order
|
|
1188
|
+
*/
|
|
1189
|
+
sortOrder?: SortOrder;
|
|
1190
|
+
/**
|
|
1191
|
+
* Specifies the item template
|
|
1192
|
+
*/
|
|
1193
|
+
template?: string | Function;
|
|
1194
|
+
/**
|
|
1195
|
+
* Specifies the group header template
|
|
1196
|
+
*/
|
|
1197
|
+
groupTemplate?: string | Function;
|
|
1198
|
+
/**
|
|
1199
|
+
* Specifies the ListView header template
|
|
1200
|
+
*/
|
|
1201
|
+
headerTemplate?: string | Function;
|
|
1202
|
+
/**
|
|
1203
|
+
* Specifies the callback function that triggered before each list creation
|
|
1204
|
+
*/
|
|
1205
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
1206
|
+
itemCreating?: Function;
|
|
1207
|
+
/**
|
|
1208
|
+
* Specifies the callback function that triggered after each list creation
|
|
1209
|
+
*/
|
|
1210
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
1211
|
+
itemCreated?: Function;
|
|
1212
|
+
/**
|
|
1213
|
+
* Specifies the customizable expand icon class
|
|
1214
|
+
*/
|
|
1215
|
+
expandIconClass?: string;
|
|
1216
|
+
/**
|
|
1217
|
+
* Specifies the customized class name based on their module name
|
|
1218
|
+
*/
|
|
1219
|
+
moduleName?: string;
|
|
1220
|
+
/**
|
|
1221
|
+
* Specifies the expand/collapse icon position
|
|
1222
|
+
*/
|
|
1223
|
+
expandIconPosition?: Position;
|
|
1224
|
+
/**
|
|
1225
|
+
* Specifies the template ID
|
|
1226
|
+
*/
|
|
1227
|
+
templateID?: string;
|
|
1228
|
+
/**
|
|
1229
|
+
* Specifies the groupTemplate ID
|
|
1230
|
+
*/
|
|
1231
|
+
groupTemplateID?: string;
|
|
1232
|
+
/**
|
|
1233
|
+
* Force template compiler to compile as string template
|
|
1234
|
+
*/
|
|
1235
|
+
isStringTemplate?: string;
|
|
1236
|
+
/**
|
|
1237
|
+
* Defines whether to allow the cross scripting site or not.
|
|
1238
|
+
*/
|
|
1239
|
+
enableHtmlSanitizer?: boolean;
|
|
1240
|
+
/**
|
|
1241
|
+
* If set true to this property then the entire list will be navigate-able instead of text element
|
|
1242
|
+
*/
|
|
1243
|
+
itemNavigable?: boolean;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
/**
|
|
1247
|
+
* Used to get dataSource item from complex data using fields.
|
|
1248
|
+
*
|
|
1249
|
+
* @param {Object} dataSource - Specifies an JSON or String data.
|
|
1250
|
+
*
|
|
1251
|
+
* @param {FieldsMapping} fields - Fields that are mapped from the dataSource.
|
|
1252
|
+
*/
|
|
1253
|
+
|
|
1254
|
+
export function getFieldValues(dataItem: { [key: string]: Object } | string | number, fields: FieldsMapping)
|
|
1255
|
+
: { [key: string]: Object } | string | number {
|
|
1256
|
+
const fieldData: { [key: string]: Object } = {};
|
|
1257
|
+
if (isNullOrUndefined(dataItem) || typeof (dataItem) === 'string' || typeof (dataItem) === 'number'
|
|
1258
|
+
|| !isNullOrUndefined((<{ [key: string]: Object }>dataItem).isHeader)) {
|
|
1259
|
+
return dataItem;
|
|
1260
|
+
} else {
|
|
1261
|
+
for (const field of Object.keys(fields)) {
|
|
1262
|
+
const dataField: string = (<{ [key: string]: Object }>fields)[`${field}`] as string;
|
|
1263
|
+
const value: { [key: string]: Object } = !isNullOrUndefined(dataField) &&
|
|
1264
|
+
typeof (dataField) === 'string' ? getValue(dataField, dataItem) : undefined;
|
|
1265
|
+
if (!isNullOrUndefined(value)) {
|
|
1266
|
+
fieldData[`${dataField}`] = value;
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
return fieldData;
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
function compileTemplate(template: string | Function): Function {
|
|
1274
|
+
if (template) {
|
|
1275
|
+
try {
|
|
1276
|
+
if (typeof template !== 'function' && document.querySelector(template)) {
|
|
1277
|
+
return compile(document.querySelector(template).innerHTML.trim());
|
|
1278
|
+
} else {
|
|
1279
|
+
return compile(template);
|
|
1280
|
+
}
|
|
1281
|
+
} catch (e) {
|
|
1282
|
+
return compile(template);
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
return undefined;
|
|
1286
|
+
}
|