@syncfusion/ej2-dropdowns 18.2.44-4568 → 18.2.44-4570

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