@syncfusion/ej2-dropdowns 23.1.43 → 23.2.4-13895
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/CHANGELOG.md +2114 -2084
- package/{README.md → ReadMe.md} +217 -217
- package/dist/ej2-dropdowns.min.js +1 -10
- package/dist/ej2-dropdowns.umd.min.js +1 -10
- package/dist/ej2-dropdowns.umd.min.js.map +1 -1
- package/dist/es6/ej2-dropdowns.es2015.js +83 -71
- package/dist/es6/ej2-dropdowns.es2015.js.map +1 -1
- package/dist/es6/ej2-dropdowns.es5.js +225 -212
- package/dist/es6/ej2-dropdowns.es5.js.map +1 -1
- package/dist/global/ej2-dropdowns.min.js +1 -10
- package/dist/global/ej2-dropdowns.min.js.map +1 -1
- package/dist/global/index.d.ts +0 -9
- package/dist/ts/auto-complete/auto-complete.ts +615 -0
- package/dist/ts/combo-box/combo-box.ts +1028 -0
- package/dist/ts/common/highlight-search.ts +57 -0
- package/dist/ts/common/incremental-search.ts +131 -0
- package/dist/ts/common/interface.ts +72 -0
- package/dist/ts/common/virtual-scroll.ts +354 -0
- package/dist/ts/drop-down-base/drop-down-base.ts +1864 -0
- package/dist/ts/drop-down-list/drop-down-list.ts +3954 -0
- package/dist/ts/drop-down-tree/drop-down-tree.ts +3741 -0
- package/dist/ts/list-box/list-box.ts +2753 -0
- package/dist/ts/mention/mention.ts +1857 -0
- package/dist/ts/multi-select/checkbox-selection.ts +547 -0
- package/dist/ts/multi-select/float-label.ts +176 -0
- package/dist/ts/multi-select/interface.ts +70 -0
- package/dist/ts/multi-select/multi-select.ts +4880 -0
- package/helpers/e2e/autocomplete.js +13 -13
- package/helpers/e2e/combobox.js +13 -13
- package/helpers/e2e/dropdownlist.js +13 -13
- package/helpers/e2e/index.js +3 -3
- package/helpers/e2e/listboxHelper.js +13 -13
- package/helpers/e2e/multiselect.js +13 -13
- package/license +2 -2
- package/package.json +80 -80
- package/src/auto-complete/auto-complete-model.d.ts +188 -188
- package/src/auto-complete/auto-complete.d.ts +12 -12
- package/src/auto-complete/auto-complete.js +21 -21
- package/src/combo-box/combo-box-model.d.ts +224 -224
- package/src/combo-box/combo-box.d.ts +27 -27
- package/src/combo-box/combo-box.js +29 -29
- package/src/common/virtual-scroll.js +46 -46
- package/src/drop-down-base/drop-down-base-model.d.ts +200 -200
- package/src/drop-down-base/drop-down-base.d.ts +15 -15
- package/src/drop-down-base/drop-down-base.js +23 -21
- package/src/drop-down-list/drop-down-list-model.d.ts +202 -202
- package/src/drop-down-list/drop-down-list.d.ts +4 -4
- package/src/drop-down-list/drop-down-list.js +24 -21
- package/src/drop-down-tree/drop-down-tree-model.d.ts +468 -468
- package/src/drop-down-tree/drop-down-tree.d.ts +0 -1
- package/src/drop-down-tree/drop-down-tree.js +19 -27
- package/src/list-box/list-box-model.d.ts +193 -193
- package/src/list-box/list-box.d.ts +5 -2
- package/src/list-box/list-box.js +38 -21
- package/src/mention/mention-model.d.ts +261 -261
- package/src/mention/mention.js +20 -21
- package/src/multi-select/multi-select-model.d.ts +512 -512
- package/src/multi-select/multi-select.js +19 -19
- package/styles/auto-complete/_all.scss +1 -1
- package/styles/auto-complete/_bootstrap-dark-definition.scss +3 -3
- package/styles/auto-complete/_bootstrap-definition.scss +2 -2
- package/styles/auto-complete/_bootstrap4-definition.scss +11 -11
- package/styles/auto-complete/_bootstrap5-definition.scss +2 -2
- package/styles/auto-complete/_fabric-dark-definition.scss +2 -2
- package/styles/auto-complete/_fabric-definition.scss +2 -2
- package/styles/auto-complete/_fluent-definition.scss +2 -2
- package/styles/auto-complete/_fusionnew-definition.scss +2 -2
- package/styles/auto-complete/_highcontrast-definition.scss +2 -2
- package/styles/auto-complete/_highcontrast-light-definition.scss +2 -2
- package/styles/auto-complete/_material-dark-definition.scss +2 -2
- package/styles/auto-complete/_material-definition.scss +2 -2
- package/styles/auto-complete/_material3-definition.scss +2 -2
- package/styles/auto-complete/_tailwind-definition.scss +2 -2
- package/styles/auto-complete/material3-dark.scss +1 -1
- package/styles/auto-complete/material3.scss +1 -1
- package/styles/bootstrap-dark.css +5 -0
- package/styles/bootstrap5-dark.css +2 -1
- package/styles/bootstrap5.css +2 -1
- package/styles/combo-box/_all.scss +1 -1
- package/styles/combo-box/_bootstrap-dark-definition.scss +2 -2
- package/styles/combo-box/_bootstrap-definition.scss +2 -2
- package/styles/combo-box/_bootstrap4-definition.scss +11 -11
- package/styles/combo-box/_bootstrap5-definition.scss +2 -2
- package/styles/combo-box/_fabric-dark-definition.scss +2 -2
- package/styles/combo-box/_fabric-definition.scss +2 -2
- package/styles/combo-box/_fluent-definition.scss +2 -2
- package/styles/combo-box/_fusionnew-definition.scss +2 -2
- package/styles/combo-box/_highcontrast-definition.scss +2 -2
- package/styles/combo-box/_highcontrast-light-definition.scss +3 -3
- package/styles/combo-box/_material-dark-definition.scss +2 -2
- package/styles/combo-box/_material-definition.scss +2 -2
- package/styles/combo-box/_material3-definition.scss +2 -2
- package/styles/combo-box/_tailwind-definition.scss +2 -2
- package/styles/combo-box/material3-dark.scss +1 -1
- package/styles/combo-box/material3.scss +1 -1
- package/styles/drop-down-base/_all.scss +2 -2
- package/styles/drop-down-base/_bootstrap-dark-definition.scss +83 -83
- package/styles/drop-down-base/_bootstrap-definition.scss +83 -83
- package/styles/drop-down-base/_bootstrap4-definition.scss +90 -90
- package/styles/drop-down-base/_bootstrap5-definition.scss +117 -117
- package/styles/drop-down-base/_definition.scss +23 -23
- package/styles/drop-down-base/_fabric-dark-definition.scss +86 -86
- package/styles/drop-down-base/_fabric-definition.scss +84 -84
- package/styles/drop-down-base/_fluent-definition.scss +121 -121
- package/styles/drop-down-base/_fusionnew-definition.scss +117 -117
- package/styles/drop-down-base/_highcontrast-definition.scss +105 -105
- package/styles/drop-down-base/_highcontrast-light-definition.scss +105 -105
- package/styles/drop-down-base/_layout.scss +195 -195
- package/styles/drop-down-base/_material-dark-definition.scss +86 -86
- package/styles/drop-down-base/_material-definition.scss +85 -85
- package/styles/drop-down-base/_material3-definition.scss +87 -87
- package/styles/drop-down-base/_tailwind-definition.scss +129 -129
- package/styles/drop-down-base/_theme.scss +391 -391
- package/styles/drop-down-base/material3-dark.scss +1 -1
- package/styles/drop-down-base/material3.scss +1 -1
- package/styles/drop-down-list/_all.scss +3 -3
- package/styles/drop-down-list/_bootstrap-dark-definition.scss +157 -157
- package/styles/drop-down-list/_bootstrap-definition.scss +156 -156
- package/styles/drop-down-list/_bootstrap4-definition.scss +202 -202
- package/styles/drop-down-list/_bootstrap5-definition.scss +201 -201
- package/styles/drop-down-list/_fabric-dark-definition.scss +128 -128
- package/styles/drop-down-list/_fabric-definition.scss +124 -124
- package/styles/drop-down-list/_fluent-definition.scss +185 -185
- package/styles/drop-down-list/_fusionnew-definition.scss +201 -201
- package/styles/drop-down-list/_highcontrast-definition.scss +142 -142
- package/styles/drop-down-list/_highcontrast-light-definition.scss +144 -144
- package/styles/drop-down-list/_layout.scss +310 -310
- package/styles/drop-down-list/_material-dark-definition.scss +143 -143
- package/styles/drop-down-list/_material-definition.scss +167 -167
- package/styles/drop-down-list/_material3-definition.scss +180 -180
- package/styles/drop-down-list/_tailwind-definition.scss +134 -134
- package/styles/drop-down-list/_theme.scss +10 -10
- package/styles/drop-down-list/icons/_bootstrap-dark.scss +14 -14
- package/styles/drop-down-list/icons/_bootstrap.scss +14 -14
- package/styles/drop-down-list/icons/_bootstrap4.scss +14 -14
- package/styles/drop-down-list/icons/_bootstrap5.scss +14 -14
- package/styles/drop-down-list/icons/_fabric-dark.scss +14 -14
- package/styles/drop-down-list/icons/_fabric.scss +14 -14
- package/styles/drop-down-list/icons/_fluent.scss +14 -14
- package/styles/drop-down-list/icons/_fusionnew.scss +14 -14
- package/styles/drop-down-list/icons/_highcontrast-light.scss +14 -14
- package/styles/drop-down-list/icons/_highcontrast.scss +14 -14
- package/styles/drop-down-list/icons/_material-dark.scss +14 -14
- package/styles/drop-down-list/icons/_material.scss +14 -14
- package/styles/drop-down-list/icons/_material3.scss +14 -14
- package/styles/drop-down-list/icons/_tailwind.scss +14 -14
- package/styles/drop-down-list/material3-dark.scss +1 -1
- package/styles/drop-down-list/material3.scss +1 -1
- package/styles/drop-down-tree/_all.scss +2 -2
- package/styles/drop-down-tree/_bootstrap-dark-definition.scss +71 -71
- package/styles/drop-down-tree/_bootstrap-definition.scss +70 -70
- package/styles/drop-down-tree/_bootstrap4-definition.scss +71 -71
- package/styles/drop-down-tree/_bootstrap5-definition.scss +59 -59
- package/styles/drop-down-tree/_fabric-dark-definition.scss +71 -71
- package/styles/drop-down-tree/_fabric-definition.scss +71 -71
- package/styles/drop-down-tree/_fluent-definition.scss +65 -65
- package/styles/drop-down-tree/_fusionnew-definition.scss +59 -59
- package/styles/drop-down-tree/_highcontrast-definition.scss +71 -71
- package/styles/drop-down-tree/_highcontrast-light-definition.scss +71 -71
- package/styles/drop-down-tree/_layout.scss +1418 -1412
- package/styles/drop-down-tree/_material-dark-definition.scss +72 -72
- package/styles/drop-down-tree/_material-definition.scss +72 -72
- package/styles/drop-down-tree/_material3-definition.scss +76 -76
- package/styles/drop-down-tree/_tailwind-definition.scss +61 -61
- package/styles/drop-down-tree/_theme.scss +132 -132
- package/styles/drop-down-tree/fluent-dark.css +2 -0
- package/styles/drop-down-tree/fluent.css +2 -0
- package/styles/drop-down-tree/icons/_bootstrap-dark.scss +11 -11
- package/styles/drop-down-tree/icons/_bootstrap.scss +11 -11
- package/styles/drop-down-tree/icons/_bootstrap4.scss +11 -11
- package/styles/drop-down-tree/icons/_bootstrap5.scss +11 -11
- package/styles/drop-down-tree/icons/_fabric-dark.scss +11 -11
- package/styles/drop-down-tree/icons/_fabric.scss +11 -11
- package/styles/drop-down-tree/icons/_fluent.scss +11 -11
- package/styles/drop-down-tree/icons/_fusionnew.scss +11 -11
- package/styles/drop-down-tree/icons/_highcontrast-light.scss +11 -11
- package/styles/drop-down-tree/icons/_highcontrast.scss +11 -11
- package/styles/drop-down-tree/icons/_material-dark.scss +11 -11
- package/styles/drop-down-tree/icons/_material.scss +11 -11
- package/styles/drop-down-tree/icons/_material3.scss +11 -11
- package/styles/drop-down-tree/icons/_tailwind-dark.scss +11 -11
- package/styles/drop-down-tree/icons/_tailwind.scss +11 -11
- package/styles/drop-down-tree/material3-dark.scss +1 -1
- package/styles/drop-down-tree/material3.scss +1 -1
- package/styles/fabric-dark.css +5 -0
- package/styles/fluent-dark.css +4 -1
- package/styles/fluent.css +4 -1
- package/styles/highcontrast.css +5 -0
- package/styles/list-box/_all.scss +2 -2
- package/styles/list-box/_bootstrap-dark-definition.scss +126 -126
- package/styles/list-box/_bootstrap-definition.scss +119 -119
- package/styles/list-box/_bootstrap4-definition.scss +124 -124
- package/styles/list-box/_bootstrap5-definition.scss +120 -120
- package/styles/list-box/_fabric-dark-definition.scss +126 -126
- package/styles/list-box/_fabric-definition.scss +119 -119
- package/styles/list-box/_fluent-definition.scss +120 -120
- package/styles/list-box/_fusionnew-definition.scss +111 -111
- package/styles/list-box/_highcontrast-definition.scss +119 -119
- package/styles/list-box/_highcontrast-light-definition.scss +126 -126
- package/styles/list-box/_layout.scss +542 -542
- package/styles/list-box/_material-dark-definition.scss +126 -126
- package/styles/list-box/_material-definition.scss +119 -119
- package/styles/list-box/_material3-definition.scss +119 -119
- package/styles/list-box/_tailwind-definition.scss +119 -119
- package/styles/list-box/_theme.scss +382 -382
- package/styles/list-box/icons/_bootstrap-dark.scss +25 -25
- package/styles/list-box/icons/_bootstrap.scss +25 -25
- package/styles/list-box/icons/_bootstrap4.scss +25 -25
- package/styles/list-box/icons/_bootstrap5.scss +25 -25
- package/styles/list-box/icons/_fabric-dark.scss +25 -25
- package/styles/list-box/icons/_fabric.scss +25 -25
- package/styles/list-box/icons/_fluent.scss +25 -25
- package/styles/list-box/icons/_fusionnew.scss +25 -25
- package/styles/list-box/icons/_highcontrast-light.scss +25 -25
- package/styles/list-box/icons/_highcontrast.scss +25 -25
- package/styles/list-box/icons/_material-dark.scss +25 -25
- package/styles/list-box/icons/_material.scss +25 -25
- package/styles/list-box/icons/_material3.scss +25 -25
- package/styles/list-box/icons/_tailwind-dark.scss +25 -25
- package/styles/list-box/icons/_tailwind.scss +25 -25
- package/styles/list-box/material3-dark.scss +1 -1
- package/styles/list-box/material3.scss +1 -1
- package/styles/material3-dark.scss +1 -1
- package/styles/material3.scss +1 -1
- package/styles/mention/_all.scss +1 -1
- package/styles/mention/_bootstrap-dark-definition.scss +3 -3
- package/styles/mention/_bootstrap-definition.scss +3 -3
- package/styles/mention/_bootstrap4-definition.scss +3 -3
- package/styles/mention/_bootstrap5-definition.scss +1 -1
- package/styles/mention/_fabric-dark-definition.scss +2 -2
- package/styles/mention/_fabric-definition.scss +3 -3
- package/styles/mention/_fluent-definition.scss +1 -1
- package/styles/mention/_fusionnew-definition.scss +1 -1
- package/styles/mention/_highcontrast-definition.scss +3 -3
- package/styles/mention/_highcontrast-light-definition.scss +3 -3
- package/styles/mention/_layout.scss +6 -6
- package/styles/mention/_material-dark-definition.scss +3 -3
- package/styles/mention/_material-definition.scss +3 -3
- package/styles/mention/_material3-definition.scss +1 -1
- package/styles/mention/_tailwind-definition.scss +1 -1
- package/styles/mention/material3-dark.scss +1 -1
- package/styles/mention/material3.scss +1 -1
- package/styles/multi-select/_all.scss +2 -2
- package/styles/multi-select/_bootstrap-dark-definition.scss +203 -198
- package/styles/multi-select/_bootstrap-definition.scss +192 -192
- package/styles/multi-select/_bootstrap4-definition.scss +278 -278
- package/styles/multi-select/_bootstrap5-definition.scss +230 -229
- package/styles/multi-select/_fabric-dark-definition.scss +192 -187
- package/styles/multi-select/_fabric-definition.scss +183 -183
- package/styles/multi-select/_fluent-definition.scss +241 -240
- package/styles/multi-select/_fusionnew-definition.scss +227 -227
- package/styles/multi-select/_highcontrast-definition.scss +303 -298
- package/styles/multi-select/_highcontrast-light-definition.scss +297 -297
- package/styles/multi-select/_layout.scss +2199 -2199
- package/styles/multi-select/_material-dark-definition.scss +230 -230
- package/styles/multi-select/_material-definition.scss +223 -223
- package/styles/multi-select/_material3-definition.scss +246 -246
- package/styles/multi-select/_tailwind-definition.scss +235 -234
- package/styles/multi-select/_theme.scss +586 -586
- package/styles/multi-select/bootstrap-dark.css +5 -0
- package/styles/multi-select/bootstrap5-dark.css +2 -1
- package/styles/multi-select/bootstrap5.css +2 -1
- package/styles/multi-select/fabric-dark.css +5 -0
- package/styles/multi-select/fluent-dark.css +2 -1
- package/styles/multi-select/fluent.css +2 -1
- package/styles/multi-select/highcontrast.css +5 -0
- package/styles/multi-select/icons/_bootstrap-dark.scss +26 -26
- package/styles/multi-select/icons/_bootstrap.scss +26 -26
- package/styles/multi-select/icons/_bootstrap4.scss +37 -37
- package/styles/multi-select/icons/_bootstrap5.scss +26 -26
- package/styles/multi-select/icons/_fabric-dark.scss +26 -26
- package/styles/multi-select/icons/_fabric.scss +26 -26
- package/styles/multi-select/icons/_fluent.scss +55 -55
- package/styles/multi-select/icons/_fusionnew.scss +26 -26
- package/styles/multi-select/icons/_highcontrast-light.scss +26 -26
- package/styles/multi-select/icons/_highcontrast.scss +26 -26
- package/styles/multi-select/icons/_material-dark.scss +693 -693
- package/styles/multi-select/icons/_material.scss +693 -693
- package/styles/multi-select/icons/_material3.scss +692 -692
- package/styles/multi-select/icons/_tailwind.scss +26 -26
- package/styles/multi-select/material3-dark.scss +1 -1
- package/styles/multi-select/material3.scss +1 -1
- package/styles/multi-select/tailwind-dark.css +2 -1
- package/styles/multi-select/tailwind.css +2 -1
- package/styles/tailwind-dark.css +2 -1
- package/styles/tailwind.css +2 -1
- package/.eslintrc.json +0 -260
- package/tslint.json +0 -111
|
@@ -0,0 +1,1864 @@
|
|
|
1
|
+
import { Component, EventHandler, addClass, append, Property, Event, KeyboardEvents, EmitType, L10n, compile, KeyboardEventArgs } from '@syncfusion/ej2-base';
|
|
2
|
+
import { setStyleAttribute, extend, removeClass, prepend, isNullOrUndefined, detach, getValue, AnimationModel } from '@syncfusion/ej2-base';
|
|
3
|
+
import { NotifyPropertyChanges, INotifyPropertyChanged, rippleEffect, RippleOptions, ChildProperty, Complex } from '@syncfusion/ej2-base';
|
|
4
|
+
import { DataManager, Query, DataOptions, DataUtil } from '@syncfusion/ej2-data';
|
|
5
|
+
import { ListBase, SortOrder } from '@syncfusion/ej2-lists';
|
|
6
|
+
import { DropDownBaseModel, FieldSettingsModel } from './drop-down-base-model';
|
|
7
|
+
import { Popup } from '@syncfusion/ej2-popups';
|
|
8
|
+
import { remove, select, selectAll } from '@syncfusion/ej2-base';
|
|
9
|
+
|
|
10
|
+
export type FilterType = 'StartsWith' | 'EndsWith' | 'Contains';
|
|
11
|
+
|
|
12
|
+
export class FieldSettings extends ChildProperty<FieldSettings> {
|
|
13
|
+
/**
|
|
14
|
+
* Maps the text column from data table for each list item
|
|
15
|
+
*
|
|
16
|
+
* @default null
|
|
17
|
+
*/
|
|
18
|
+
@Property()
|
|
19
|
+
public text: string;
|
|
20
|
+
/**
|
|
21
|
+
* Maps the value column from data table for each list item
|
|
22
|
+
*
|
|
23
|
+
* @default null
|
|
24
|
+
*/
|
|
25
|
+
@Property()
|
|
26
|
+
public value: string;
|
|
27
|
+
/**
|
|
28
|
+
* Maps the icon class column from data table for each list item.
|
|
29
|
+
*
|
|
30
|
+
* @default null
|
|
31
|
+
*/
|
|
32
|
+
@Property()
|
|
33
|
+
public iconCss: string;
|
|
34
|
+
/**
|
|
35
|
+
* Group the list items with it's related items by mapping groupBy field.
|
|
36
|
+
*
|
|
37
|
+
* @default null
|
|
38
|
+
*/
|
|
39
|
+
@Property()
|
|
40
|
+
public groupBy: string;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Allows additional attributes such as title, disabled, etc., to configure the elements
|
|
44
|
+
* in various ways to meet the criteria.
|
|
45
|
+
*
|
|
46
|
+
* @default null
|
|
47
|
+
*/
|
|
48
|
+
@Property()
|
|
49
|
+
public htmlAttributes: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const dropDownBaseClasses: DropDownBaseClassList = {
|
|
53
|
+
root: 'e-dropdownbase',
|
|
54
|
+
rtl: 'e-rtl',
|
|
55
|
+
content: 'e-content',
|
|
56
|
+
selected: 'e-active',
|
|
57
|
+
hover: 'e-hover',
|
|
58
|
+
noData: 'e-nodata',
|
|
59
|
+
fixedHead: 'e-fixed-head',
|
|
60
|
+
focus: 'e-item-focus',
|
|
61
|
+
li: 'e-list-item',
|
|
62
|
+
group: 'e-list-group-item',
|
|
63
|
+
disabled: 'e-disabled',
|
|
64
|
+
grouping: 'e-dd-group'
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const ITEMTEMPLATE_PROPERTY: string = 'ItemTemplate';
|
|
68
|
+
const DISPLAYTEMPLATE_PROPERTY: string = 'DisplayTemplate';
|
|
69
|
+
const SPINNERTEMPLATE_PROPERTY: string = 'SpinnerTemplate';
|
|
70
|
+
const VALUETEMPLATE_PROPERTY: string = 'ValueTemplate';
|
|
71
|
+
const GROUPTEMPLATE_PROPERTY: string = 'GroupTemplate';
|
|
72
|
+
const HEADERTEMPLATE_PROPERTY: string = 'HeaderTemplate';
|
|
73
|
+
const FOOTERTEMPLATE_PROPERTY: string = 'FooterTemplate';
|
|
74
|
+
const NORECORDSTEMPLATE_PROPERTY: string = 'NoRecordsTemplate';
|
|
75
|
+
const ACTIONFAILURETEMPLATE_PROPERTY: string = 'ActionFailureTemplate';
|
|
76
|
+
const HIDE_GROUPLIST: string = 'e-hide-group-header';
|
|
77
|
+
|
|
78
|
+
export interface DropDownBaseClassList {
|
|
79
|
+
root: string
|
|
80
|
+
rtl: string
|
|
81
|
+
content: string
|
|
82
|
+
selected: string
|
|
83
|
+
hover: string
|
|
84
|
+
noData: string
|
|
85
|
+
fixedHead: string
|
|
86
|
+
focus: string
|
|
87
|
+
li: string
|
|
88
|
+
disabled: string
|
|
89
|
+
group: string
|
|
90
|
+
grouping: string
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface SelectEventArgs {
|
|
94
|
+
/**
|
|
95
|
+
* If the event is triggered by interaction, it returns true. Otherwise, it returns false.
|
|
96
|
+
*/
|
|
97
|
+
isInteracted: boolean
|
|
98
|
+
/**
|
|
99
|
+
* Returns the selected list item
|
|
100
|
+
*/
|
|
101
|
+
item: HTMLLIElement
|
|
102
|
+
/**
|
|
103
|
+
* Returns the selected item as JSON Object from the data source.
|
|
104
|
+
*
|
|
105
|
+
*/
|
|
106
|
+
itemData: FieldSettingsModel
|
|
107
|
+
/**
|
|
108
|
+
* Specifies the original event arguments.
|
|
109
|
+
*/
|
|
110
|
+
e: MouseEvent | KeyboardEvent | TouchEvent
|
|
111
|
+
/**
|
|
112
|
+
* Illustrates whether the current action needs to be prevented or not.
|
|
113
|
+
*/
|
|
114
|
+
cancel?: boolean
|
|
115
|
+
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface BeforeOpenEventArgs {
|
|
119
|
+
/**
|
|
120
|
+
* Illustrates whether the current action needs to be prevented or not.
|
|
121
|
+
*/
|
|
122
|
+
cancel?: boolean
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface ActionBeginEventArgs {
|
|
126
|
+
/**
|
|
127
|
+
* Specify the query to begin the data
|
|
128
|
+
*
|
|
129
|
+
*/
|
|
130
|
+
query: Query
|
|
131
|
+
/**
|
|
132
|
+
* Set the data source to action begin
|
|
133
|
+
*
|
|
134
|
+
*/
|
|
135
|
+
data: { [key: string]: Object }[] | DataManager | string[] | number[] | boolean[]
|
|
136
|
+
/**
|
|
137
|
+
* Illustrates whether the current action needs to be prevented or not.
|
|
138
|
+
*/
|
|
139
|
+
cancel?: boolean
|
|
140
|
+
/**
|
|
141
|
+
* Specify the Event Name
|
|
142
|
+
*/
|
|
143
|
+
eventName?: string
|
|
144
|
+
/**
|
|
145
|
+
* Return Items
|
|
146
|
+
*/
|
|
147
|
+
items?: Object[]
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export interface ActionCompleteEventArgs {
|
|
151
|
+
/**
|
|
152
|
+
* Illustrates whether the current action needs to be prevented or not.
|
|
153
|
+
*/
|
|
154
|
+
cancel?: boolean
|
|
155
|
+
/**
|
|
156
|
+
* Returns the selected items as JSON Object from the data source.
|
|
157
|
+
*
|
|
158
|
+
*/
|
|
159
|
+
result?: ResultData
|
|
160
|
+
/**
|
|
161
|
+
* Return the actual records.
|
|
162
|
+
*/
|
|
163
|
+
actual?: object
|
|
164
|
+
/**
|
|
165
|
+
* Return the aggregates
|
|
166
|
+
*/
|
|
167
|
+
aggregates?: object
|
|
168
|
+
/**
|
|
169
|
+
* Return the total number for records.
|
|
170
|
+
*/
|
|
171
|
+
count?: number
|
|
172
|
+
/**
|
|
173
|
+
* Specify the query to complete the data
|
|
174
|
+
*
|
|
175
|
+
*/
|
|
176
|
+
query?: Query
|
|
177
|
+
/**
|
|
178
|
+
* Return the request type
|
|
179
|
+
*/
|
|
180
|
+
request?: string
|
|
181
|
+
/**
|
|
182
|
+
* Return the virtualSelectRecords
|
|
183
|
+
*/
|
|
184
|
+
virtualSelectRecords?: object
|
|
185
|
+
/**
|
|
186
|
+
* Return XMLHttpRequest
|
|
187
|
+
*/
|
|
188
|
+
xhr: XMLHttpRequest
|
|
189
|
+
/**
|
|
190
|
+
* Specify the Event Name
|
|
191
|
+
*/
|
|
192
|
+
eventName?: string
|
|
193
|
+
/**
|
|
194
|
+
* Return Items
|
|
195
|
+
*/
|
|
196
|
+
items?: Object[]
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export interface DataBoundEventArgs {
|
|
200
|
+
/**
|
|
201
|
+
* Returns the selected items as JSON Object from the data source.
|
|
202
|
+
*
|
|
203
|
+
*/
|
|
204
|
+
items: { [key: string]: Object }[] | DataManager | string[] | number[] | boolean[]
|
|
205
|
+
/**
|
|
206
|
+
* Return the bounded objects
|
|
207
|
+
*/
|
|
208
|
+
e?: object
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* DropDownBase component will generate the list items based on given data and act as base class to drop-down related components
|
|
213
|
+
*/
|
|
214
|
+
@NotifyPropertyChanges
|
|
215
|
+
export class DropDownBase extends Component<HTMLElement> implements INotifyPropertyChanged {
|
|
216
|
+
protected listData: { [key: string]: Object }[] | string[] | boolean[] | number[];
|
|
217
|
+
protected ulElement: HTMLElement;
|
|
218
|
+
protected liCollections: HTMLElement[];
|
|
219
|
+
private bindEvent: boolean;
|
|
220
|
+
private scrollTimer: number;
|
|
221
|
+
protected list: HTMLElement;
|
|
222
|
+
protected fixedHeaderElement: HTMLElement;
|
|
223
|
+
protected keyboardModule: KeyboardEvents;
|
|
224
|
+
protected enableRtlElements: HTMLElement[];
|
|
225
|
+
protected rippleFun: Function;
|
|
226
|
+
protected l10n: L10n;
|
|
227
|
+
protected item: HTMLLIElement;
|
|
228
|
+
protected itemData: { [key: string]: Object } | string | number | boolean;
|
|
229
|
+
protected isActive: boolean;
|
|
230
|
+
protected isRequested: boolean;
|
|
231
|
+
protected isDataFetched: boolean;
|
|
232
|
+
protected selectData: { [key: string]: Object }[] | string[] | boolean[] | number[];
|
|
233
|
+
protected queryString: string;
|
|
234
|
+
protected sortedData: { [key: string]: Object }[] | string[] | boolean[] | number[];
|
|
235
|
+
protected isGroupChecking: boolean;
|
|
236
|
+
protected itemTemplateId: string;
|
|
237
|
+
protected displayTemplateId: string;
|
|
238
|
+
protected spinnerTemplateId: string;
|
|
239
|
+
protected valueTemplateId: string;
|
|
240
|
+
protected groupTemplateId: string;
|
|
241
|
+
protected headerTemplateId: string;
|
|
242
|
+
protected footerTemplateId: string;
|
|
243
|
+
protected noRecordsTemplateId: string;
|
|
244
|
+
protected actionFailureTemplateId: string;
|
|
245
|
+
protected preventChange: boolean = false;
|
|
246
|
+
protected isAngular: boolean = false;
|
|
247
|
+
protected isPreventChange: boolean = false;
|
|
248
|
+
protected isDynamicDataChange: boolean = false;
|
|
249
|
+
protected addedNewItem: boolean = false;
|
|
250
|
+
protected isAddNewItemTemplate: boolean = false;
|
|
251
|
+
private isRequesting: boolean = false;
|
|
252
|
+
private isVirtualizationEnabled: boolean = false;
|
|
253
|
+
private isAllowFiltering: boolean = false;
|
|
254
|
+
private virtualizedItemsCount: number = 0;
|
|
255
|
+
protected totalItemCount: number = 0;
|
|
256
|
+
protected dataCount: number = 0;
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* The `fields` property maps the columns of the data table and binds the data to the component.
|
|
260
|
+
* * text - Maps the text column from data table for each list item.
|
|
261
|
+
* * value - Maps the value column from data table for each list item.
|
|
262
|
+
* * iconCss - Maps the icon class column from data table for each list item.
|
|
263
|
+
* * groupBy - Group the list items with it's related items by mapping groupBy field.
|
|
264
|
+
* ```html
|
|
265
|
+
* <input type="text" tabindex="1" id="list"> </input>
|
|
266
|
+
* ```
|
|
267
|
+
* ```typescript
|
|
268
|
+
* let customers: DropDownList = new DropDownList({
|
|
269
|
+
* dataSource:new DataManager({ url:'http://js.syncfusion.com/demos/ejServices/Wcf/Northwind.svc/' }),
|
|
270
|
+
* query: new Query().from('Customers').select(['ContactName', 'CustomerID']).take(5),
|
|
271
|
+
* fields: { text: 'ContactName', value: 'CustomerID' },
|
|
272
|
+
* placeholder: 'Select a customer'
|
|
273
|
+
* });
|
|
274
|
+
* customers.appendTo("#list");
|
|
275
|
+
* ```
|
|
276
|
+
*
|
|
277
|
+
* @default {text: null, value: null, iconCss: null, groupBy: null}
|
|
278
|
+
* @deprecated
|
|
279
|
+
*/
|
|
280
|
+
@Complex<FieldSettingsModel>({ text: null, value: null, iconCss: null, groupBy: null }, FieldSettings)
|
|
281
|
+
public fields: FieldSettingsModel;
|
|
282
|
+
/**
|
|
283
|
+
* Accepts the template design and assigns it to each list item present in the popup.
|
|
284
|
+
* We have built-in `template engine`
|
|
285
|
+
*
|
|
286
|
+
* which provides options to compile template string into a executable function.
|
|
287
|
+
* For EX: We have expression evolution as like ES6 expression string literals.
|
|
288
|
+
*
|
|
289
|
+
* @default null
|
|
290
|
+
* @aspType string
|
|
291
|
+
* @deprecated
|
|
292
|
+
*/
|
|
293
|
+
@Property(null)
|
|
294
|
+
public itemTemplate: string | Function;
|
|
295
|
+
/**
|
|
296
|
+
* Accepts the template design and assigns it to the group headers present in the popup list.
|
|
297
|
+
*
|
|
298
|
+
* @default null
|
|
299
|
+
* @aspType string
|
|
300
|
+
* @deprecated
|
|
301
|
+
*/
|
|
302
|
+
@Property(null)
|
|
303
|
+
public groupTemplate: string | Function;
|
|
304
|
+
/**
|
|
305
|
+
* Accepts the template design and assigns it to popup list of component
|
|
306
|
+
* when no data is available on the component.
|
|
307
|
+
*
|
|
308
|
+
* @default 'No records found'
|
|
309
|
+
* @aspType string
|
|
310
|
+
* @deprecated
|
|
311
|
+
*/
|
|
312
|
+
@Property('No records found')
|
|
313
|
+
public noRecordsTemplate: string | Function;
|
|
314
|
+
/**
|
|
315
|
+
* Accepts the template and assigns it to the popup list content of the component
|
|
316
|
+
* when the data fetch request from the remote server fails.
|
|
317
|
+
*
|
|
318
|
+
* @default 'Request failed'
|
|
319
|
+
* @aspType string
|
|
320
|
+
* @deprecated
|
|
321
|
+
*/
|
|
322
|
+
@Property('Request failed')
|
|
323
|
+
public actionFailureTemplate: string | Function;
|
|
324
|
+
/**
|
|
325
|
+
* Specifies the `sortOrder` to sort the data source. The available type of sort orders are
|
|
326
|
+
* * `None` - The data source is not sorting.
|
|
327
|
+
* * `Ascending` - The data source is sorting with ascending order.
|
|
328
|
+
* * `Descending` - The data source is sorting with descending order.
|
|
329
|
+
*
|
|
330
|
+
* @default null
|
|
331
|
+
* @asptype object
|
|
332
|
+
* @aspjsonconverterignore
|
|
333
|
+
* @deprecated
|
|
334
|
+
*/
|
|
335
|
+
@Property<SortOrder>('None')
|
|
336
|
+
public sortOrder: SortOrder;
|
|
337
|
+
/**
|
|
338
|
+
* Accepts the list items either through local or remote service and binds it to the component.
|
|
339
|
+
* It can be an array of JSON Objects or an instance of
|
|
340
|
+
* `DataManager`.
|
|
341
|
+
*
|
|
342
|
+
* @default []
|
|
343
|
+
* @deprecated
|
|
344
|
+
*/
|
|
345
|
+
@Property([])
|
|
346
|
+
public dataSource: { [key: string]: Object }[] | DataManager | string[] | number[] | boolean[];
|
|
347
|
+
/**
|
|
348
|
+
* Accepts the external `Query`
|
|
349
|
+
* which will execute along with the data processing.
|
|
350
|
+
*
|
|
351
|
+
* @default null
|
|
352
|
+
* @deprecated
|
|
353
|
+
*/
|
|
354
|
+
@Property(null)
|
|
355
|
+
public query: Query;
|
|
356
|
+
/**
|
|
357
|
+
* Determines on which filter type, the component needs to be considered on search action.
|
|
358
|
+
* The `FilterType` and its supported data types are
|
|
359
|
+
*
|
|
360
|
+
* <table>
|
|
361
|
+
* <tr>
|
|
362
|
+
* <td colSpan=1 rowSpan=1>
|
|
363
|
+
* FilterType<br/></td><td colSpan=1 rowSpan=1>
|
|
364
|
+
* Description<br/></td><td colSpan=1 rowSpan=1>
|
|
365
|
+
* Supported Types<br/></td></tr>
|
|
366
|
+
* <tr>
|
|
367
|
+
* <td colSpan=1 rowSpan=1>
|
|
368
|
+
* StartsWith<br/></td><td colSpan=1 rowSpan=1>
|
|
369
|
+
* Checks whether a value begins with the specified value.<br/></td><td colSpan=1 rowSpan=1>
|
|
370
|
+
* String<br/></td></tr>
|
|
371
|
+
* <tr>
|
|
372
|
+
* <td colSpan=1 rowSpan=1>
|
|
373
|
+
* EndsWith<br/></td><td colSpan=1 rowSpan=1>
|
|
374
|
+
* Checks whether a value ends with specified value.<br/><br/></td><td colSpan=1 rowSpan=1>
|
|
375
|
+
* <br/>String<br/></td></tr>
|
|
376
|
+
* <tr>
|
|
377
|
+
* <td colSpan=1 rowSpan=1>
|
|
378
|
+
* Contains<br/></td><td colSpan=1 rowSpan=1>
|
|
379
|
+
* Checks whether a value contains with specified value.<br/><br/></td><td colSpan=1 rowSpan=1>
|
|
380
|
+
* <br/>String<br/></td></tr>
|
|
381
|
+
* </table>
|
|
382
|
+
*
|
|
383
|
+
* The default value set to `StartsWith`, all the suggestion items which contain typed characters to listed in the suggestion popup.
|
|
384
|
+
*
|
|
385
|
+
* @default 'StartsWith'
|
|
386
|
+
* @deprecated
|
|
387
|
+
*/
|
|
388
|
+
@Property('StartsWith')
|
|
389
|
+
public filterType: FilterType;
|
|
390
|
+
/**
|
|
391
|
+
* When set to ‘false’, consider the `case-sensitive` on performing the search to find suggestions.
|
|
392
|
+
* By default consider the casing.
|
|
393
|
+
*
|
|
394
|
+
* @default true
|
|
395
|
+
* @deprecated
|
|
396
|
+
*/
|
|
397
|
+
@Property(true)
|
|
398
|
+
public ignoreCase: boolean;
|
|
399
|
+
/**
|
|
400
|
+
* specifies the z-index value of the component popup element.
|
|
401
|
+
*
|
|
402
|
+
* @default 1000
|
|
403
|
+
* @deprecated
|
|
404
|
+
*/
|
|
405
|
+
@Property(1000)
|
|
406
|
+
public zIndex: number;
|
|
407
|
+
/**
|
|
408
|
+
* ignoreAccent set to true, then ignores the diacritic characters or accents when filtering.
|
|
409
|
+
*
|
|
410
|
+
* @deprecated
|
|
411
|
+
*/
|
|
412
|
+
@Property(false)
|
|
413
|
+
public ignoreAccent: boolean;
|
|
414
|
+
/**
|
|
415
|
+
* Overrides the global culture and localization value for this component. Default global culture is 'en-US'.
|
|
416
|
+
*
|
|
417
|
+
* @default 'en-US'
|
|
418
|
+
* @deprecated
|
|
419
|
+
*/
|
|
420
|
+
@Property()
|
|
421
|
+
public locale: string;
|
|
422
|
+
/**
|
|
423
|
+
* Triggers before fetching data from the remote server.
|
|
424
|
+
*
|
|
425
|
+
* @event actionBegin
|
|
426
|
+
*/
|
|
427
|
+
@Event()
|
|
428
|
+
public actionBegin: EmitType<Object>;
|
|
429
|
+
/**
|
|
430
|
+
* Triggers after data is fetched successfully from the remote server.
|
|
431
|
+
*
|
|
432
|
+
* @event actionComplete
|
|
433
|
+
*/
|
|
434
|
+
@Event()
|
|
435
|
+
public actionComplete: EmitType<Object>;
|
|
436
|
+
/**
|
|
437
|
+
* Triggers when the data fetch request from the remote server fails.
|
|
438
|
+
*
|
|
439
|
+
* @event actionFailure
|
|
440
|
+
*/
|
|
441
|
+
@Event()
|
|
442
|
+
public actionFailure: EmitType<Object>;
|
|
443
|
+
/**
|
|
444
|
+
* Triggers when an item in the popup is selected by the user either with mouse/tap or with keyboard navigation.
|
|
445
|
+
*
|
|
446
|
+
* @event select
|
|
447
|
+
*/
|
|
448
|
+
@Event()
|
|
449
|
+
public select: EmitType<SelectEventArgs>;
|
|
450
|
+
/**
|
|
451
|
+
* Triggers when data source is populated in the popup list..
|
|
452
|
+
*
|
|
453
|
+
* @event dataBound
|
|
454
|
+
*/
|
|
455
|
+
@Event()
|
|
456
|
+
public dataBound: EmitType<Object>;
|
|
457
|
+
/**
|
|
458
|
+
* Triggers when the component is created.
|
|
459
|
+
*
|
|
460
|
+
* @event created
|
|
461
|
+
*/
|
|
462
|
+
@Event()
|
|
463
|
+
public created: EmitType<Object>;
|
|
464
|
+
/**
|
|
465
|
+
* Triggers when the component is destroyed.
|
|
466
|
+
*
|
|
467
|
+
* @event destroyed
|
|
468
|
+
*/
|
|
469
|
+
@Event()
|
|
470
|
+
public destroyed: EmitType<Object>;
|
|
471
|
+
/**
|
|
472
|
+
* * Constructor for DropDownBase class
|
|
473
|
+
*
|
|
474
|
+
* @param {DropDownBaseModel} options - Specifies the DropDownBase model.
|
|
475
|
+
* @param {string | HTMLElement} element - Specifies the element to render as component.
|
|
476
|
+
* @private
|
|
477
|
+
*/
|
|
478
|
+
public constructor(options?: DropDownBaseModel, element?: string | HTMLElement) {
|
|
479
|
+
super(options, element);
|
|
480
|
+
}
|
|
481
|
+
protected getPropObject(
|
|
482
|
+
prop: string, newProp: { [key: string]: string }, oldProp: { [key: string]: string }): { [key: string]: Object } {
|
|
483
|
+
const newProperty: { [key: string]: string } = <{ [key: string]: string }>new Object();
|
|
484
|
+
const oldProperty: { [key: string]: string } = <{ [key: string]: string }>new Object();
|
|
485
|
+
const propName: Function = (prop: string) => {
|
|
486
|
+
return prop;
|
|
487
|
+
};
|
|
488
|
+
newProperty[propName(prop)] = (newProp as { [key: string]: string })[propName(prop)];
|
|
489
|
+
oldProperty[propName(prop)] = (oldProp as { [key: string]: string })[propName(prop)];
|
|
490
|
+
const data: { [key: string]: Object } = <{ [key: string]: Object }>new Object();
|
|
491
|
+
data.newProperty = newProperty;
|
|
492
|
+
data.oldProperty = oldProperty;
|
|
493
|
+
return data;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
protected getValueByText(text: string, ignoreCase?: boolean, ignoreAccent?: boolean): string | number | boolean {
|
|
497
|
+
let value: string | number | boolean = null;
|
|
498
|
+
if (!isNullOrUndefined(this.listData)) {
|
|
499
|
+
if (ignoreCase) {
|
|
500
|
+
value = this.checkValueCase(text, true, ignoreAccent);
|
|
501
|
+
} else {
|
|
502
|
+
value = this.checkValueCase(text, false, ignoreAccent);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
return value;
|
|
506
|
+
}
|
|
507
|
+
private checkValueCase(text: string, ignoreCase: boolean, ignoreAccent: boolean, isTextByValue?: boolean): string | number {
|
|
508
|
+
let value: string | number = null;
|
|
509
|
+
if (isTextByValue) {
|
|
510
|
+
value = text;
|
|
511
|
+
}
|
|
512
|
+
const dataSource: { [key: string]: Object }[] = this.listData as { [key: string]: Object }[];
|
|
513
|
+
const fields: FieldSettingsModel = this.fields;
|
|
514
|
+
const type: string = this.typeOfData(dataSource).typeof as string;
|
|
515
|
+
if (type === 'string' || type === 'number' || type === 'boolean') {
|
|
516
|
+
for (const item of dataSource) {
|
|
517
|
+
if (!isNullOrUndefined(item)) {
|
|
518
|
+
if (ignoreAccent) {
|
|
519
|
+
value = this.checkingAccent(String(item), text, ignoreCase);
|
|
520
|
+
} else {
|
|
521
|
+
if (ignoreCase) {
|
|
522
|
+
if (this.checkIgnoreCase(String(item), text)) {
|
|
523
|
+
value = this.getItemValue(String(item), text, ignoreCase);
|
|
524
|
+
}
|
|
525
|
+
} else {
|
|
526
|
+
if (this.checkNonIgnoreCase(String(item), text)) {
|
|
527
|
+
value = this.getItemValue(String(item), text, ignoreCase, isTextByValue);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
} else {
|
|
534
|
+
if (ignoreCase) {
|
|
535
|
+
(dataSource as { [key: string]: Object }[]).filter((item: { [key: string]: Object }) => {
|
|
536
|
+
const itemValue: string | number = getValue(fields.value, item);
|
|
537
|
+
if (!isNullOrUndefined(itemValue) && this.checkIgnoreCase(getValue(fields.text, item).toString(), text)) {
|
|
538
|
+
value = <string>getValue(fields.value, item);
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
} else {
|
|
542
|
+
if (isTextByValue) {
|
|
543
|
+
let compareValue: string | number = null;
|
|
544
|
+
compareValue = value;
|
|
545
|
+
dataSource.filter((item: { [key: string]: Object }) => {
|
|
546
|
+
const itemValue: string | number = getValue(fields.value, item);
|
|
547
|
+
if (!isNullOrUndefined(itemValue) && !isNullOrUndefined(value) && itemValue.toString() === compareValue.toString()) {
|
|
548
|
+
value = getValue(fields.text, item) as string;
|
|
549
|
+
}
|
|
550
|
+
});
|
|
551
|
+
} else {
|
|
552
|
+
dataSource.filter((item: { [key: string]: Object }) => {
|
|
553
|
+
if (this.checkNonIgnoreCase(getValue(fields.text, item), text)) {
|
|
554
|
+
value = <string>getValue(fields.value, item);
|
|
555
|
+
}
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
return value;
|
|
561
|
+
}
|
|
562
|
+
private checkingAccent(item: string, text: string, ignoreCase: boolean): string {
|
|
563
|
+
const dataItem: string | object = DataUtil.ignoreDiacritics(String(item));
|
|
564
|
+
const textItem: string | object = DataUtil.ignoreDiacritics(text.toString());
|
|
565
|
+
let value: string | number = null;
|
|
566
|
+
if (ignoreCase) {
|
|
567
|
+
if (this.checkIgnoreCase(dataItem as string, textItem as string)) {
|
|
568
|
+
value = this.getItemValue(String(item), text, ignoreCase);
|
|
569
|
+
}
|
|
570
|
+
} else {
|
|
571
|
+
if (this.checkNonIgnoreCase(String(item), text)) {
|
|
572
|
+
value = this.getItemValue(String(item), text, ignoreCase);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
return (value as string);
|
|
576
|
+
}
|
|
577
|
+
private checkIgnoreCase(item: string, text: string): boolean {
|
|
578
|
+
return String(item).toLowerCase() === text.toString().toLowerCase() ? true : false;
|
|
579
|
+
}
|
|
580
|
+
private checkNonIgnoreCase(item: string, text: string): boolean {
|
|
581
|
+
return String(item) === text.toString() ? true : false;
|
|
582
|
+
}
|
|
583
|
+
private getItemValue(dataItem: string, typedText: string, ignoreCase: boolean, isTextByValue?: boolean): string {
|
|
584
|
+
let value: string | number | boolean = null;
|
|
585
|
+
const dataSource: { [key: string]: Object }[] = this.listData as { [key: string]: Object }[];
|
|
586
|
+
const type: string = this.typeOfData(dataSource).typeof as string;
|
|
587
|
+
if (isTextByValue) {
|
|
588
|
+
value = dataItem.toString();
|
|
589
|
+
} else {
|
|
590
|
+
if (ignoreCase) {
|
|
591
|
+
value = type === 'string' ? String(dataItem) : this.getFormattedValue(String(dataItem));
|
|
592
|
+
} else {
|
|
593
|
+
value = type === 'string' ? typedText : this.getFormattedValue(typedText);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
return value as string;
|
|
597
|
+
}
|
|
598
|
+
private templateCompiler(baseTemplate: string | Function): boolean {
|
|
599
|
+
let checkTemplate: boolean = false;
|
|
600
|
+
if (typeof baseTemplate !== 'function' && baseTemplate) {
|
|
601
|
+
try {
|
|
602
|
+
checkTemplate = (selectAll(baseTemplate, document).length) ? true : false;
|
|
603
|
+
} catch (exception) {
|
|
604
|
+
checkTemplate = false;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
return checkTemplate;
|
|
608
|
+
}
|
|
609
|
+
protected l10nUpdate(actionFailure?: boolean): void {
|
|
610
|
+
const ele: Element = this.getModuleName() === 'listbox' ? this.ulElement : this.list;
|
|
611
|
+
if (this.noRecordsTemplate !== 'No records found' || this.actionFailureTemplate !== 'Request failed') {
|
|
612
|
+
const template: string | Function = actionFailure ? this.actionFailureTemplate : this.noRecordsTemplate;
|
|
613
|
+
let compiledString: Function;
|
|
614
|
+
const templateId: string = actionFailure ? this.actionFailureTemplateId : this.noRecordsTemplateId;
|
|
615
|
+
ele.innerHTML = '';
|
|
616
|
+
const tempaltecheck: boolean = this.templateCompiler(template);
|
|
617
|
+
if (typeof template !== 'function' && tempaltecheck) {
|
|
618
|
+
compiledString = compile(select(template, document).innerHTML.trim());
|
|
619
|
+
} else {
|
|
620
|
+
compiledString = compile(template);
|
|
621
|
+
}
|
|
622
|
+
const templateName: string = actionFailure ? 'actionFailureTemplate' : 'noRecordsTemplate';
|
|
623
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
624
|
+
let noDataElement: any;
|
|
625
|
+
if (((this as any).isReact) && typeof template === 'function') {
|
|
626
|
+
noDataElement = compiledString({}, this, templateName, templateId, this.isStringTemplate, null);
|
|
627
|
+
}
|
|
628
|
+
else {
|
|
629
|
+
noDataElement = compiledString({}, this, templateName, templateId, this.isStringTemplate, null, ele);
|
|
630
|
+
}
|
|
631
|
+
if (noDataElement && noDataElement.length > 0) {
|
|
632
|
+
for (let i: number = 0; i < noDataElement.length; i++) {
|
|
633
|
+
if (this.getModuleName() === 'listbox' && templateName === 'noRecordsTemplate') {
|
|
634
|
+
if (noDataElement[i as number].nodeName === '#text') {
|
|
635
|
+
const liElem: HTMLElement = this.createElement('li');
|
|
636
|
+
liElem.textContent = noDataElement[i as number].textContent;
|
|
637
|
+
liElem.classList.add('e-list-nrt');
|
|
638
|
+
liElem.setAttribute('role','option')
|
|
639
|
+
ele.appendChild(liElem);
|
|
640
|
+
} else {
|
|
641
|
+
noDataElement[i as number].classList.add('e-list-nr-template');
|
|
642
|
+
ele.appendChild(noDataElement[i as number]);
|
|
643
|
+
}
|
|
644
|
+
} else {
|
|
645
|
+
if(noDataElement[i as number] instanceof HTMLElement)
|
|
646
|
+
{
|
|
647
|
+
ele.appendChild(noDataElement[i as number]);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
this.renderReactTemplates();
|
|
653
|
+
} else {
|
|
654
|
+
const l10nLocale: Object = { noRecordsTemplate: 'No records found', actionFailureTemplate: 'Request failed'};
|
|
655
|
+
const componentLocale: L10n = new L10n(this.getLocaleName(), {}, this.locale);
|
|
656
|
+
if (componentLocale.getConstant('actionFailureTemplate') !== '' || componentLocale.getConstant('noRecordsTemplate') !== '') {
|
|
657
|
+
this.l10n = componentLocale;
|
|
658
|
+
} else {
|
|
659
|
+
this.l10n = new L10n(this.getModuleName() === 'listbox' ? 'listbox' :
|
|
660
|
+
this.getModuleName() === 'mention' ? 'mention' : 'dropdowns', l10nLocale, this.locale);
|
|
661
|
+
}
|
|
662
|
+
const content: string = actionFailure ?
|
|
663
|
+
this.l10n.getConstant('actionFailureTemplate') : this.l10n.getConstant('noRecordsTemplate');
|
|
664
|
+
if (this.getModuleName() === 'listbox') {
|
|
665
|
+
const liElem: Element = this.createElement('li');
|
|
666
|
+
liElem.textContent = content;
|
|
667
|
+
ele.appendChild(liElem);
|
|
668
|
+
liElem.classList.add('e-list-nrt');
|
|
669
|
+
liElem.setAttribute('role','option')
|
|
670
|
+
} else {
|
|
671
|
+
if (!isNullOrUndefined(ele)) {
|
|
672
|
+
ele.innerHTML = content;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
protected getLocaleName(): string {
|
|
679
|
+
return 'drop-down-base';
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
protected getTextByValue(value: string | number | boolean): string {
|
|
683
|
+
const text: string = this.checkValueCase(value as string, false, false, true) as string;
|
|
684
|
+
return text;
|
|
685
|
+
}
|
|
686
|
+
protected getFormattedValue(value: string): string | number | boolean {
|
|
687
|
+
if (this.listData && this.listData.length) {
|
|
688
|
+
let item: { [key: string]: Object };
|
|
689
|
+
if(this.properties.allowCustomValue && this.properties.value && this.properties.value instanceof Array && this.properties.value.length > 0) {
|
|
690
|
+
item = this.typeOfData(this.properties.value);
|
|
691
|
+
}else{
|
|
692
|
+
item = this.typeOfData(this.listData);
|
|
693
|
+
}
|
|
694
|
+
if (typeof getValue((this.fields.value ? this.fields.value : 'value'), item.item as { [key: string]: Object }) === 'number'
|
|
695
|
+
|| item.typeof === 'number') {
|
|
696
|
+
return parseFloat(value);
|
|
697
|
+
}
|
|
698
|
+
if (typeof getValue((this.fields.value ? this.fields.value : 'value'), item.item as { [key: string]: Object }) === 'boolean'
|
|
699
|
+
|| item.typeof === 'boolean') {
|
|
700
|
+
return ((value === 'true') || ('' + value === 'true'));
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
return value;
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Sets RTL to dropdownbase wrapper
|
|
707
|
+
*
|
|
708
|
+
* @returns {void}
|
|
709
|
+
*/
|
|
710
|
+
protected setEnableRtl(): void {
|
|
711
|
+
if (!isNullOrUndefined(this.enableRtlElements)) {
|
|
712
|
+
if (this.list) {
|
|
713
|
+
this.enableRtlElements.push(this.list);
|
|
714
|
+
}
|
|
715
|
+
if (this.enableRtl) {
|
|
716
|
+
addClass(this.enableRtlElements, dropDownBaseClasses.rtl);
|
|
717
|
+
} else {
|
|
718
|
+
removeClass(this.enableRtlElements, dropDownBaseClasses.rtl);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* Initialize the Component.
|
|
724
|
+
*
|
|
725
|
+
* @returns {void}
|
|
726
|
+
*/
|
|
727
|
+
private initialize(e?: MouseEvent | KeyboardEventArgs | TouchEvent): void {
|
|
728
|
+
this.bindEvent = true;
|
|
729
|
+
this.actionFailureTemplateId = `${this.element.id}${ACTIONFAILURETEMPLATE_PROPERTY}`;
|
|
730
|
+
if (this.element.tagName === 'UL') {
|
|
731
|
+
const jsonElement: { [key: string]: Object }[] = ListBase.createJsonFromElement(this.element);
|
|
732
|
+
this.setProperties({ fields: { text: 'text', value: 'text' } }, true);
|
|
733
|
+
this.resetList(jsonElement, this.fields);
|
|
734
|
+
} else if (this.element.tagName === 'SELECT') {
|
|
735
|
+
const dataSource: boolean = this.dataSource instanceof Array ? (this.dataSource.length > 0 ? true : false)
|
|
736
|
+
: !isNullOrUndefined(this.dataSource) ? true : false;
|
|
737
|
+
if (!dataSource) {
|
|
738
|
+
this.renderItemsBySelect();
|
|
739
|
+
} else if (this.isDynamicDataChange) {
|
|
740
|
+
this.setListData(this.dataSource, this.fields, this.query);
|
|
741
|
+
}
|
|
742
|
+
} else {
|
|
743
|
+
this.setListData(this.dataSource, this.fields, this.query, e);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
/**
|
|
747
|
+
* Get the properties to be maintained in persisted state.
|
|
748
|
+
*
|
|
749
|
+
* @returns {string} Returns the persisted data of the component.
|
|
750
|
+
*/
|
|
751
|
+
protected getPersistData(): string {
|
|
752
|
+
return this.addOnPersist([]);
|
|
753
|
+
}
|
|
754
|
+
/**
|
|
755
|
+
* Sets the enabled state to DropDownBase.
|
|
756
|
+
*
|
|
757
|
+
* @param {string} value - Specifies the attribute values to add on the input element.
|
|
758
|
+
* @returns {void}
|
|
759
|
+
*/
|
|
760
|
+
protected updateDataAttribute(value: { [key: string]: string }) : void {
|
|
761
|
+
const invalidAttr: string[] = ['class', 'style', 'id', 'type','aria-expanded','aria-autocomplete','aria-readonly'];
|
|
762
|
+
const attr: { [key: string]: string } = {};
|
|
763
|
+
for (let a: number = 0; a < this.element.attributes.length; a++) {
|
|
764
|
+
if (invalidAttr.indexOf(this.element.attributes[a as number].name) === -1 &&
|
|
765
|
+
!( this.getModuleName() === 'dropdownlist' && this.element.attributes[a as number].name === 'readonly')) {
|
|
766
|
+
attr[this.element.attributes[a as number].name] = this.element.getAttribute(this.element.attributes[a as number].name);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
extend(attr, value, attr);
|
|
770
|
+
this.setProperties({ htmlAttributes: attr }, true);
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
private renderItemsBySelect(): void {
|
|
774
|
+
const element: Element = this.element;
|
|
775
|
+
const fields: FieldSettingsModel = { value: 'value', text: 'text' };
|
|
776
|
+
const jsonElement: { [key: string]: Object }[] = [];
|
|
777
|
+
const group: HTMLElement[] = <HTMLElement[] & NodeListOf<HTMLElement>>element.querySelectorAll('select>optgroup');
|
|
778
|
+
const option: HTMLOptionElement[] = <HTMLOptionElement[] & NodeListOf<HTMLOptionElement>>element.querySelectorAll('select>option');
|
|
779
|
+
this.getJSONfromOption(jsonElement, option, fields);
|
|
780
|
+
if (group.length) {
|
|
781
|
+
for (let i: number = 0; i < group.length; i++) {
|
|
782
|
+
const item: HTMLOptGroupElement = group[i as number] as HTMLOptGroupElement;
|
|
783
|
+
const optionGroup: { [key: string]: {} } = {};
|
|
784
|
+
optionGroup[fields.text] = item.label;
|
|
785
|
+
optionGroup.isHeader = true;
|
|
786
|
+
const child: HTMLOptionElement[] = <HTMLOptionElement[] & NodeListOf<HTMLOptionElement>>item.querySelectorAll('option');
|
|
787
|
+
jsonElement.push(optionGroup);
|
|
788
|
+
this.getJSONfromOption(jsonElement, child, fields);
|
|
789
|
+
}
|
|
790
|
+
element.querySelectorAll('select>option');
|
|
791
|
+
}
|
|
792
|
+
this.updateFields(fields.text, fields.value, this.fields.groupBy, this.fields.htmlAttributes, this.fields.iconCss);
|
|
793
|
+
this.resetList(jsonElement, fields);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
private updateFields(text?: string, value?: string, groupBy?: string, htmlAttributes?: string, iconCss?: string): void {
|
|
797
|
+
const field: Object = {
|
|
798
|
+
'fields': {
|
|
799
|
+
text: text,
|
|
800
|
+
value: value,
|
|
801
|
+
groupBy: !isNullOrUndefined(groupBy) ? groupBy : this.fields && this.fields.groupBy,
|
|
802
|
+
htmlAttributes: !isNullOrUndefined(htmlAttributes) ? htmlAttributes : this.fields && this.fields.htmlAttributes,
|
|
803
|
+
iconCss: !isNullOrUndefined(iconCss) ? iconCss : this.fields && this.fields.iconCss
|
|
804
|
+
}
|
|
805
|
+
};
|
|
806
|
+
this.setProperties(field, true);
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
private getJSONfromOption(
|
|
810
|
+
items: { [key: string]: Object }[],
|
|
811
|
+
options: HTMLOptionElement[],
|
|
812
|
+
fields: FieldSettingsModel): void {
|
|
813
|
+
for (const option of options) {
|
|
814
|
+
const json: { [key: string]: {} } = {};
|
|
815
|
+
json[fields.text] = option.innerText;
|
|
816
|
+
json[fields.value] = !isNullOrUndefined(option.getAttribute(fields.value)) ?
|
|
817
|
+
option.getAttribute(fields.value) : option.innerText;
|
|
818
|
+
items.push(json);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Execute before render the list items
|
|
823
|
+
*
|
|
824
|
+
* @private
|
|
825
|
+
* @returns {void}
|
|
826
|
+
*/
|
|
827
|
+
protected preRender(): void {
|
|
828
|
+
// there is no event handler
|
|
829
|
+
this.scrollTimer = -1;
|
|
830
|
+
this.enableRtlElements = [];
|
|
831
|
+
this.isRequested = false;
|
|
832
|
+
this.isDataFetched = false;
|
|
833
|
+
this.itemTemplateId = `${this.element.id}${ITEMTEMPLATE_PROPERTY}`;
|
|
834
|
+
this.displayTemplateId = `${this.element.id}${DISPLAYTEMPLATE_PROPERTY}`;
|
|
835
|
+
this.spinnerTemplateId = `${this.element.id}${SPINNERTEMPLATE_PROPERTY}`;
|
|
836
|
+
this.valueTemplateId = `${this.element.id}${VALUETEMPLATE_PROPERTY}`;
|
|
837
|
+
this.groupTemplateId = `${this.element.id}${GROUPTEMPLATE_PROPERTY}`;
|
|
838
|
+
this.headerTemplateId = `${this.element.id}${HEADERTEMPLATE_PROPERTY}`;
|
|
839
|
+
this.footerTemplateId = `${this.element.id}${FOOTERTEMPLATE_PROPERTY}`;
|
|
840
|
+
this.noRecordsTemplateId = `${this.element.id}${NORECORDSTEMPLATE_PROPERTY}`;
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Creates the list items of DropDownBase component.
|
|
844
|
+
*
|
|
845
|
+
* @param {Object[] | string[] | number[] | DataManager | boolean[]} dataSource - Specifies the data to generate the list.
|
|
846
|
+
* @param {FieldSettingsModel} fields - Maps the columns of the data table and binds the data to the component.
|
|
847
|
+
* @param {Query} query - Accepts the external Query that execute along with data processing.
|
|
848
|
+
* @returns {void}
|
|
849
|
+
*/
|
|
850
|
+
private setListData(
|
|
851
|
+
dataSource: { [key: string]: Object }[] | string[] | number[] | DataManager | boolean[],
|
|
852
|
+
fields: FieldSettingsModel, query: Query, event?: MouseEvent | KeyboardEventArgs | TouchEvent): void {
|
|
853
|
+
fields = fields ? fields : this.fields;
|
|
854
|
+
let ulElement: HTMLElement;
|
|
855
|
+
this.isActive = true;
|
|
856
|
+
const eventArgs: ActionBeginEventArgs = { cancel: false, data: dataSource, query: query };
|
|
857
|
+
this.isPreventChange = this.isAngular && this.preventChange ? true : this.isPreventChange;
|
|
858
|
+
if (!this.isRequesting) {
|
|
859
|
+
this.trigger('actionBegin', eventArgs, (eventArgs: ActionBeginEventArgs) => {
|
|
860
|
+
if (!eventArgs.cancel) {
|
|
861
|
+
this.isRequesting = true;
|
|
862
|
+
this.showSpinner();
|
|
863
|
+
if (dataSource instanceof DataManager) {
|
|
864
|
+
this.isRequested = true;
|
|
865
|
+
if (this.isDataFetched) {
|
|
866
|
+
this.emptyDataRequest(fields);
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
(eventArgs.data as DataManager).executeQuery(this.getQuery(eventArgs.query as Query)).then((e: Object) => {
|
|
870
|
+
this.isPreventChange = this.isAngular && this.preventChange ? true : this.isPreventChange;
|
|
871
|
+
this.trigger('actionComplete', e, (e: Object) => {
|
|
872
|
+
if (!(e as { [key: string]: object }).cancel) {
|
|
873
|
+
const listItems: { [key: string]: Object }[] = (e as ResultData).result;
|
|
874
|
+
if (listItems.length === 0) {
|
|
875
|
+
this.isDataFetched = true;
|
|
876
|
+
}
|
|
877
|
+
this.dataCount = (e as any).count;
|
|
878
|
+
this.totalItemCount = (e as any).count;
|
|
879
|
+
ulElement = this.renderItems(listItems, fields);
|
|
880
|
+
this.onActionComplete(ulElement, listItems, e);
|
|
881
|
+
if (this.groupTemplate) {
|
|
882
|
+
this.renderGroupTemplate(ulElement);
|
|
883
|
+
}
|
|
884
|
+
this.isRequested = false;
|
|
885
|
+
this.bindChildItems(listItems, ulElement, fields, e);
|
|
886
|
+
}
|
|
887
|
+
this.isRequesting = false;
|
|
888
|
+
});
|
|
889
|
+
}).catch((e: Object) => {
|
|
890
|
+
this.isRequested = false;
|
|
891
|
+
this.isRequesting = false;
|
|
892
|
+
this.onActionFailure(e);
|
|
893
|
+
this.hideSpinner();
|
|
894
|
+
});
|
|
895
|
+
} else {
|
|
896
|
+
this.isRequesting = false;
|
|
897
|
+
const dataManager: DataManager = new DataManager(eventArgs.data as DataOptions | JSON[]);
|
|
898
|
+
let listItems: { [key: string]: Object }[] = <{ [key: string]: Object }[]>(
|
|
899
|
+
this.getQuery(eventArgs.query as Query)).executeLocal(dataManager);
|
|
900
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
901
|
+
this.dataCount = (listItems as any).count;
|
|
902
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
903
|
+
this.totalItemCount = (listItems as any).count;
|
|
904
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
905
|
+
listItems = this.isVirtualizationEnabled ? (listItems as any).result : listItems;
|
|
906
|
+
const localDataArgs: { [key: string]: Object } = { cancel: false, result: listItems };
|
|
907
|
+
this.isPreventChange = this.isAngular && this.preventChange ? true : this.isPreventChange;
|
|
908
|
+
this.trigger('actionComplete', localDataArgs, (localDataArgs: { [key: string]: object }) => {
|
|
909
|
+
if (!localDataArgs.cancel) {
|
|
910
|
+
ulElement = this.renderItems(localDataArgs.result as { [key: string]: Object }[], fields);
|
|
911
|
+
this.onActionComplete(ulElement, localDataArgs.result as { [key: string]: Object }[], event);
|
|
912
|
+
if (this.groupTemplate) {
|
|
913
|
+
this.renderGroupTemplate(ulElement);
|
|
914
|
+
}
|
|
915
|
+
this.bindChildItems(localDataArgs.result as { [key: string]: Object }[], ulElement, fields);
|
|
916
|
+
setTimeout(() => {
|
|
917
|
+
if (this.getModuleName() === 'multiselect' && this.itemTemplate != null && (ulElement.childElementCount > 0 && (ulElement.children[0].childElementCount > 0 || (this.fields.groupBy && ulElement.children[1] && ulElement.children[1].childElementCount > 0)))) {
|
|
918
|
+
this.updateDataList();
|
|
919
|
+
}
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
});
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
private bindChildItems(
|
|
929
|
+
listItems: { [key: string]: Object }[],
|
|
930
|
+
ulElement: HTMLElement,
|
|
931
|
+
fields: FieldSettingsModel,
|
|
932
|
+
e?: object): void {
|
|
933
|
+
if (listItems.length >= 100 && this.getModuleName() === 'autocomplete') {
|
|
934
|
+
setTimeout(
|
|
935
|
+
() => {
|
|
936
|
+
const childNode: HTMLElement[] = this.remainingItems(this.sortedData, fields);
|
|
937
|
+
append(childNode, ulElement);
|
|
938
|
+
this.liCollections = <HTMLElement[] & NodeListOf<Element>>this.list.querySelectorAll('.' + dropDownBaseClasses.li);
|
|
939
|
+
this.updateListValues();
|
|
940
|
+
this.raiseDataBound(listItems, e);
|
|
941
|
+
},
|
|
942
|
+
0);
|
|
943
|
+
} else {
|
|
944
|
+
this.raiseDataBound(listItems, e);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
protected updateListValues(): void {
|
|
948
|
+
// Used this method in component side.
|
|
949
|
+
}
|
|
950
|
+
protected findListElement(list: HTMLElement, findNode: string, attribute: string, value: string | boolean | number ): HTMLElement {
|
|
951
|
+
let liElement: HTMLElement = null;
|
|
952
|
+
if (list) {
|
|
953
|
+
const listArr: HTMLElement[] = [].slice.call(list.querySelectorAll(findNode));
|
|
954
|
+
for (let index: number = 0; index < listArr.length; index++) {
|
|
955
|
+
if (listArr[index as number].getAttribute(attribute) === (value + '')) {
|
|
956
|
+
liElement = listArr[index as number];
|
|
957
|
+
break;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
return liElement;
|
|
962
|
+
}
|
|
963
|
+
private raiseDataBound(
|
|
964
|
+
listItems: { [key: string]: Object }[] | string[] | boolean[] | number[],
|
|
965
|
+
e?: object): void {
|
|
966
|
+
this.hideSpinner();
|
|
967
|
+
const dataBoundEventArgs: DataBoundEventArgs = {
|
|
968
|
+
items: listItems,
|
|
969
|
+
e: e
|
|
970
|
+
};
|
|
971
|
+
this.trigger('dataBound', dataBoundEventArgs);
|
|
972
|
+
}
|
|
973
|
+
private remainingItems(
|
|
974
|
+
dataSource: { [key: string]: Object }[] | string[] | number[] | boolean[],
|
|
975
|
+
fields: FieldSettingsModel): HTMLElement[] {
|
|
976
|
+
const spliceData: { [key: string]: Object }[] | string[] | number[] | boolean[] =
|
|
977
|
+
<{ [key: string]: Object }[] | string[] | number[] | boolean[]>new DataManager(
|
|
978
|
+
dataSource as DataOptions | JSON[]).executeLocal(new Query().skip(100));
|
|
979
|
+
if (this.itemTemplate) {
|
|
980
|
+
const listElements: HTMLElement = this.templateListItem(spliceData as { [key: string]: Object }[], fields);
|
|
981
|
+
return [].slice.call(listElements.childNodes);
|
|
982
|
+
}
|
|
983
|
+
const type: string = this.typeOfData(spliceData).typeof as string;
|
|
984
|
+
if (type === 'string' || type === 'number' || type === 'boolean') {
|
|
985
|
+
return ListBase.createListItemFromArray(
|
|
986
|
+
this.createElement, <string[] | number[]>spliceData,
|
|
987
|
+
true,
|
|
988
|
+
<{ [key: string]: Object }>this.listOption(spliceData, fields), this);
|
|
989
|
+
}
|
|
990
|
+
return ListBase.createListItemFromJson(
|
|
991
|
+
this.createElement,
|
|
992
|
+
<{ [key: string]: Object }[]>spliceData,
|
|
993
|
+
<{ [key: string]: Object }>this.listOption(spliceData, fields),
|
|
994
|
+
1,
|
|
995
|
+
true, this);
|
|
996
|
+
}
|
|
997
|
+
private emptyDataRequest(fields: FieldSettingsModel): void {
|
|
998
|
+
const listItems: { [key: string]: Object }[] = [];
|
|
999
|
+
this.onActionComplete(this.renderItems(listItems, fields), listItems);
|
|
1000
|
+
this.isRequested = false;
|
|
1001
|
+
this.hideSpinner();
|
|
1002
|
+
}
|
|
1003
|
+
protected showSpinner(): void {
|
|
1004
|
+
// Used this method in component side.
|
|
1005
|
+
}
|
|
1006
|
+
protected hideSpinner(): void {
|
|
1007
|
+
// Used this method in component side.
|
|
1008
|
+
}
|
|
1009
|
+
protected onActionFailure(e: Object): void {
|
|
1010
|
+
this.liCollections = [];
|
|
1011
|
+
this.trigger('actionFailure', e);
|
|
1012
|
+
this.l10nUpdate(true);
|
|
1013
|
+
if (!isNullOrUndefined(this.list)) {
|
|
1014
|
+
addClass([this.list], dropDownBaseClasses.noData);
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
1018
|
+
protected onActionComplete(
|
|
1019
|
+
ulElement: HTMLElement,
|
|
1020
|
+
list: { [key: string]: Object }[] | boolean[] | string[] | number[],
|
|
1021
|
+
e?: Object): void {
|
|
1022
|
+
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
1023
|
+
this.listData = list;
|
|
1024
|
+
if (this.isVirtualizationEnabled) {
|
|
1025
|
+
this.notify("setGeneratedData", {
|
|
1026
|
+
module: "VirtualScroll",
|
|
1027
|
+
});
|
|
1028
|
+
}
|
|
1029
|
+
if (this.getModuleName() !== 'listbox') {
|
|
1030
|
+
ulElement.setAttribute('tabindex', '0'); }
|
|
1031
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1032
|
+
if ((this as any).isReact) {
|
|
1033
|
+
this.clearTemplate(['itemTemplate', 'groupTemplate', 'actionFailureTemplate', 'noRecordsTemplate']);
|
|
1034
|
+
}
|
|
1035
|
+
this.fixedHeaderElement = isNullOrUndefined(this.fixedHeaderElement) ? this.fixedHeaderElement : null;
|
|
1036
|
+
if (this.getModuleName() === 'multiselect' && this.properties.allowCustomValue && this.fields.groupBy) {
|
|
1037
|
+
for (let i: number = 0; i< ulElement.childElementCount; i++) {
|
|
1038
|
+
if (ulElement.children[i as number].classList.contains('e-list-group-item')) {
|
|
1039
|
+
if (isNullOrUndefined(ulElement.children[i as number].innerHTML) || ulElement.children[i as number].innerHTML == "") {
|
|
1040
|
+
addClass([ulElement.children[i as number]], HIDE_GROUPLIST) }
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
if (!isNullOrUndefined(this.list)) {
|
|
1045
|
+
if (!this.isVirtualizationEnabled) {
|
|
1046
|
+
this.list.innerHTML = '';
|
|
1047
|
+
this.list.appendChild(ulElement);
|
|
1048
|
+
this.liCollections = <HTMLElement[] & NodeListOf<Element>>this.list.querySelectorAll('.' + dropDownBaseClasses.li);
|
|
1049
|
+
this.ulElement = this.list.querySelector('ul');
|
|
1050
|
+
this.postRender(this.list, list, this.bindEvent);
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
1055
|
+
protected postRender(
|
|
1056
|
+
listElement: HTMLElement,
|
|
1057
|
+
list: { [key: string]: Object }[] | number[] | string[] | boolean[],
|
|
1058
|
+
bindEvent: boolean): void {
|
|
1059
|
+
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
1060
|
+
const focusItem: Element = listElement.querySelector('.' + dropDownBaseClasses.li);
|
|
1061
|
+
const selectedItem: Element = listElement.querySelector('.' + dropDownBaseClasses.selected);
|
|
1062
|
+
if (focusItem && !selectedItem) {
|
|
1063
|
+
focusItem.classList.add(dropDownBaseClasses.focus);
|
|
1064
|
+
}
|
|
1065
|
+
if (list.length <= 0) {
|
|
1066
|
+
this.l10nUpdate();
|
|
1067
|
+
addClass([listElement], dropDownBaseClasses.noData);
|
|
1068
|
+
} else {
|
|
1069
|
+
listElement.classList.remove(dropDownBaseClasses.noData);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
/**
|
|
1074
|
+
* Get the query to do the data operation before list item generation.
|
|
1075
|
+
*
|
|
1076
|
+
* @param {Query} query - Accepts the external Query that execute along with data processing.
|
|
1077
|
+
* @returns {Query} Returns the query to do the data query operation.
|
|
1078
|
+
*/
|
|
1079
|
+
protected getQuery(query: Query): Query {
|
|
1080
|
+
return query ? query : this.query ? this.query : new Query();
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
protected updateVirtualizationProperties(itemCount: number, filtering: boolean): void {
|
|
1084
|
+
this.isVirtualizationEnabled = true;
|
|
1085
|
+
this.virtualizedItemsCount = itemCount;
|
|
1086
|
+
this.isAllowFiltering = filtering;
|
|
1087
|
+
}
|
|
1088
|
+
/**
|
|
1089
|
+
* To render the template content for group header element.
|
|
1090
|
+
*
|
|
1091
|
+
* @param {HTMLElement} listEle - Specifies the group list elements.
|
|
1092
|
+
* @returns {void}
|
|
1093
|
+
*/
|
|
1094
|
+
private renderGroupTemplate(listEle: HTMLElement): void {
|
|
1095
|
+
if (this.fields.groupBy !== null && this.dataSource || this.element.querySelector('.' + dropDownBaseClasses.group)) {
|
|
1096
|
+
const dataSource: { [key: string]: Object }[] = <{ [key: string]: Object }[]>this.dataSource;
|
|
1097
|
+
const option: { [key: string]: Object } = { groupTemplateID: this.groupTemplateId, isStringTemplate: this.isStringTemplate };
|
|
1098
|
+
const headerItems: Element[] = <NodeListOf<Element> & Element[]>listEle.querySelectorAll('.' + dropDownBaseClasses.group);
|
|
1099
|
+
const groupcheck: boolean = this.templateCompiler(this.groupTemplate);
|
|
1100
|
+
if (typeof this.groupTemplate !== 'function' && groupcheck) {
|
|
1101
|
+
const groupValue: string = select(this.groupTemplate, document).innerHTML.trim();
|
|
1102
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1103
|
+
const tempHeaders: Element[] = ListBase.renderGroupTemplate(
|
|
1104
|
+
groupValue as string, <{ [key: string]: Object }[]>dataSource,
|
|
1105
|
+
(this.fields as FieldSettingsModel & { properties: Object }).properties,
|
|
1106
|
+
headerItems, option, this);
|
|
1107
|
+
//EJ2-55168- Group checkbox is not working with group template
|
|
1108
|
+
if (this.isGroupChecking) {
|
|
1109
|
+
for (let i: number = 0; i < tempHeaders.length; i++) {
|
|
1110
|
+
this.notify('addItem', { module: 'CheckBoxSelection', item: tempHeaders[i as number] });
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
} else {
|
|
1114
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1115
|
+
const tempHeaders: Element[] = ListBase.renderGroupTemplate(
|
|
1116
|
+
this.groupTemplate as string, <{ [key: string]: Object }[]>dataSource,
|
|
1117
|
+
(this.fields as FieldSettingsModel & { properties: Object }).properties,
|
|
1118
|
+
headerItems, option, this);
|
|
1119
|
+
//EJ2-55168- Group checkbox is not working with group template
|
|
1120
|
+
if (this.isGroupChecking) {
|
|
1121
|
+
for (let i: number = 0; i < tempHeaders.length; i++) {
|
|
1122
|
+
this.notify('addItem', { module: 'CheckBoxSelection', item: tempHeaders[i as number] });
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
this.renderReactTemplates();
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
/**
|
|
1130
|
+
* To create the ul li list items
|
|
1131
|
+
*
|
|
1132
|
+
* @param {object []} dataSource - Specifies the data to generate the list.
|
|
1133
|
+
* @param {FieldSettingsModel} fields - Maps the columns of the data table and binds the data to the component.
|
|
1134
|
+
* @returns {HTMLElement} Return the ul li list items.
|
|
1135
|
+
*/
|
|
1136
|
+
private createListItems(dataSource: { [key: string]: Object }[], fields: FieldSettingsModel): HTMLElement {
|
|
1137
|
+
if (dataSource && fields.groupBy || this.element.querySelector('optgroup')) {
|
|
1138
|
+
if (fields.groupBy) {
|
|
1139
|
+
if (this.sortOrder !== 'None') {
|
|
1140
|
+
dataSource = this.getSortedDataSource(dataSource);
|
|
1141
|
+
}
|
|
1142
|
+
dataSource = ListBase.groupDataSource(
|
|
1143
|
+
dataSource, (fields as FieldSettingsModel & { properties: Object }).properties, this.sortOrder);
|
|
1144
|
+
}
|
|
1145
|
+
addClass([this.list], dropDownBaseClasses.grouping);
|
|
1146
|
+
} else {
|
|
1147
|
+
dataSource = this.getSortedDataSource(dataSource);
|
|
1148
|
+
}
|
|
1149
|
+
const options: { [key: string]: Object } = <{ [key: string]: Object }>this.listOption(dataSource, fields);
|
|
1150
|
+
const spliceData: { [key: string]: Object }[] = (dataSource.length > 100) ?
|
|
1151
|
+
<{ [key: string]: Object }[]>new DataManager(dataSource as DataOptions | JSON[]).executeLocal(new Query().take(100))
|
|
1152
|
+
: dataSource;
|
|
1153
|
+
this.sortedData = dataSource;
|
|
1154
|
+
return ListBase.createList(
|
|
1155
|
+
this.createElement, (this.getModuleName() === 'autocomplete') ? spliceData : dataSource, options, true, this);
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
protected listOption(
|
|
1159
|
+
dataSource: { [key: string]: Object }[] | string[] | number[] | boolean[],
|
|
1160
|
+
fields: FieldSettingsModel): FieldSettingsModel {
|
|
1161
|
+
const iconCss: boolean = isNullOrUndefined(fields.iconCss) ? false : true;
|
|
1162
|
+
const fieldValues: FieldSettingsModel = !isNullOrUndefined((fields as FieldSettingsModel & { properties: Object }).properties) ?
|
|
1163
|
+
(fields as FieldSettingsModel & { properties: Object }).properties : fields;
|
|
1164
|
+
const options: { [key: string]: Object } = (fields.text !== null || fields.value !== null) ? {
|
|
1165
|
+
fields: fieldValues,
|
|
1166
|
+
showIcon: iconCss, ariaAttributes: { groupItemRole: 'presentation' }
|
|
1167
|
+
} : { fields: { value: 'text' } as Object };
|
|
1168
|
+
return extend({}, options, fields, true);
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
protected setFloatingHeader(e: Event): void {
|
|
1172
|
+
if (!isNullOrUndefined(this.list) && !this.list.classList.contains(dropDownBaseClasses.noData)) {
|
|
1173
|
+
if (isNullOrUndefined(this.fixedHeaderElement)) {
|
|
1174
|
+
this.fixedHeaderElement = this.createElement('div', { className: dropDownBaseClasses.fixedHead });
|
|
1175
|
+
if ( !isNullOrUndefined(this.list) && !this.list.querySelector('li').classList.contains(dropDownBaseClasses.group)) {
|
|
1176
|
+
this.fixedHeaderElement.style.display = 'none';
|
|
1177
|
+
}
|
|
1178
|
+
if (!isNullOrUndefined(this.fixedHeaderElement) && !isNullOrUndefined(this.list)) {
|
|
1179
|
+
prepend([this.fixedHeaderElement], this.list);
|
|
1180
|
+
}
|
|
1181
|
+
this.setFixedHeader();
|
|
1182
|
+
}
|
|
1183
|
+
if (!isNullOrUndefined(this.fixedHeaderElement) && this.fixedHeaderElement.style.zIndex === '0') {
|
|
1184
|
+
this.setFixedHeader();
|
|
1185
|
+
}
|
|
1186
|
+
this.scrollStop(e);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
protected scrollStop(e?: Event): void {
|
|
1191
|
+
const target: Element = !isNullOrUndefined(e) ? <Element>e.target : this.list;
|
|
1192
|
+
const liHeight: number = parseInt(getComputedStyle(this.getValidLi(), null).getPropertyValue('height'), 10);
|
|
1193
|
+
const topIndex: number = Math.round(target.scrollTop / liHeight);
|
|
1194
|
+
const liCollections: NodeListOf<Element> = <NodeListOf<Element>>this.list.querySelectorAll('li' + ':not(.e-hide-listitem)');
|
|
1195
|
+
for (let i: number = topIndex; i > -1; i--) {
|
|
1196
|
+
if (!isNullOrUndefined(liCollections[i as number]) && liCollections[i as number].classList.contains(dropDownBaseClasses.group)) {
|
|
1197
|
+
const currentLi: HTMLElement = liCollections[i as number] as HTMLElement;
|
|
1198
|
+
this.fixedHeaderElement.innerHTML = currentLi.innerHTML;
|
|
1199
|
+
this.fixedHeaderElement.style.top = target.scrollTop + 'px';
|
|
1200
|
+
this.fixedHeaderElement.style.display = 'block';
|
|
1201
|
+
break;
|
|
1202
|
+
} else {
|
|
1203
|
+
this.fixedHeaderElement.style.display = 'none';
|
|
1204
|
+
this.fixedHeaderElement.style.top = 'none';
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
protected getValidLi() : HTMLElement {
|
|
1210
|
+
return this.liCollections[0];
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
/**
|
|
1214
|
+
* To render the list items
|
|
1215
|
+
*
|
|
1216
|
+
* @param {object[]} listData - Specifies the list of array of data.
|
|
1217
|
+
* @param {FieldSettingsModel} fields - Maps the columns of the data table and binds the data to the component.
|
|
1218
|
+
* @returns {HTMLElement} Return the list items.
|
|
1219
|
+
*/
|
|
1220
|
+
protected renderItems(listData: { [key: string]: Object }[], fields: FieldSettingsModel): HTMLElement {
|
|
1221
|
+
let ulElement: HTMLElement;
|
|
1222
|
+
if (this.itemTemplate && listData) {
|
|
1223
|
+
let dataSource: { [key: string]: Object }[] = listData;
|
|
1224
|
+
if (dataSource && fields.groupBy) {
|
|
1225
|
+
if (this.sortOrder !== 'None') {
|
|
1226
|
+
dataSource = this.getSortedDataSource(dataSource);
|
|
1227
|
+
}
|
|
1228
|
+
dataSource = ListBase.groupDataSource(
|
|
1229
|
+
dataSource, (fields as FieldSettingsModel & { properties: Object }).properties, this.sortOrder);
|
|
1230
|
+
} else {
|
|
1231
|
+
dataSource = this.getSortedDataSource(dataSource);
|
|
1232
|
+
}
|
|
1233
|
+
this.sortedData = dataSource;
|
|
1234
|
+
const spliceData: { [key: string]: Object }[] = (dataSource.length > 100) ?
|
|
1235
|
+
<{ [key: string]: Object }[]>new DataManager(dataSource as DataOptions | JSON[]).executeLocal(new Query().take(100))
|
|
1236
|
+
: dataSource;
|
|
1237
|
+
ulElement = this.templateListItem((this.getModuleName() === 'autocomplete') ? spliceData : dataSource, fields);
|
|
1238
|
+
if (this.isVirtualizationEnabled) {
|
|
1239
|
+
var oldUlElement = this.list.querySelector('.e-list-parent');
|
|
1240
|
+
var virtualUlElement = this.list.querySelector('.e-virtual-ddl-content');
|
|
1241
|
+
if ((listData.length >= this.virtualizedItemsCount && oldUlElement && virtualUlElement) || (oldUlElement && virtualUlElement && this.isAllowFiltering) || (oldUlElement && virtualUlElement && this.getModuleName() === 'autocomplete')) {
|
|
1242
|
+
virtualUlElement.replaceChild(ulElement, oldUlElement);
|
|
1243
|
+
this.liCollections = <HTMLElement[] & NodeListOf<Element>>this.list.querySelectorAll('.' + dropDownBaseClasses.li);
|
|
1244
|
+
this.ulElement = this.list.querySelector('ul');
|
|
1245
|
+
this.listData = listData;
|
|
1246
|
+
this.postRender(this.list, listData, this.bindEvent);
|
|
1247
|
+
}
|
|
1248
|
+
else if ((!virtualUlElement)) {
|
|
1249
|
+
this.list.innerHTML = '';
|
|
1250
|
+
this.list.appendChild(ulElement);
|
|
1251
|
+
this.liCollections = <HTMLElement[] & NodeListOf<Element>>this.list.querySelectorAll('.' + dropDownBaseClasses.li);
|
|
1252
|
+
this.ulElement = this.list.querySelector('ul');
|
|
1253
|
+
this.listData = listData;
|
|
1254
|
+
this.postRender(this.list, listData, this.bindEvent);
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
} else {
|
|
1258
|
+
ulElement = this.createListItems(listData, fields);
|
|
1259
|
+
if (this.isVirtualizationEnabled) {
|
|
1260
|
+
var oldUlElement = this.list.querySelector('.e-list-parent');
|
|
1261
|
+
var virtualUlElement = this.list.querySelector('.e-virtual-ddl-content');
|
|
1262
|
+
if ((listData.length >= this.virtualizedItemsCount && oldUlElement && virtualUlElement) || (oldUlElement && virtualUlElement && this.isAllowFiltering) || (oldUlElement && virtualUlElement && this.getModuleName() === 'autocomplete')) {
|
|
1263
|
+
virtualUlElement.replaceChild(ulElement, oldUlElement);
|
|
1264
|
+
this.liCollections = <HTMLElement[] & NodeListOf<Element>>this.list.querySelectorAll('.' + dropDownBaseClasses.li);
|
|
1265
|
+
this.ulElement = this.list.querySelector('ul');
|
|
1266
|
+
this.listData = listData;
|
|
1267
|
+
this.postRender(this.list, listData, this.bindEvent);
|
|
1268
|
+
}
|
|
1269
|
+
else if ((!virtualUlElement)) {
|
|
1270
|
+
this.list.innerHTML = '';
|
|
1271
|
+
this.list.appendChild(ulElement);
|
|
1272
|
+
this.liCollections = <HTMLElement[] & NodeListOf<Element>>this.list.querySelectorAll('.' + dropDownBaseClasses.li);
|
|
1273
|
+
this.ulElement = this.list.querySelector('ul');
|
|
1274
|
+
this.listData = listData;
|
|
1275
|
+
this.postRender(this.list, listData, this.bindEvent);
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
return ulElement;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
protected templateListItem(dataSource: { [key: string]: Object }[], fields: FieldSettingsModel): HTMLElement {
|
|
1283
|
+
const option: { [key: string]: Object } = <{ [key: string]: Object }>this.listOption(dataSource, fields);
|
|
1284
|
+
option.templateID = this.itemTemplateId;
|
|
1285
|
+
option.isStringTemplate = this.isStringTemplate;
|
|
1286
|
+
const itemcheck: boolean = this.templateCompiler(this.itemTemplate);
|
|
1287
|
+
if (typeof this.itemTemplate !== 'function' && itemcheck) {
|
|
1288
|
+
const itemValue: string = select(this.itemTemplate, document).innerHTML.trim();
|
|
1289
|
+
return ListBase.renderContentTemplate(
|
|
1290
|
+
this.createElement, itemValue, dataSource,
|
|
1291
|
+
(fields as FieldSettingsModel & { properties: Object }).properties, option, this);
|
|
1292
|
+
} else {
|
|
1293
|
+
return ListBase.renderContentTemplate(
|
|
1294
|
+
this.createElement, this.itemTemplate as any, dataSource,
|
|
1295
|
+
(fields as FieldSettingsModel & { properties: Object }).properties, option, this);
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
protected typeOfData(items:
|
|
1300
|
+
{ [key: string]: Object }[] | string[] | number[] | boolean[]): { [key: string]: Object } {
|
|
1301
|
+
let item: { [key: string]: Object } = { typeof: null, item: null };
|
|
1302
|
+
for (let i: number = 0; (!isNullOrUndefined(items) && i < items.length); i++) {
|
|
1303
|
+
if (!isNullOrUndefined(items[i as number])) {
|
|
1304
|
+
const listDataType: boolean = typeof (items[i as number]) === 'string' ||
|
|
1305
|
+
typeof (items[i as number]) === 'number' || typeof (items[i as number]) === 'boolean';
|
|
1306
|
+
const isNullData: boolean = listDataType ? isNullOrUndefined(items[i as number]) :
|
|
1307
|
+
isNullOrUndefined(getValue((this.fields.value ? this.fields.value : 'value'), items[i as number]));
|
|
1308
|
+
if (!isNullData) {
|
|
1309
|
+
return item = { typeof: typeof items[i as number], item: items[i as number] };
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
return item;
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
protected setFixedHeader(): void {
|
|
1317
|
+
if (!isNullOrUndefined(this.list)) {
|
|
1318
|
+
this.list.parentElement.style.display = 'block';
|
|
1319
|
+
}
|
|
1320
|
+
let borderWidth: number = 0;
|
|
1321
|
+
if (this.list && this.list.parentElement) {
|
|
1322
|
+
borderWidth = parseInt(
|
|
1323
|
+
document.defaultView.getComputedStyle(this.list.parentElement, null).getPropertyValue('border-width'), 10
|
|
1324
|
+
);
|
|
1325
|
+
/*Shorthand property not working in Firefox for getComputedStyle method.
|
|
1326
|
+
Refer bug report https://bugzilla.mozilla.org/show_bug.cgi?id=137688
|
|
1327
|
+
Refer alternate solution https://stackoverflow.com/a/41696234/9133493*/
|
|
1328
|
+
if (isNaN(borderWidth)) {
|
|
1329
|
+
let borderTopWidth: number = parseInt(document.defaultView.getComputedStyle(this.list.parentElement, null).getPropertyValue('border-top-width'), 10);
|
|
1330
|
+
let borderBottomWidth: number = parseInt(document.defaultView.getComputedStyle(this.list.parentElement, null).getPropertyValue('border-bottom-width'), 10);
|
|
1331
|
+
let borderLeftWidth: number = parseInt(document.defaultView.getComputedStyle(this.list.parentElement, null).getPropertyValue('border-left-width'), 10);
|
|
1332
|
+
let borderRightWidth: number = parseInt(document.defaultView.getComputedStyle(this.list.parentElement, null).getPropertyValue('border-right-width'), 10);
|
|
1333
|
+
borderWidth = (borderTopWidth + borderBottomWidth + borderLeftWidth + borderRightWidth);
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
if (!isNullOrUndefined(this.liCollections)) {
|
|
1337
|
+
const liWidth: number = this.getValidLi().offsetWidth - borderWidth;
|
|
1338
|
+
this.fixedHeaderElement.style.width = liWidth.toString() + 'px';
|
|
1339
|
+
}
|
|
1340
|
+
setStyleAttribute(this.fixedHeaderElement, { zIndex: 10 });
|
|
1341
|
+
const firstLi: HTMLElement = this.ulElement.querySelector('.' + dropDownBaseClasses.group + ':not(.e-hide-listitem)') as HTMLElement;
|
|
1342
|
+
this.fixedHeaderElement.innerHTML = firstLi.innerHTML;
|
|
1343
|
+
}
|
|
1344
|
+
private getSortedDataSource(dataSource: { [key: string]: Object }[]): { [key: string]: Object }[] {
|
|
1345
|
+
if (dataSource && this.sortOrder !== 'None') {
|
|
1346
|
+
let textField: string = this.fields.text ? this.fields.text : 'text';
|
|
1347
|
+
if (this.typeOfData(dataSource).typeof === 'string' || this.typeOfData(dataSource).typeof === 'number'
|
|
1348
|
+
|| this.typeOfData(dataSource).typeof === 'boolean') {
|
|
1349
|
+
textField = '';
|
|
1350
|
+
}
|
|
1351
|
+
dataSource = ListBase.getDataSource(dataSource, ListBase.addSorting(this.sortOrder, textField));
|
|
1352
|
+
}
|
|
1353
|
+
return dataSource;
|
|
1354
|
+
}
|
|
1355
|
+
/**
|
|
1356
|
+
* Return the index of item which matched with given value in data source
|
|
1357
|
+
*
|
|
1358
|
+
* @param {string | number | boolean} value - Specifies given value.
|
|
1359
|
+
* @returns {number} Returns the index of the item.
|
|
1360
|
+
*/
|
|
1361
|
+
protected getIndexByValueFilter(value: string | number | boolean): number {
|
|
1362
|
+
let index: number;
|
|
1363
|
+
const listItems: HTMLElement = this.renderItems(this.selectData as { [key: string]: Object }[], this.fields);
|
|
1364
|
+
for (let i: number = 0; i < listItems.children.length; i++) {
|
|
1365
|
+
if (!isNullOrUndefined(value) && listItems.children[i as number].getAttribute('data-value') === value.toString()) {
|
|
1366
|
+
index = i;
|
|
1367
|
+
break;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
return index;
|
|
1371
|
+
}
|
|
1372
|
+
/**
|
|
1373
|
+
* Return the index of item which matched with given value in data source
|
|
1374
|
+
*
|
|
1375
|
+
* @param {string | number | boolean} value - Specifies given value.
|
|
1376
|
+
* @returns {number} Returns the index of the item.
|
|
1377
|
+
*/
|
|
1378
|
+
protected getIndexByValue(value: string | number | boolean): number {
|
|
1379
|
+
let index: number;
|
|
1380
|
+
const listItems: Element[] = this.getItems();
|
|
1381
|
+
for (let i: number = 0; i < listItems.length; i++) {
|
|
1382
|
+
if (!isNullOrUndefined(value) && listItems[i as number].getAttribute('data-value') === value.toString()) {
|
|
1383
|
+
index = i;
|
|
1384
|
+
break;
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
return index;
|
|
1388
|
+
}
|
|
1389
|
+
/**
|
|
1390
|
+
* To dispatch the event manually
|
|
1391
|
+
*
|
|
1392
|
+
* @param {HTMLElement} element - Specifies the element to dispatch the event.
|
|
1393
|
+
* @param {string} type - Specifies the name of the event.
|
|
1394
|
+
* @returns {void}
|
|
1395
|
+
*/
|
|
1396
|
+
protected dispatchEvent(element: HTMLElement, type: string): void {
|
|
1397
|
+
const evt: Event = document.createEvent('HTMLEvents');
|
|
1398
|
+
evt.initEvent(type, false, true);
|
|
1399
|
+
if(element){
|
|
1400
|
+
element.dispatchEvent(evt);
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
/**
|
|
1404
|
+
* To set the current fields
|
|
1405
|
+
*
|
|
1406
|
+
* @returns {void}
|
|
1407
|
+
*/
|
|
1408
|
+
protected setFields(): void {
|
|
1409
|
+
if (this.fields.value && !this.fields.text) {
|
|
1410
|
+
this.updateFields(this.fields.value, this.fields.value);
|
|
1411
|
+
} else if (!this.fields.value && this.fields.text) {
|
|
1412
|
+
this.updateFields(this.fields.text, this.fields.text);
|
|
1413
|
+
} else if (!this.fields.value && !this.fields.text) {
|
|
1414
|
+
this.updateFields('text', 'text');
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
/**
|
|
1418
|
+
* reset the items list.
|
|
1419
|
+
*
|
|
1420
|
+
* @param {Object[] | string[] | number[] | DataManager | boolean[]} dataSource - Specifies the data to generate the list.
|
|
1421
|
+
* @param {FieldSettingsModel} fields - Maps the columns of the data table and binds the data to the component.
|
|
1422
|
+
* @param {Query} query - Accepts the external Query that execute along with data processing.
|
|
1423
|
+
* @returns {void}
|
|
1424
|
+
*/
|
|
1425
|
+
protected resetList(
|
|
1426
|
+
dataSource?: { [key: string]: Object }[] | DataManager | string[] | number[] | boolean[],
|
|
1427
|
+
fields?: FieldSettingsModel, query?: Query, e?: MouseEvent | KeyboardEventArgs | TouchEvent): void {
|
|
1428
|
+
if (this.list) {
|
|
1429
|
+
if ((this.element.tagName === 'SELECT' && (<HTMLSelectElement>this.element).options.length > 0)
|
|
1430
|
+
|| (this.element.tagName === 'UL' && (<HTMLUListElement>this.element).childNodes.length > 0)) {
|
|
1431
|
+
const data: boolean = dataSource instanceof Array ? (dataSource.length > 0)
|
|
1432
|
+
: !isNullOrUndefined(dataSource);
|
|
1433
|
+
if (!data && this.selectData && this.selectData.length > 0) {
|
|
1434
|
+
dataSource = this.selectData;
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
dataSource = this.getModuleName() === 'combobox' && this.selectData && dataSource instanceof Array && dataSource.length < this.selectData.length && this.addedNewItem ? this.selectData : dataSource;
|
|
1438
|
+
this.addedNewItem = false;
|
|
1439
|
+
this.setListData(dataSource, fields, query, e);
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
protected updateSelectElementData(isFiltering: boolean): void {
|
|
1444
|
+
if ((isFiltering || this.isVirtualizationEnabled) && isNullOrUndefined(this.selectData) && this.listData && this.listData.length > 0) {
|
|
1445
|
+
this.selectData = this.listData;
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
protected updateSelection(): void {
|
|
1450
|
+
// This is for after added the item, need to update the selected index values.
|
|
1451
|
+
}
|
|
1452
|
+
protected renderList(): void {
|
|
1453
|
+
// This is for render the list items.
|
|
1454
|
+
this.render();
|
|
1455
|
+
}
|
|
1456
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1457
|
+
protected updateDataSource(props?: DropDownBaseModel): void {
|
|
1458
|
+
this.resetList(this.dataSource);
|
|
1459
|
+
this.totalItemCount = this.dataSource instanceof DataManager ? this.dataSource.dataSource.json.length : 0;
|
|
1460
|
+
}
|
|
1461
|
+
protected setUpdateInitial(props: string[], newProp: { [key: string]: string }): void {
|
|
1462
|
+
this.isDataFetched = false;
|
|
1463
|
+
const updateData: { [key: string]: string | { [key: string]: Object }[] } = {};
|
|
1464
|
+
for (let j: number = 0; props.length > j; j++) {
|
|
1465
|
+
if ((newProp as { [key: string]: string })[props[j as number]] && props[j as number] === 'fields') {
|
|
1466
|
+
this.setFields();
|
|
1467
|
+
(updateData as { [key: string]: string })[props[j as number]] = (newProp as { [key: string]: string })[props[j as number]];
|
|
1468
|
+
} else if ((newProp as { [key: string]: string })[props[j as number]]) {
|
|
1469
|
+
(updateData as { [key: string]: string })[props[j as number]] = (newProp as { [key: string]: string })[props[j as number]];
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
if (Object.keys(updateData).length > 0) {
|
|
1473
|
+
if (Object.keys(updateData).indexOf('dataSource') === -1) {
|
|
1474
|
+
(updateData as { [key: string]: { [key: string]: Object }[] }).dataSource = this.dataSource as
|
|
1475
|
+
{ [key: string]: Object }[];
|
|
1476
|
+
}
|
|
1477
|
+
this.updateDataSource(updateData);
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
/**
|
|
1482
|
+
* When property value changes happened, then onPropertyChanged method will execute the respective changes in this component.
|
|
1483
|
+
*
|
|
1484
|
+
* @param {DropDownBaseModel} newProp - Returns the dynamic property value of the component.
|
|
1485
|
+
* @param {DropDownBaseModel} oldProp - Returns the previous property value of the component.
|
|
1486
|
+
* @private
|
|
1487
|
+
* @returns {void}
|
|
1488
|
+
*/
|
|
1489
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1490
|
+
public onPropertyChanged(newProp: DropDownBaseModel, oldProp: DropDownBaseModel): void {
|
|
1491
|
+
if (this.getModuleName() === 'dropdownbase') {
|
|
1492
|
+
this.setUpdateInitial(['fields', 'query', 'dataSource'], newProp as { [key: string]: string });
|
|
1493
|
+
}
|
|
1494
|
+
this.setUpdateInitial(['sortOrder', 'itemTemplate'], newProp as { [key: string]: string });
|
|
1495
|
+
for (const prop of Object.keys(newProp)) {
|
|
1496
|
+
switch (prop) {
|
|
1497
|
+
case 'query':
|
|
1498
|
+
case 'sortOrder':
|
|
1499
|
+
case 'dataSource':
|
|
1500
|
+
case 'itemTemplate':
|
|
1501
|
+
break;
|
|
1502
|
+
case 'enableRtl':
|
|
1503
|
+
this.setEnableRtl();
|
|
1504
|
+
break;
|
|
1505
|
+
case 'groupTemplate':
|
|
1506
|
+
this.renderGroupTemplate(this.list);
|
|
1507
|
+
if (this.ulElement && this.fixedHeaderElement) {
|
|
1508
|
+
const firstLi: HTMLElement = this.ulElement.querySelector('.' + dropDownBaseClasses.group) as HTMLElement;
|
|
1509
|
+
this.fixedHeaderElement.innerHTML = firstLi.innerHTML;
|
|
1510
|
+
}
|
|
1511
|
+
break;
|
|
1512
|
+
case 'locale':
|
|
1513
|
+
if (this.list && (!isNullOrUndefined(this.liCollections) && this.liCollections.length === 0)) {
|
|
1514
|
+
this.l10nUpdate();
|
|
1515
|
+
}
|
|
1516
|
+
break;
|
|
1517
|
+
case 'zIndex':
|
|
1518
|
+
this.setProperties({ zIndex: newProp.zIndex }, true);
|
|
1519
|
+
this.setZIndex();
|
|
1520
|
+
break;
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
/**
|
|
1525
|
+
* Build and render the component
|
|
1526
|
+
*
|
|
1527
|
+
* @param {boolean} isEmptyData - Specifies the component to initialize with list data or not.
|
|
1528
|
+
* @private
|
|
1529
|
+
* @returns {void}
|
|
1530
|
+
*/
|
|
1531
|
+
public render(e?: MouseEvent | KeyboardEventArgs | TouchEvent, isEmptyData?: boolean): void {
|
|
1532
|
+
if (this.getModuleName() === 'listbox') {
|
|
1533
|
+
this.list = this.createElement('div', { className: dropDownBaseClasses.content, attrs: { 'tabindex': '0' } }); }
|
|
1534
|
+
else {
|
|
1535
|
+
this.list = this.createElement('div', { className: dropDownBaseClasses.content});
|
|
1536
|
+
}
|
|
1537
|
+
this.list.classList.add(dropDownBaseClasses.root);
|
|
1538
|
+
this.setFields();
|
|
1539
|
+
const rippleModel: RippleOptions = { duration: 300, selector: '.' + dropDownBaseClasses.li };
|
|
1540
|
+
this.rippleFun = rippleEffect(this.list, rippleModel);
|
|
1541
|
+
const group: HTMLElement = <HTMLElement>this.element.querySelector('select>optgroup');
|
|
1542
|
+
if ((this.fields.groupBy || !isNullOrUndefined(group)) && !this.isGroupChecking) {
|
|
1543
|
+
EventHandler.add(this.list, 'scroll', this.setFloatingHeader, this);
|
|
1544
|
+
}
|
|
1545
|
+
if (this.getModuleName() === 'dropdownbase') {
|
|
1546
|
+
if (this.element.getAttribute('tabindex')) {
|
|
1547
|
+
this.list.setAttribute('tabindex', this.element.getAttribute('tabindex'));
|
|
1548
|
+
}
|
|
1549
|
+
removeClass([this.element], dropDownBaseClasses.root);
|
|
1550
|
+
this.element.style.display = 'none';
|
|
1551
|
+
const wrapperElement: HTMLElement = this.createElement('div');
|
|
1552
|
+
this.element.parentElement.insertBefore(wrapperElement, this.element);
|
|
1553
|
+
wrapperElement.appendChild(this.element);
|
|
1554
|
+
wrapperElement.appendChild(this.list);
|
|
1555
|
+
}
|
|
1556
|
+
this.setEnableRtl();
|
|
1557
|
+
if (!isEmptyData) {
|
|
1558
|
+
this.initialize(e);
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
protected removeScrollEvent() : void
|
|
1562
|
+
{
|
|
1563
|
+
if (this.list) {
|
|
1564
|
+
EventHandler.remove(this.list, 'scroll', this.setFloatingHeader);
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
/**
|
|
1568
|
+
* Return the module name of this component.
|
|
1569
|
+
*
|
|
1570
|
+
* @private
|
|
1571
|
+
* @returns {string} Return the module name of this component.
|
|
1572
|
+
*/
|
|
1573
|
+
public getModuleName(): string {
|
|
1574
|
+
return 'dropdownbase';
|
|
1575
|
+
}
|
|
1576
|
+
/* eslint-disable valid-jsdoc, jsdoc/require-returns-description */
|
|
1577
|
+
/**
|
|
1578
|
+
* Gets all the list items bound on this component.
|
|
1579
|
+
*
|
|
1580
|
+
* @returns {Element[]}
|
|
1581
|
+
*/
|
|
1582
|
+
public getItems(): Element[] {
|
|
1583
|
+
return <HTMLElement[] & NodeListOf<Element>>this.ulElement.querySelectorAll('.' + dropDownBaseClasses.li);
|
|
1584
|
+
}
|
|
1585
|
+
/* eslint-enable valid-jsdoc, jsdoc/require-returns-description */
|
|
1586
|
+
/**
|
|
1587
|
+
* Adds a new item to the popup list. By default, new item appends to the list as the last item,
|
|
1588
|
+
* but you can insert based on the index parameter.
|
|
1589
|
+
*
|
|
1590
|
+
* @param { Object[] } items - Specifies an array of JSON data or a JSON data.
|
|
1591
|
+
* @param { number } itemIndex - Specifies the index to place the newly added item in the popup list.
|
|
1592
|
+
* @returns {void}
|
|
1593
|
+
* @deprecated
|
|
1594
|
+
*/
|
|
1595
|
+
public addItem(
|
|
1596
|
+
items: { [key: string]: Object }[] | { [key: string]: Object } | string | boolean | number | string[] | boolean[] | number[],
|
|
1597
|
+
itemIndex?: number): void {
|
|
1598
|
+
if (!this.list || (this.list.textContent === this.noRecordsTemplate && this.getModuleName() !== 'listbox')) {
|
|
1599
|
+
this.renderList();
|
|
1600
|
+
}
|
|
1601
|
+
if (this.sortOrder !== 'None' && isNullOrUndefined(itemIndex)) {
|
|
1602
|
+
let newList: { [key: string]: Object }[] = [].slice.call(this.listData as { [key: string]: Object }[]);
|
|
1603
|
+
newList.push(items as { [key: string]: Object });
|
|
1604
|
+
newList = this.getSortedDataSource(newList);
|
|
1605
|
+
if (this.fields.groupBy) {
|
|
1606
|
+
newList = ListBase.groupDataSource(
|
|
1607
|
+
newList, (this.fields as FieldSettingsModel & { properties: Object }).properties, this.sortOrder);
|
|
1608
|
+
itemIndex = newList.indexOf(items as { [key: string]: Object });
|
|
1609
|
+
} else {
|
|
1610
|
+
itemIndex = newList.indexOf(items as { [key: string]: Object });
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
const itemsCount: number = this.getItems().length;
|
|
1614
|
+
const selectedItemValue: Element = this.list.querySelector('.' + dropDownBaseClasses.selected);
|
|
1615
|
+
items = (items instanceof Array ? items : [items]) as { [key: string]: Object }[] | string[] | boolean[] | number[];
|
|
1616
|
+
let index: number;
|
|
1617
|
+
index = (isNullOrUndefined(itemIndex) || itemIndex < 0 || itemIndex > itemsCount - 1) ? itemsCount : itemIndex;
|
|
1618
|
+
const fields: FieldSettingsModel = this.fields;
|
|
1619
|
+
if (items && fields.groupBy) {
|
|
1620
|
+
items = ListBase.groupDataSource(
|
|
1621
|
+
(items as { [key: string]: Object }[]), (fields as FieldSettingsModel & { properties: Object }).properties);
|
|
1622
|
+
}
|
|
1623
|
+
const liCollections: HTMLElement[] = [];
|
|
1624
|
+
for (let i: number = 0; i < items.length; i++) {
|
|
1625
|
+
const item: { [key: string]: Object } | string | boolean | number = items[i as number];
|
|
1626
|
+
const isHeader: boolean = (item as { [key: string]: Object }).isHeader as boolean;
|
|
1627
|
+
const li: HTMLElement = this.createElement(
|
|
1628
|
+
'li', { className: isHeader ? dropDownBaseClasses.group : dropDownBaseClasses.li, id: 'option-add-' + i });
|
|
1629
|
+
|
|
1630
|
+
const itemText: string = item instanceof Object ? getValue(fields.text, item) : item;
|
|
1631
|
+
if (isHeader) {
|
|
1632
|
+
li.innerText = itemText;
|
|
1633
|
+
}
|
|
1634
|
+
if (this.itemTemplate && !isHeader) {
|
|
1635
|
+
const itemCheck: boolean = this.templateCompiler(this.itemTemplate);
|
|
1636
|
+
const compiledString: Function = typeof this.itemTemplate !== 'function' &&
|
|
1637
|
+
itemCheck ? compile(select(this.itemTemplate, document).innerHTML.trim()) : compile(this.itemTemplate);
|
|
1638
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1639
|
+
const addItemTemplate: any = compiledString(
|
|
1640
|
+
item, this, 'itemTemplate', this.itemTemplateId, this.isStringTemplate, null, li);
|
|
1641
|
+
if (addItemTemplate) {
|
|
1642
|
+
append(addItemTemplate, li);
|
|
1643
|
+
}
|
|
1644
|
+
} else if (!isHeader) {
|
|
1645
|
+
li.appendChild(document.createTextNode(itemText));
|
|
1646
|
+
}
|
|
1647
|
+
li.setAttribute('data-value', item instanceof Object ? getValue(fields.value, item) : item);
|
|
1648
|
+
li.setAttribute('role', 'option');
|
|
1649
|
+
this.notify('addItem', { module: 'CheckBoxSelection', item: li });
|
|
1650
|
+
liCollections.push(li);
|
|
1651
|
+
(this.listData as { [key: string]: Object }[]).push(item as { [key: string]: Object });
|
|
1652
|
+
if (this.sortOrder === 'None' && isNullOrUndefined(itemIndex) && index === 0 ) {
|
|
1653
|
+
index = null;
|
|
1654
|
+
}
|
|
1655
|
+
this.updateActionCompleteData(li, item as { [key: string]: Object }, index);
|
|
1656
|
+
//Listbox event
|
|
1657
|
+
this.trigger('beforeItemRender', {element: li, item: item});
|
|
1658
|
+
}
|
|
1659
|
+
if (itemsCount === 0 && isNullOrUndefined(this.list.querySelector('ul'))) {
|
|
1660
|
+
if (!isNullOrUndefined(this.list)) {
|
|
1661
|
+
this.list.innerHTML = '';
|
|
1662
|
+
this.list.classList.remove(dropDownBaseClasses.noData);
|
|
1663
|
+
this.isAddNewItemTemplate = true;
|
|
1664
|
+
if (!isNullOrUndefined(this.ulElement)) {
|
|
1665
|
+
this.list.appendChild(this.ulElement);
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
this.liCollections = liCollections;
|
|
1669
|
+
if (!isNullOrUndefined(liCollections) && !isNullOrUndefined(this.ulElement)) {
|
|
1670
|
+
append(liCollections, this.ulElement);
|
|
1671
|
+
}
|
|
1672
|
+
this.updateAddItemList(this.list, itemsCount);
|
|
1673
|
+
} else {
|
|
1674
|
+
if (this.getModuleName() === 'listbox' && itemsCount === 0) {
|
|
1675
|
+
this.ulElement.innerHTML = '';
|
|
1676
|
+
}
|
|
1677
|
+
const attr: string[] = [];
|
|
1678
|
+
for (let i: number = 0; i < items.length; i++) {
|
|
1679
|
+
const listGroupItem: NodeList = this.ulElement.querySelectorAll('.e-list-group-item');
|
|
1680
|
+
for (let j: number = 0; j < listGroupItem.length; j++) {
|
|
1681
|
+
attr[j as number] = (listGroupItem[j as number] as HTMLElement).innerText;
|
|
1682
|
+
}
|
|
1683
|
+
if (attr.indexOf(liCollections[i as number].innerText) > -1 && fields.groupBy) {
|
|
1684
|
+
for (let j: number = 0; j < listGroupItem.length; j++) {
|
|
1685
|
+
if (attr[j as number] === liCollections[i as number].innerText ) {
|
|
1686
|
+
if (this.sortOrder === 'None') {
|
|
1687
|
+
this.ulElement.insertBefore(liCollections[i + 1], listGroupItem[j + 1]);
|
|
1688
|
+
} else {
|
|
1689
|
+
this.ulElement.insertBefore(liCollections[i + 1], this.ulElement.childNodes[itemIndex as number]);
|
|
1690
|
+
}
|
|
1691
|
+
i = i + 1;
|
|
1692
|
+
break;
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
} else {
|
|
1696
|
+
if (this.liCollections[index as number]) {
|
|
1697
|
+
this.liCollections[index as number].parentNode.insertBefore(liCollections[i as number], this.liCollections[index as number]);
|
|
1698
|
+
} else {
|
|
1699
|
+
this.ulElement.appendChild(liCollections[i as number]);
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
const tempLi: HTMLElement[] = [].slice.call(this.liCollections);
|
|
1703
|
+
tempLi.splice(index, 0, liCollections[i as number]);
|
|
1704
|
+
this.liCollections = tempLi;
|
|
1705
|
+
index += 1;
|
|
1706
|
+
if (this.getModuleName() === 'multiselect') {
|
|
1707
|
+
this.updateDataList();
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
if (this.getModuleName() === 'listbox' && (this as any).isReact) {
|
|
1712
|
+
this.renderReactTemplates();
|
|
1713
|
+
}
|
|
1714
|
+
if (selectedItemValue || itemIndex === 0) {
|
|
1715
|
+
this.updateSelection();
|
|
1716
|
+
}
|
|
1717
|
+
this.addedNewItem = true;
|
|
1718
|
+
}
|
|
1719
|
+
protected validationAttribute(target: HTMLElement, hidden: Element): void {
|
|
1720
|
+
const name: string = target.getAttribute('name') ? target.getAttribute('name') : target.getAttribute('id');
|
|
1721
|
+
hidden.setAttribute('name', name);
|
|
1722
|
+
target.removeAttribute('name');
|
|
1723
|
+
const attributes: string[] = ['required', 'aria-required', 'form'];
|
|
1724
|
+
for (let i: number = 0; i < attributes.length; i++) {
|
|
1725
|
+
if (!target.getAttribute(attributes[i as number])) {
|
|
1726
|
+
continue;
|
|
1727
|
+
}
|
|
1728
|
+
const attr: string = target.getAttribute(attributes[i as number]);
|
|
1729
|
+
hidden.setAttribute(attributes[i as number], attr);
|
|
1730
|
+
target.removeAttribute(attributes[i as number]);
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
protected setZIndex(): void {
|
|
1735
|
+
// this is for component wise
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1739
|
+
protected updateActionCompleteData(li: HTMLElement, item: { [key: string]: Object }, index?: number): void {
|
|
1740
|
+
// this is for ComboBox custom value
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1744
|
+
protected updateAddItemList(list: HTMLElement, itemCount: number): void {
|
|
1745
|
+
// this is for multiselect add item
|
|
1746
|
+
}
|
|
1747
|
+
protected updateDataList(): void {
|
|
1748
|
+
// this is for multiselect update list items
|
|
1749
|
+
}
|
|
1750
|
+
/* eslint-disable valid-jsdoc, jsdoc/require-returns-description */
|
|
1751
|
+
/**
|
|
1752
|
+
* Gets the data Object that matches the given value.
|
|
1753
|
+
*
|
|
1754
|
+
* @param { string | number } value - Specifies the value of the list item.
|
|
1755
|
+
* @returns {Object}
|
|
1756
|
+
*/
|
|
1757
|
+
public getDataByValue(value: string | number | boolean)
|
|
1758
|
+
: { [key: string]: Object } | string | number | boolean {
|
|
1759
|
+
if (!isNullOrUndefined(this.listData)) {
|
|
1760
|
+
const type: string = this.typeOfData(this.listData).typeof as string;
|
|
1761
|
+
if (type === 'string' || type === 'number' || type === 'boolean') {
|
|
1762
|
+
for (const item of this.listData) {
|
|
1763
|
+
if (!isNullOrUndefined(item) && item === value as Object) {
|
|
1764
|
+
return item;
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
} else {
|
|
1768
|
+
for (const item of this.listData) {
|
|
1769
|
+
if (!isNullOrUndefined(item) && getValue((this.fields.value ? this.fields.value : 'value'), item) === value) {
|
|
1770
|
+
return item;
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
return null;
|
|
1776
|
+
}
|
|
1777
|
+
/* eslint-enable valid-jsdoc, jsdoc/require-returns-description */
|
|
1778
|
+
/**
|
|
1779
|
+
* Removes the component from the DOM and detaches all its related event handlers. It also removes the attributes and classes.
|
|
1780
|
+
*
|
|
1781
|
+
* @method destroy
|
|
1782
|
+
* @returns {void}
|
|
1783
|
+
*/
|
|
1784
|
+
public destroy(): void {
|
|
1785
|
+
if (document.body.contains(this.list)) {
|
|
1786
|
+
EventHandler.remove(this.list, 'scroll', this.setFloatingHeader);
|
|
1787
|
+
if (!isNullOrUndefined(this.rippleFun)) {
|
|
1788
|
+
this.rippleFun();
|
|
1789
|
+
}
|
|
1790
|
+
detach(this.list);
|
|
1791
|
+
}
|
|
1792
|
+
this.liCollections = null;
|
|
1793
|
+
this.ulElement = null;
|
|
1794
|
+
this.list = null;
|
|
1795
|
+
this.enableRtlElements = null;
|
|
1796
|
+
this.rippleFun = null;
|
|
1797
|
+
super.destroy();
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
export interface ResultData {
|
|
1801
|
+
/**
|
|
1802
|
+
* To return the JSON result.
|
|
1803
|
+
*/
|
|
1804
|
+
result: { [key: string]: Object }[]
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
export interface FilteringEventArgs {
|
|
1808
|
+
/**
|
|
1809
|
+
* To prevent the internal filtering action.
|
|
1810
|
+
*/
|
|
1811
|
+
preventDefaultAction: boolean
|
|
1812
|
+
/**
|
|
1813
|
+
* Gets the `keyup` event arguments.
|
|
1814
|
+
*/
|
|
1815
|
+
baseEventArgs: Object
|
|
1816
|
+
/**
|
|
1817
|
+
* Illustrates whether the current action needs to be prevented or not.
|
|
1818
|
+
*/
|
|
1819
|
+
cancel: boolean
|
|
1820
|
+
/**
|
|
1821
|
+
* Search text value.
|
|
1822
|
+
*/
|
|
1823
|
+
text: string
|
|
1824
|
+
/**
|
|
1825
|
+
* To filter the data from given data source by using query
|
|
1826
|
+
*
|
|
1827
|
+
* @param {Object[] | DataManager } dataSource - Set the data source to filter.
|
|
1828
|
+
* @param {Query} query - Specify the query to filter the data.
|
|
1829
|
+
* @param {FieldSettingsModel} fields - Specify the fields to map the column in the data table.
|
|
1830
|
+
* @returns {void}
|
|
1831
|
+
*/
|
|
1832
|
+
updateData(dataSource: { [key: string]: Object }[] | DataManager | string[] | number[] | boolean[], query?: Query,
|
|
1833
|
+
fields?: FieldSettingsModel): void
|
|
1834
|
+
}
|
|
1835
|
+
export interface PopupEventArgs {
|
|
1836
|
+
/**
|
|
1837
|
+
* Specifies the popup Object.
|
|
1838
|
+
*
|
|
1839
|
+
* @deprecated
|
|
1840
|
+
*/
|
|
1841
|
+
popup: Popup
|
|
1842
|
+
/**
|
|
1843
|
+
* Illustrates whether the current action needs to be prevented or not.
|
|
1844
|
+
*/
|
|
1845
|
+
cancel?: boolean
|
|
1846
|
+
/**
|
|
1847
|
+
* Specifies the animation Object.
|
|
1848
|
+
*/
|
|
1849
|
+
animation?: AnimationModel
|
|
1850
|
+
/**
|
|
1851
|
+
* Specifies the event.
|
|
1852
|
+
*/
|
|
1853
|
+
event?: MouseEvent | KeyboardEventArgs | TouchEvent | Object
|
|
1854
|
+
}
|
|
1855
|
+
export interface FocusEventArgs {
|
|
1856
|
+
/**
|
|
1857
|
+
* Specifies the focus interacted.
|
|
1858
|
+
*/
|
|
1859
|
+
isInteracted?: boolean
|
|
1860
|
+
/**
|
|
1861
|
+
* Specifies the event.
|
|
1862
|
+
*/
|
|
1863
|
+
event?: MouseEvent | FocusEvent | TouchEvent | KeyboardEvent
|
|
1864
|
+
}
|