@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,528 @@
1
+ import { createCheckBox } from '@syncfusion/ej2-buttons';
2
+ import { IMulitSelect } from './interface';
3
+ import { Input, InputObject } from '@syncfusion/ej2-inputs';
4
+ import { EventHandler, select, removeClass, addClass, detach, compile, L10n, isBlazor } from '@syncfusion/ej2-base';
5
+ import { Browser, attributes, isNullOrUndefined, KeyboardEventArgs, append, closest, prepend } from '@syncfusion/ej2-base';
6
+ import { dropDownBaseClasses } from '../drop-down-base/drop-down-base';
7
+ import { MultiSelectModel } from '../multi-select';
8
+
9
+
10
+ const ICON: string = 'e-icons';
11
+ const CHECKBOXFRAME: string = 'e-frame';
12
+ const CHECK: string = 'e-check';
13
+ const CHECKBOXWRAP: string = 'e-checkbox-wrapper';
14
+ const CHECKBOXRIPPLE: string = 'e-ripple-container';
15
+ const INDETERMINATE: string = 'e-stop';
16
+ const checkAllParent: string = 'e-selectall-parent';
17
+ const searchBackIcon: string = 'e-input-group-icon e-back-icon e-icons';
18
+ const filterBarClearIcon: string = 'e-input-group-icon e-clear-icon e-icons';
19
+ const filterInput: string = 'e-input-filter';
20
+ const filterParent: string = 'e-filter-parent';
21
+ const mobileFilter: string = 'e-ddl-device-filter';
22
+ const clearIcon: string = 'e-clear-icon';
23
+ const popupFullScreen: string = 'e-popup-full-page';
24
+ const device: string = 'e-ddl-device';
25
+ const FOCUS: string = 'e-input-focus';
26
+
27
+ /**
28
+ * The Multiselect enable CheckBoxSelection call this inject module.
29
+ */
30
+
31
+ export class CheckBoxSelection {
32
+ private parent: IMulitSelect;
33
+ private checkAllParent: HTMLElement;
34
+ private selectAllSpan: HTMLElement;
35
+ public filterInput: HTMLInputElement;
36
+ private filterInputObj: InputObject;
37
+ private backIconElement: Element;
38
+ private clearIconElement: Element;
39
+ private checkWrapper: HTMLElement;
40
+ public list: HTMLElement;
41
+ private activeLi: HTMLElement[] = [];
42
+ private activeEle: HTMLElement[] = [];
43
+ constructor(parent?: IMulitSelect) {
44
+ this.parent = parent;
45
+ this.addEventListener();
46
+ }
47
+ public getModuleName(): string {
48
+ return 'CheckBoxSelection';
49
+ }
50
+
51
+ public addEventListener(): void {
52
+ if (this.parent.isDestroyed) { return; }
53
+ this.parent.on('updatelist', this.listSelection, this);
54
+ this.parent.on('listoption', this.listOption, this);
55
+ this.parent.on('selectAll', this.setSelectAll, this);
56
+ this.parent.on('checkSelectAll', this.checkSelectAll, this);
57
+ this.parent.on('searchBox', this.setSearchBox, this);
58
+ this.parent.on('blur', this.onBlur, this);
59
+ this.parent.on('targetElement', this.targetElement, this);
60
+ this.parent.on('deviceSearchBox', this.setDeviceSearchBox, this);
61
+ this.parent.on('inputFocus', this.getFocus, this);
62
+ this.parent.on('reOrder', this.setReorder, this);
63
+ this.parent.on('activeList', this.getActiveList, this);
64
+ this.parent.on('selectAllText', this.setLocale, this);
65
+ this.parent.on('filterBarPlaceholder', this.setPlaceholder, this);
66
+ EventHandler.add(document, 'mousedown', this.onDocumentClick, this);
67
+ this.parent.on('addItem', this.checboxCreate, this);
68
+ this.parent.on('popupFullScreen', this.setPopupFullScreen, this);
69
+ }
70
+ public removeEventListener(): void {
71
+ if (this.parent.isDestroyed) { return; }
72
+ this.parent.off('updatelist', this.listSelection);
73
+ this.parent.off('listoption', this.listOption);
74
+ this.parent.off('selectAll', this.setSelectAll);
75
+ this.parent.off('checkSelectAll', this.checkSelectAll);
76
+ this.parent.off('searchBox', this.setSearchBox);
77
+ this.parent.off('blur', this.onBlur);
78
+ this.parent.off('targetElement', this.targetElement);
79
+ this.parent.off('deviceSearchBox', this.setDeviceSearchBox);
80
+ this.parent.off('inputFocus', this.getFocus);
81
+ this.parent.off('reOrder', this.setReorder);
82
+ this.parent.off('activeList', this.getActiveList);
83
+ this.parent.off('selectAllText', this.setLocale);
84
+ this.parent.off('filterBarPlaceholder', this.setPlaceholder);
85
+ this.parent.off('addItem', this.checboxCreate);
86
+ EventHandler.remove(document, 'mousedown', this.onDocumentClick);
87
+ this.parent.off('popupFullScreen', this.setPopupFullScreen);
88
+ }
89
+
90
+ public listOption(args: { [key: string]: Object }): void {
91
+ if (isNullOrUndefined(this.parent.listCurrentOptions.itemCreated)) {
92
+ this.parent.listCurrentOptions.itemCreated = (e: { [key: string]: HTMLElement }) => {
93
+ this.checboxCreate(e);
94
+ };
95
+ } else {
96
+ let itemCreated: Function = <Function>this.parent.listCurrentOptions.itemCreated;
97
+ this.parent.listCurrentOptions.itemCreated = (e: { [key: string]: HTMLElement }) => {
98
+ this.checboxCreate(e);
99
+ itemCreated.apply(this, [e]);
100
+ };
101
+ }
102
+ };
103
+ private setPlaceholder(props: MultiSelectModel): void {
104
+ Input.setPlaceholder(props.filterBarPlaceholder, this.filterInput as HTMLInputElement);
105
+ }
106
+ private checboxCreate(e: { [key: string]: HTMLElement } | HTMLElement): { [key: string]: HTMLElement } | HTMLElement {
107
+ let item: { [key: string]: HTMLElement } | HTMLElement;
108
+ if (!isNullOrUndefined((e as { [key: string]: HTMLElement }).item)) {
109
+ item = (e as { [key: string]: HTMLElement }).item;
110
+ } else {
111
+ item = e;
112
+ }
113
+ if (this.parent.enableGroupCheckBox || ((item as HTMLElement).className !== 'e-list-group-item '
114
+ && (item as HTMLElement).className !== 'e-list-group-item')) {
115
+ let checkboxEle: HTMLElement | Element | string = createCheckBox(this.parent.createElement, true);
116
+ let icon: Element = select('div.' + ICON, (item as HTMLElement));
117
+ let id: string = (item as HTMLElement).getAttribute('data-uid');
118
+ (item as HTMLElement).insertBefore(checkboxEle, (item as HTMLElement).childNodes[isNullOrUndefined(icon) ? 0 : 1]);
119
+ select('.' + CHECKBOXFRAME, checkboxEle);
120
+ let frame: Element = select('.' + CHECKBOXFRAME, checkboxEle);
121
+ if (this.parent.enableGroupCheckBox ) {
122
+ this.parent.popupWrapper.classList.add('e-multiselect-group');
123
+ }
124
+ return item;
125
+ } else {
126
+ return item;
127
+ }
128
+ }
129
+
130
+ private setSelectAll(): void {
131
+ if (this.parent.showSelectAll) {
132
+ if (isNullOrUndefined(this.checkAllParent)) {
133
+ this.checkAllParent = this.parent.createElement('div', {
134
+ className: checkAllParent
135
+ });
136
+ this.selectAllSpan = this.parent.createElement('span', {
137
+ className: 'e-all-text'
138
+ });
139
+ this.selectAllSpan.textContent = '';
140
+ this.checkAllParent.appendChild(this.selectAllSpan);
141
+ this.setLocale();
142
+ this.checboxCreate(this.checkAllParent as { [key: string]: HTMLElement } | HTMLElement);
143
+ if (this.parent.headerTemplate) {
144
+ if (!isNullOrUndefined(this.parent.filterParent)) {
145
+ append([this.checkAllParent], this.parent.filterParent);
146
+ } else {
147
+ append([this.checkAllParent], this.parent.popupWrapper);
148
+ }
149
+ }
150
+ if (!this.parent.headerTemplate) {
151
+ if (!isNullOrUndefined(this.parent.filterParent)) {
152
+ this.parent.filterParent.parentNode.insertBefore(this.checkAllParent, this.parent.filterParent.nextSibling);
153
+ } else {
154
+ prepend([this.checkAllParent], this.parent.popupWrapper);
155
+ }
156
+ }
157
+ EventHandler.add(this.checkAllParent, 'mousedown', this.clickHandler, this);
158
+ }
159
+ if (this.parent.list.classList.contains('e-nodata') || (this.parent.listData && this.parent.listData.length <= 1)) {
160
+ this.checkAllParent.style.display = 'none';
161
+ } else {
162
+ this.checkAllParent.style.display = 'block';
163
+ }
164
+ this.parent.selectAllHeight = this.checkAllParent.getBoundingClientRect().height;
165
+ } else if (!isNullOrUndefined(this.checkAllParent)) {
166
+ this.checkAllParent.parentElement.removeChild(this.checkAllParent);
167
+ this.checkAllParent = null;
168
+ }
169
+ }
170
+
171
+ public destroy(): void {
172
+ this.removeEventListener();
173
+ }
174
+ public listSelection(args: IUpdateListArgs): void {
175
+ let target: EventTarget;
176
+ let isBlazorListbox: boolean = isBlazor() && (args.module && args.module === 'listbox');
177
+ if (!isNullOrUndefined(args.e)) {
178
+ let frameElm: Element = args.li.querySelector('.e-checkbox-wrapper .e-frame');
179
+ target = !isNullOrUndefined(args.e.target) ?
180
+ ((args.e.target as HTMLElement).classList.contains('e-frame')
181
+ && (!this.parent.showSelectAll
182
+ || ( this.checkAllParent && !this.checkAllParent.contains(args.e.target as Element)))) ?
183
+ args.e.target : (isBlazorListbox ? frameElm : args.li.querySelector('.e-checkbox-wrapper').childNodes[1])
184
+ : (isBlazorListbox ? frameElm : args.li.querySelector('.e-checkbox-wrapper').childNodes[1]);
185
+ } else {
186
+ let checkboxWrapper: Element = args.li.querySelector('.e-checkbox-wrapper');
187
+ target = checkboxWrapper ? (isBlazorListbox ?
188
+ checkboxWrapper.querySelector('.e-frame') : checkboxWrapper.childNodes[1]) : args.li.lastElementChild.childNodes[1];
189
+ }
190
+ if (this.parent.itemTemplate || this.parent.enableGroupCheckBox ) {
191
+ target = args.li.firstElementChild.childNodes[1];
192
+ }
193
+ if (!isNullOrUndefined(target)) {
194
+ this.checkWrapper = closest((target as HTMLElement), '.' + CHECKBOXWRAP) as HTMLElement;
195
+ }
196
+ if (!isNullOrUndefined(this.checkWrapper)) {
197
+ let checkElement: Element = select('.' + CHECKBOXFRAME, this.checkWrapper);
198
+ let selectAll: boolean = false;
199
+ this.validateCheckNode(this.checkWrapper, checkElement.classList.contains(CHECK), args.li, args.e, selectAll);
200
+ }
201
+ }
202
+ private validateCheckNode(
203
+ checkWrap: HTMLElement | Element,
204
+ isCheck: boolean, li?: HTMLElement | Element,
205
+ e?: KeyboardEventArgs | MouseEvent, selectAll?: boolean): void {
206
+ this.changeState(checkWrap, isCheck ? 'uncheck' : 'check', e, true, selectAll);
207
+ }
208
+ private clickHandler(e: MouseEvent): void {
209
+ let target: EventTarget;
210
+ if ((e.currentTarget as HTMLElement).classList.contains(this.checkAllParent.className)) {
211
+ target = (e.currentTarget as HTMLElement).firstElementChild.lastElementChild;
212
+ } else {
213
+ target = <Element>e.currentTarget;
214
+ }
215
+ this.checkWrapper = closest((target as HTMLElement), '.' + CHECKBOXWRAP) as HTMLElement;
216
+ let selectAll: boolean = true;
217
+ if (!isNullOrUndefined(this.checkWrapper)) {
218
+ let checkElement: Element = select('.' + CHECKBOXFRAME, this.checkWrapper);
219
+ this.validateCheckNode(this.checkWrapper, checkElement.classList.contains(CHECK), null, e, selectAll);
220
+ }
221
+ e.preventDefault();
222
+ }
223
+ private changeState(
224
+ wrapper: HTMLElement | Element, state: string, e?: MouseEvent | KeyboardEventArgs, isPrevent?: boolean, selectAll?: boolean): void {
225
+ let ariaState: string;
226
+ let frameSpan: Element = wrapper.getElementsByClassName(CHECKBOXFRAME)[0];
227
+ if (state === 'check' && !frameSpan.classList.contains(CHECK)) {
228
+ frameSpan.classList.remove(INDETERMINATE);
229
+ frameSpan.classList.add(CHECK);
230
+ ariaState = 'true';
231
+ if (selectAll) {
232
+ this.parent.selectAllItems(true, e as MouseEvent);
233
+ this.setLocale(true);
234
+ }
235
+ } else if (state === 'uncheck' && (frameSpan.classList.contains(CHECK) || frameSpan.classList.contains(INDETERMINATE))) {
236
+ removeClass([frameSpan], [CHECK, INDETERMINATE]);
237
+ ariaState = 'false';
238
+ if (selectAll) {
239
+ this.parent.selectAllItems(false, e as MouseEvent);
240
+ this.setLocale();
241
+ }
242
+ } else if (state === 'indeterminate' && !(frameSpan.classList.contains(INDETERMINATE))) {
243
+ removeClass([frameSpan], [CHECK]);
244
+ frameSpan.classList.add(INDETERMINATE);
245
+ ariaState = 'false';
246
+ if (selectAll) {
247
+ this.parent.selectAllItems(false, e as MouseEvent);
248
+ this.setLocale();
249
+ }
250
+ }
251
+ ariaState = state === 'check' ? 'true' : state === 'uncheck' ? 'false' : ariaState;
252
+ if (!isNullOrUndefined(ariaState)) {
253
+ wrapper.setAttribute('aria-checked', ariaState);
254
+ }
255
+ }
256
+ protected setSearchBox(args: IUpdateListArgs): InputObject | void {
257
+ if (isNullOrUndefined(this.parent.filterParent)) {
258
+ this.parent.filterParent = this.parent.createElement('span', {
259
+ className: filterParent
260
+ });
261
+ this.filterInput = <HTMLInputElement>this.parent.createElement('input', {
262
+ attrs: { type: 'text' },
263
+ className: filterInput
264
+ });
265
+ this.parent.element.parentNode.insertBefore(this.filterInput, this.parent.element);
266
+ let backIcon: boolean = false;
267
+ if (Browser.isDevice) {
268
+ backIcon = true;
269
+ this.parent.mobFilter = false;
270
+ }
271
+ this.filterInputObj = Input.createInput(
272
+ {
273
+ element: this.filterInput,
274
+ buttons: backIcon ? [searchBackIcon, filterBarClearIcon] : [filterBarClearIcon],
275
+ properties: { placeholder: this.parent.filterBarPlaceholder }
276
+ },
277
+ this.parent.createElement
278
+ );
279
+ if (!isNullOrUndefined(this.parent.cssClass)) {
280
+ if (this.parent.cssClass.split(' ').indexOf('e-outline') !== -1) {
281
+ addClass([this.filterInputObj.container], 'e-outline');
282
+ } else if (this.parent.cssClass.split(' ').indexOf('e-filled') !== -1) {
283
+ addClass([this.filterInputObj.container], 'e-filled');
284
+ }
285
+ }
286
+ append([this.filterInputObj.container], this.parent.filterParent);
287
+ prepend([this.parent.filterParent], args.popupElement);
288
+ attributes(this.filterInput, {
289
+ 'aria-disabled': 'false',
290
+ 'aria-owns': this.parent.element.id + '_options',
291
+ 'role': 'listbox',
292
+ 'aria-activedescendant': null,
293
+ 'autocomplete': 'off',
294
+ 'autocorrect': 'off',
295
+ 'autocapitalize': 'off',
296
+ 'spellcheck': 'false'
297
+ });
298
+ this.clearIconElement = this.filterInput.parentElement.querySelector('.' + clearIcon);
299
+ if (!Browser.isDevice && this.clearIconElement) {
300
+ EventHandler.add(this.clearIconElement, 'mousedown', this.clearText, this);
301
+ (this.clearIconElement as HTMLElement).style.visibility = 'hidden';
302
+ }
303
+ EventHandler.add(this.filterInput, 'input', this.parent.onInput, this.parent);
304
+ EventHandler.add(this.filterInput, 'keyup', this.parent.KeyUp, this.parent);
305
+ EventHandler.add(this.filterInput, 'keydown', this.parent.onKeyDown, this.parent);
306
+ EventHandler.add(this.filterInput, 'blur', this.onBlur, this);
307
+ EventHandler.add(this.filterInput, 'paste', this.parent.pasteHandler, this.parent);
308
+ this.parent.searchBoxHeight = (this.filterInputObj.container.parentElement).getBoundingClientRect().height;
309
+ return this.filterInputObj;
310
+ }
311
+ };
312
+
313
+ private clickOnBackIcon(e: EventHandler): void {
314
+ this.parent.hidePopup();
315
+ removeClass([document.body, this.parent.popupObj.element], popupFullScreen);
316
+ this.parent.inputElement.focus();
317
+ }
318
+ private clearText(e: MouseEvent): void {
319
+ (this.parent.targetInputElement as HTMLInputElement).value = '';
320
+ this.parent.refreshPopup();
321
+ this.parent.refreshListItems(null);
322
+ (this.clearIconElement as HTMLElement).style.visibility = 'hidden';
323
+ this.filterInput.focus();
324
+ this.setReorder(e);
325
+ e.preventDefault();
326
+ }
327
+
328
+ private setDeviceSearchBox(): void {
329
+ this.parent.popupObj.element.classList.add(device);
330
+ this.parent.popupObj.element.classList.add(mobileFilter);
331
+ this.parent.popupObj.position = { X: 0, Y: 0 };
332
+ this.parent.popupObj.dataBind();
333
+ this.setSearchBoxPosition();
334
+ this.backIconElement = this.filterInputObj.container.querySelector('.e-back-icon');
335
+ this.clearIconElement = this.filterInputObj.container.querySelector('.' + clearIcon);
336
+ (this.clearIconElement as HTMLElement).style.visibility = 'hidden';
337
+ EventHandler.add(this.backIconElement, 'click', this.clickOnBackIcon, this);
338
+ EventHandler.add(this.clearIconElement, 'click', this.clearText, this);
339
+ }
340
+
341
+ private setSearchBoxPosition(): void {
342
+ let searchBoxHeight: number = this.filterInput.parentElement.getBoundingClientRect().height;
343
+ let selectAllHeight: number = 0;
344
+ if (this.checkAllParent) {
345
+ selectAllHeight = this.checkAllParent.getBoundingClientRect().height;
346
+ }
347
+ this.parent.popupObj.element.style.maxHeight = '100%';
348
+ this.parent.popupObj.element.style.width = '100%';
349
+ this.parent.list.style.maxHeight = (window.innerHeight - searchBoxHeight - selectAllHeight) + 'px';
350
+ this.parent.list.style.height = (window.innerHeight - searchBoxHeight - selectAllHeight) + 'px';
351
+ let clearElement: Element = this.filterInput.parentElement.querySelector('.' + clearIcon);
352
+ detach(this.filterInput);
353
+ clearElement.parentElement.insertBefore(this.filterInput, clearElement);
354
+ }
355
+
356
+ protected setPopupFullScreen(): void {
357
+ attributes(this.parent.popupObj.element, { style: 'left:0px;right:0px;top:0px;bottom:0px;' });
358
+ addClass([document.body, this.parent.popupObj.element], popupFullScreen);
359
+ this.parent.popupObj.element.style.maxHeight = '100%';
360
+ this.parent.popupObj.element.style.width = '100%';
361
+ }
362
+
363
+ protected targetElement(): string {
364
+ if (!isNullOrUndefined(this.clearIconElement)) {
365
+ this.parent.targetInputElement = this.filterInput;
366
+ (this.clearIconElement as HTMLElement).style.visibility = this.parent.targetInputElement.value === '' ? 'hidden' : 'visible';
367
+ }
368
+ return (this.parent.targetInputElement as HTMLInputElement).value;
369
+ }
370
+
371
+ private onBlur(e: MouseEvent): void {
372
+ if (!this.parent.element.classList.contains('e-listbox')) {
373
+ let target: HTMLElement;
374
+ if (this.parent.keyAction) { return; }
375
+ if (Browser.isIE) {
376
+ target = !isNullOrUndefined(e) && <HTMLElement>e.target;
377
+ }
378
+ if (!Browser.isIE) {
379
+ target = !isNullOrUndefined(e) && <HTMLElement>e.relatedTarget;
380
+ }
381
+ if (this.parent.popupObj && document.body.contains(this.parent.popupObj.element) && this.parent.popupObj.element.contains(target)
382
+ && !Browser.isIE && this.filterInput) {
383
+ this.filterInput.focus();
384
+ return;
385
+ }
386
+ if (this.parent.scrollFocusStatus && this.filterInput) {
387
+ e.preventDefault();
388
+ this.filterInput.focus();
389
+ this.parent.scrollFocusStatus = false;
390
+ return;
391
+ }
392
+ if (this.parent.popupObj && document.body.contains(this.parent.popupObj.element)
393
+ && !this.parent.popupObj.element.classList.contains('e-popup-close')) {
394
+ this.parent.inputFocus = false;
395
+ this.parent.updateValueState(e, this.parent.value, this.parent.tempValues);
396
+ this.parent.dispatchEvent(this.parent.hiddenElement as HTMLElement, 'change');
397
+ }
398
+ if (this.parent.popupObj && document.body.contains(this.parent.popupObj.element) &&
399
+ !this.parent.popupObj.element.classList.contains('e-popup-close')) {
400
+ this.parent.inputFocus = false;
401
+ this.parent.overAllWrapper.classList.remove(FOCUS);
402
+ this.parent.trigger('blur');
403
+ this.parent.focused = true;
404
+ }
405
+ if (this.parent.popupObj && document.body.contains(this.parent.popupObj.element) &&
406
+ !this.parent.popupObj.element.classList.contains('e-popup-close') && !Browser.isDevice) {
407
+ this.parent.hidePopup();
408
+ }
409
+ }
410
+ }
411
+ protected onDocumentClick(e: MouseEvent): void {
412
+ if (this.parent.getLocaleName() !== 'listbox') {
413
+ let target: HTMLElement = <HTMLElement>e.target;
414
+ if (!isNullOrUndefined(this.parent.popupObj) && closest(target, '#' + this.parent.popupObj.element.id)) {
415
+ e.preventDefault();
416
+ }
417
+ if (!(!isNullOrUndefined(this.parent.popupObj) && closest(target, '#' + this.parent.popupObj.element.id)) &&
418
+ !this.parent.overAllWrapper.contains(e.target as Node)) {
419
+ if (this.parent.overAllWrapper.classList.contains(dropDownBaseClasses.focus) || this.parent.isPopupOpen()) {
420
+ this.parent.inputFocus = false;
421
+ this.parent.scrollFocusStatus = false;
422
+ this.parent.hidePopup();
423
+ this.parent.onBlur(e, true);
424
+ this.parent.focused = true;
425
+ }
426
+ } else {
427
+ this.parent.scrollFocusStatus = (Browser.isIE || Browser.info.name === 'edge') && (document.activeElement === this.filterInput);
428
+ }
429
+ if (!this.parent.overAllWrapper.contains(e.target as Node) && this.parent.overAllWrapper.classList.contains('e-input-focus') &&
430
+ !this.parent.isPopupOpen()) {
431
+ if (Browser.isIE) {
432
+ this.parent.onBlur();
433
+ } else {
434
+ this.parent.onBlur(e);
435
+ }
436
+ }
437
+ if (this.filterInput === target) { this.filterInput.focus(); }
438
+ }
439
+ }
440
+ private getFocus(e: IUpdateListArgs): void {
441
+ this.parent.overAllWrapper.classList.remove(FOCUS);
442
+ if (this.parent.keyAction && e.value !== 'clear') {
443
+ this.parent.keyAction = false;
444
+ return;
445
+ }
446
+ if (e.value === 'focus') {
447
+ this.filterInput.focus();
448
+ this.parent.removeFocus();
449
+ EventHandler.remove(this.parent.list, 'keydown', this.parent.onKeyDown);
450
+ }
451
+ if (e.value === 'clear') {
452
+ this.filterInput.value = '';
453
+ (this.clearIconElement as HTMLElement).style.visibility = 'hidden';
454
+ }
455
+ }
456
+ private checkSelectAll(e: IUpdateListArgs): void {
457
+ if (e.value === 'check' && this.checkAllParent.getAttribute('aria-checked') !== 'true') {
458
+ this.changeState(this.checkAllParent, e.value, null, null, false);
459
+ this.setLocale(true);
460
+ }
461
+ if (e.value === 'uncheck') {
462
+ this.changeState(this.checkAllParent, e.value, null, null, false);
463
+ this.setLocale();
464
+ }
465
+ if (e.value === 'indeterminate') {
466
+ this.changeState(this.checkAllParent, e.value, null, null, false);
467
+ this.setLocale();
468
+ }
469
+ }
470
+ private setLocale(unSelect?: boolean): void {
471
+ if (this.parent.selectAllText !== 'Select All' || this.parent.unSelectAllText !== 'Unselect All') {
472
+ let template: string = unSelect ? this.parent.unSelectAllText : this.parent.selectAllText;
473
+ let compiledString: Function;
474
+ this.selectAllSpan.textContent = '';
475
+ compiledString = compile(template);
476
+ for (let item of compiledString({}, null, null, null, !this.parent.isStringTemplate)) {
477
+ this.selectAllSpan.textContent = item.textContent;
478
+ }
479
+ } else {
480
+ let l10nLocale: Object = { selectAllText: 'Select All', unSelectAllText: 'Unselect All' };
481
+ let l10n: L10n = new L10n(this.parent.getLocaleName(), {}, this.parent.locale);
482
+ if (l10n.getConstant('selectAllText') === '') {
483
+ l10n = new L10n('dropdowns', l10nLocale, this.parent.locale);
484
+ }
485
+ this.selectAllSpan.textContent = unSelect ? l10n.getConstant('unSelectAllText') : l10n.getConstant('selectAllText');
486
+ }
487
+ }
488
+ private getActiveList(args: IUpdateListArgs): void {
489
+ if (args.li.classList.contains('e-active')) {
490
+ this.activeLi.push(args.li.cloneNode(true) as HTMLElement);
491
+ } else {
492
+ this.activeLi.splice(args.index, 1);
493
+ }
494
+ }
495
+ private setReorder(args: IUpdateListArgs | MouseEvent): void {
496
+ if (this.parent.enableSelectionOrder && !isNullOrUndefined(this.parent.value)) {
497
+ let activeLiCount: number = this.parent.ulElement.querySelectorAll('li.e-active').length;
498
+ let remLi: NodeListOf<Element>;
499
+ let ulEle: HTMLElement = this.parent.createElement('ul', {
500
+ className: 'e-list-parent e-ul e-reorder'
501
+ });
502
+ let removeEle: HTMLElement = this.parent.createElement('div');
503
+ if (activeLiCount > 0) {
504
+ append(this.parent.ulElement.querySelectorAll('li.e-active'), ulEle);
505
+ remLi = this.parent.ulElement.querySelectorAll('li.e-active');
506
+ addClass(remLi, 'e-reorder-hide');
507
+ prepend([ulEle], this.parent.list);
508
+ }
509
+ this.parent.focusAtFirstListItem();
510
+ }
511
+ }
512
+ }
513
+
514
+ export interface ItemCreatedArgs {
515
+ curData: { [key: string]: Object };
516
+ item: HTMLElement;
517
+ text: string;
518
+ }
519
+
520
+ export interface IUpdateListArgs {
521
+ module: string;
522
+ enable: boolean;
523
+ li: HTMLElement;
524
+ e: MouseEvent | KeyboardEventArgs;
525
+ popupElement: HTMLElement;
526
+ value: string;
527
+ index: number;
528
+ }
@@ -0,0 +1,155 @@
1
+ /**
2
+ * FloatLable Moduel
3
+ * Specifies whether to display the floating label above the input element.
4
+ */
5
+ import { removeClass, addClass, detach } from '@syncfusion/ej2-base';
6
+ import { attributes, isNullOrUndefined, createElement } from '@syncfusion/ej2-base';
7
+ import { FloatLabelType } from '@syncfusion/ej2-inputs';
8
+
9
+ const FLOATLINE: string = 'e-float-line';
10
+ const FLOATTEXT: string = 'e-float-text';
11
+ const LABELTOP: string = 'e-label-top';
12
+ const LABELBOTTOM: string = 'e-label-bottom';
13
+
14
+
15
+ /**
16
+ * Function to create Float Label element.
17
+ * @param overAllWrapper - overall wrapper of multiselect.
18
+ * @param element - the given html element.
19
+ * @param inputElement - specify the input wrapper.
20
+ * @param value - Value of the MultiSelect.
21
+ * @param floatLabelType - Specify the FloatLabel Type.
22
+ * @param placeholder - Specify the PlaceHolder text.
23
+ */
24
+ export function createFloatLabel(
25
+ overAllWrapper: HTMLDivElement,
26
+ searchWrapper: HTMLElement, element: HTMLElement,
27
+ inputElement: HTMLInputElement, value: number[] | string[] | boolean[], floatLabelType: FloatLabelType,
28
+ placeholder: string): void {
29
+ let floatLinelement: HTMLElement;
30
+ let floatLabelElement: HTMLElement;
31
+ floatLinelement = createElement('span', { className: FLOATLINE });
32
+ floatLabelElement = createElement('label', { className: FLOATTEXT });
33
+ if (!isNullOrUndefined(element.id) && element.id !== '') {
34
+ floatLabelElement.id = 'label_' + element.id.replace(/ /g, '_');
35
+ attributes(element, { 'aria-labelledby': floatLabelElement.id });
36
+ }
37
+ if (!isNullOrUndefined(inputElement.placeholder) && inputElement.placeholder !== '') {
38
+ floatLabelElement.innerHTML = inputElement.placeholder;
39
+ inputElement.removeAttribute('placeholder');
40
+ }
41
+ floatLabelElement.innerHTML = placeholder;
42
+ searchWrapper.appendChild(floatLinelement);
43
+ searchWrapper.appendChild(floatLabelElement);
44
+ overAllWrapper.classList.add('e-float-input');
45
+ updateFloatLabelState(value, floatLabelElement);
46
+ if (floatLabelType === 'Always') {
47
+ if (floatLabelElement.classList.contains(LABELBOTTOM)) {
48
+ removeClass([floatLabelElement], LABELBOTTOM);
49
+ }
50
+ addClass([floatLabelElement], LABELTOP);
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Function to update status of the Float Label element.
56
+ * @param value - Value of the MultiSelect.
57
+ * @param label - float label element.
58
+ */
59
+ export function updateFloatLabelState(value: string[] | number[] | boolean[], label: HTMLElement): void {
60
+ if (value && value.length > 0) {
61
+ addClass([label], LABELTOP);
62
+ removeClass([label], LABELBOTTOM);
63
+ } else {
64
+ removeClass([label], LABELTOP);
65
+ addClass([label], LABELBOTTOM);
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Function to remove Float Label element.
71
+ * @param overAllWrapper - overall wrapper of multiselect.
72
+ * @param componentWrapper - wrapper element of multiselect.
73
+ * @param searchWrapper - search wrapper of multiselect.
74
+ * @param inputElement - specify the input wrapper.
75
+ * @param value - Value of the MultiSelect.
76
+ * @param floatLabelType - Specify the FloatLabel Type.
77
+ * @param placeholder - Specify the PlaceHolder text.
78
+ */
79
+ export function removeFloating(
80
+ overAllWrapper: HTMLDivElement,
81
+ componentWrapper: HTMLDivElement,
82
+ searchWrapper: HTMLElement,
83
+ inputElement: HTMLInputElement,
84
+ value: number[] | string[] | boolean[],
85
+ floatLabelType: FloatLabelType,
86
+ placeholder: string): void {
87
+ let placeholderElement: HTMLElement = componentWrapper.querySelector('.' + FLOATTEXT) as HTMLElement;
88
+ let floatLine: HTMLElement = componentWrapper.querySelector('.' + FLOATLINE) as HTMLElement;
89
+ let placeholderText: string;
90
+ if (!isNullOrUndefined(placeholderElement)) {
91
+ placeholderText = placeholderElement.innerText;
92
+ detach(searchWrapper.querySelector('.' + FLOATTEXT));
93
+ setPlaceHolder(value, inputElement, placeholderText);
94
+ if (!isNullOrUndefined(floatLine)) {
95
+ detach(searchWrapper.querySelector('.' + FLOATLINE));
96
+ }
97
+ } else {
98
+ placeholderText = (placeholder !== null) ? placeholder : '';
99
+ setPlaceHolder(value, inputElement, placeholderText);
100
+ }
101
+ overAllWrapper.classList.remove('e-float-input');
102
+ }
103
+
104
+ /**
105
+ * Function to set the placeholder to the element.
106
+ * @param value - Value of the MultiSelect.
107
+ * @param inputElement - specify the input wrapper.
108
+ * @param placeholder - Specify the PlaceHolder text.
109
+ */
110
+ export function setPlaceHolder(value: number[] | string[] | boolean[], inputElement: HTMLInputElement, placeholder: string): void {
111
+ if (value && value.length) {
112
+ inputElement.placeholder = '';
113
+ } else {
114
+ inputElement.placeholder = placeholder;
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Function for focusing the Float Element.
120
+ * @param overAllWrapper - overall wrapper of multiselect.
121
+ * @param componentWrapper - wrapper element of multiselect.
122
+ */
123
+ export function floatLabelFocus(overAllWrapper: HTMLDivElement, componentWrapper: HTMLDivElement): void {
124
+ overAllWrapper.classList.add('e-input-focus');
125
+ let label: Element = componentWrapper.querySelector('.' + FLOATTEXT);
126
+ if (!isNullOrUndefined(label)) {
127
+ addClass([label], LABELTOP);
128
+ if (label.classList.contains(LABELBOTTOM)) {
129
+ removeClass([label], LABELBOTTOM);
130
+ }
131
+ }
132
+ }
133
+ /**
134
+ * Function to focus the Float Label element.
135
+ * @param overAllWrapper - overall wrapper of multiselect.
136
+ * @param componentWrapper - wrapper element of multiselect.
137
+ * @param value - Value of the MultiSelect.
138
+ * @param floatLabelType - Specify the FloatLabel Type.
139
+ * @param placeholder - Specify the PlaceHolder text.
140
+ */
141
+ export function floatLabelBlur(
142
+ overAllWrapper: HTMLDivElement,
143
+ componentWrapper: HTMLDivElement,
144
+ value: number[] | string[] | boolean[],
145
+ floatLabelType: FloatLabelType,
146
+ placeholder: string): void {
147
+ overAllWrapper.classList.remove('e-input-focus');
148
+ let label: Element = componentWrapper.querySelector('.' + FLOATTEXT);
149
+ if (value && value.length <= 0 && floatLabelType === 'Auto' && !isNullOrUndefined(label)) {
150
+ if (label.classList.contains(LABELTOP)) {
151
+ removeClass([label], LABELTOP);
152
+ }
153
+ addClass([label], LABELBOTTOM);
154
+ }
155
+ }