@syncfusion/ej2-dropdowns 23.1.40-85814 → 23.1.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +260 -0
- package/CHANGELOG.md +2057 -2042
- package/{ReadMe.md → README.md} +217 -217
- package/dist/ej2-dropdowns.min.js +10 -0
- package/dist/ej2-dropdowns.umd.min.js +10 -1
- package/dist/ej2-dropdowns.umd.min.js.map +1 -1
- package/dist/es6/ej2-dropdowns.es2015.js +101 -60
- package/dist/es6/ej2-dropdowns.es2015.js.map +1 -1
- package/dist/es6/ej2-dropdowns.es5.js +243 -202
- package/dist/es6/ej2-dropdowns.es5.js.map +1 -1
- package/dist/global/ej2-dropdowns.min.js +10 -1
- package/dist/global/ej2-dropdowns.min.js.map +1 -1
- package/dist/global/index.d.ts +9 -0
- package/helpers/e2e/autocomplete.js +13 -13
- package/helpers/e2e/combobox.js +13 -13
- package/helpers/e2e/dropdownlist.js +13 -13
- package/helpers/e2e/index.js +3 -3
- package/helpers/e2e/listboxHelper.js +13 -13
- package/helpers/e2e/multiselect.js +13 -13
- package/license +2 -2
- package/package.json +79 -79
- package/src/auto-complete/auto-complete-model.d.ts +188 -188
- package/src/auto-complete/auto-complete.d.ts +12 -12
- package/src/auto-complete/auto-complete.js +21 -21
- package/src/combo-box/combo-box-model.d.ts +224 -224
- package/src/combo-box/combo-box.d.ts +27 -27
- package/src/combo-box/combo-box.js +29 -29
- package/src/common/virtual-scroll.js +46 -46
- package/src/drop-down-base/drop-down-base-model.d.ts +200 -200
- package/src/drop-down-base/drop-down-base.d.ts +16 -15
- package/src/drop-down-base/drop-down-base.js +25 -20
- package/src/drop-down-list/drop-down-list-model.d.ts +202 -202
- package/src/drop-down-list/drop-down-list.d.ts +7 -4
- package/src/drop-down-list/drop-down-list.js +53 -22
- package/src/drop-down-tree/drop-down-tree-model.d.ts +468 -468
- package/src/drop-down-tree/drop-down-tree.js +21 -21
- package/src/list-box/list-box-model.d.ts +193 -193
- package/src/list-box/list-box.d.ts +2 -2
- package/src/list-box/list-box.js +19 -19
- package/src/mention/mention-model.d.ts +261 -261
- package/src/mention/mention.js +19 -19
- package/src/multi-select/multi-select-model.d.ts +512 -512
- package/src/multi-select/multi-select.js +24 -19
- package/styles/auto-complete/_all.scss +1 -1
- package/styles/auto-complete/_bootstrap-dark-definition.scss +3 -3
- package/styles/auto-complete/_bootstrap-definition.scss +2 -2
- package/styles/auto-complete/_bootstrap4-definition.scss +11 -11
- package/styles/auto-complete/_bootstrap5-definition.scss +2 -2
- package/styles/auto-complete/_fabric-dark-definition.scss +2 -2
- package/styles/auto-complete/_fabric-definition.scss +2 -2
- package/styles/auto-complete/_fluent-definition.scss +2 -2
- package/styles/auto-complete/_fusionnew-definition.scss +2 -2
- package/styles/auto-complete/_highcontrast-definition.scss +2 -2
- package/styles/auto-complete/_highcontrast-light-definition.scss +2 -2
- package/styles/auto-complete/_material-dark-definition.scss +2 -2
- package/styles/auto-complete/_material-definition.scss +2 -2
- package/styles/auto-complete/_material3-definition.scss +2 -2
- package/styles/auto-complete/_tailwind-definition.scss +2 -2
- package/styles/auto-complete/material3-dark.scss +1 -1
- package/styles/auto-complete/material3.scss +1 -1
- package/styles/bootstrap-dark.css +1 -1
- package/styles/bootstrap.css +1 -1
- package/styles/bootstrap4.css +1 -1
- package/styles/bootstrap5-dark.css +1 -1
- package/styles/bootstrap5.css +1 -1
- package/styles/combo-box/_all.scss +1 -1
- package/styles/combo-box/_bootstrap-dark-definition.scss +2 -2
- package/styles/combo-box/_bootstrap-definition.scss +2 -2
- package/styles/combo-box/_bootstrap4-definition.scss +11 -11
- package/styles/combo-box/_bootstrap5-definition.scss +2 -2
- package/styles/combo-box/_fabric-dark-definition.scss +2 -2
- package/styles/combo-box/_fabric-definition.scss +2 -2
- package/styles/combo-box/_fluent-definition.scss +2 -2
- package/styles/combo-box/_fusionnew-definition.scss +2 -2
- package/styles/combo-box/_highcontrast-definition.scss +2 -2
- package/styles/combo-box/_highcontrast-light-definition.scss +3 -3
- package/styles/combo-box/_material-dark-definition.scss +2 -2
- package/styles/combo-box/_material-definition.scss +2 -2
- package/styles/combo-box/_material3-definition.scss +2 -2
- package/styles/combo-box/_tailwind-definition.scss +2 -2
- package/styles/combo-box/material3-dark.scss +1 -1
- package/styles/combo-box/material3.scss +1 -1
- package/styles/drop-down-base/_all.scss +2 -2
- package/styles/drop-down-base/_bootstrap-dark-definition.scss +83 -83
- package/styles/drop-down-base/_bootstrap-definition.scss +83 -83
- package/styles/drop-down-base/_bootstrap4-definition.scss +90 -90
- package/styles/drop-down-base/_bootstrap5-definition.scss +117 -117
- package/styles/drop-down-base/_definition.scss +23 -23
- package/styles/drop-down-base/_fabric-dark-definition.scss +86 -86
- package/styles/drop-down-base/_fabric-definition.scss +84 -84
- package/styles/drop-down-base/_fluent-definition.scss +121 -121
- package/styles/drop-down-base/_fusionnew-definition.scss +117 -117
- package/styles/drop-down-base/_highcontrast-definition.scss +105 -105
- package/styles/drop-down-base/_highcontrast-light-definition.scss +105 -105
- package/styles/drop-down-base/_layout.scss +195 -195
- package/styles/drop-down-base/_material-dark-definition.scss +86 -86
- package/styles/drop-down-base/_material-definition.scss +85 -85
- package/styles/drop-down-base/_material3-definition.scss +87 -87
- package/styles/drop-down-base/_tailwind-definition.scss +129 -129
- package/styles/drop-down-base/_theme.scss +391 -391
- package/styles/drop-down-base/material3-dark.scss +1 -1
- package/styles/drop-down-base/material3.scss +1 -1
- package/styles/drop-down-list/_all.scss +3 -3
- package/styles/drop-down-list/_bootstrap-dark-definition.scss +157 -157
- package/styles/drop-down-list/_bootstrap-definition.scss +156 -156
- package/styles/drop-down-list/_bootstrap4-definition.scss +202 -202
- package/styles/drop-down-list/_bootstrap5-definition.scss +201 -201
- package/styles/drop-down-list/_fabric-dark-definition.scss +128 -128
- package/styles/drop-down-list/_fabric-definition.scss +124 -124
- package/styles/drop-down-list/_fluent-definition.scss +185 -185
- package/styles/drop-down-list/_fusionnew-definition.scss +201 -201
- package/styles/drop-down-list/_highcontrast-definition.scss +142 -142
- package/styles/drop-down-list/_highcontrast-light-definition.scss +144 -144
- package/styles/drop-down-list/_layout.scss +310 -310
- package/styles/drop-down-list/_material-dark-definition.scss +143 -143
- package/styles/drop-down-list/_material-definition.scss +167 -167
- package/styles/drop-down-list/_material3-definition.scss +180 -180
- package/styles/drop-down-list/_tailwind-definition.scss +134 -134
- package/styles/drop-down-list/_theme.scss +10 -10
- package/styles/drop-down-list/icons/_bootstrap-dark.scss +14 -14
- package/styles/drop-down-list/icons/_bootstrap.scss +14 -14
- package/styles/drop-down-list/icons/_bootstrap4.scss +14 -14
- package/styles/drop-down-list/icons/_bootstrap5.scss +14 -14
- package/styles/drop-down-list/icons/_fabric-dark.scss +14 -14
- package/styles/drop-down-list/icons/_fabric.scss +14 -14
- package/styles/drop-down-list/icons/_fluent.scss +14 -14
- package/styles/drop-down-list/icons/_fusionnew.scss +14 -14
- package/styles/drop-down-list/icons/_highcontrast-light.scss +14 -14
- package/styles/drop-down-list/icons/_highcontrast.scss +14 -14
- package/styles/drop-down-list/icons/_material-dark.scss +14 -14
- package/styles/drop-down-list/icons/_material.scss +14 -14
- package/styles/drop-down-list/icons/_material3.scss +14 -14
- package/styles/drop-down-list/icons/_tailwind.scss +14 -14
- package/styles/drop-down-list/material3-dark.scss +1 -1
- package/styles/drop-down-list/material3.scss +1 -1
- package/styles/drop-down-tree/_all.scss +2 -2
- package/styles/drop-down-tree/_bootstrap-dark-definition.scss +71 -71
- package/styles/drop-down-tree/_bootstrap-definition.scss +70 -70
- package/styles/drop-down-tree/_bootstrap4-definition.scss +71 -71
- package/styles/drop-down-tree/_bootstrap5-definition.scss +59 -59
- package/styles/drop-down-tree/_fabric-dark-definition.scss +71 -71
- package/styles/drop-down-tree/_fabric-definition.scss +71 -71
- package/styles/drop-down-tree/_fluent-definition.scss +65 -65
- package/styles/drop-down-tree/_fusionnew-definition.scss +59 -59
- package/styles/drop-down-tree/_highcontrast-definition.scss +71 -71
- package/styles/drop-down-tree/_highcontrast-light-definition.scss +71 -71
- package/styles/drop-down-tree/_layout.scss +1412 -1418
- package/styles/drop-down-tree/_material-dark-definition.scss +72 -72
- package/styles/drop-down-tree/_material-definition.scss +72 -72
- package/styles/drop-down-tree/_material3-definition.scss +76 -76
- package/styles/drop-down-tree/_tailwind-definition.scss +61 -61
- package/styles/drop-down-tree/_theme.scss +132 -132
- package/styles/drop-down-tree/fluent-dark.css +0 -2
- package/styles/drop-down-tree/fluent.css +0 -2
- package/styles/drop-down-tree/icons/_bootstrap-dark.scss +11 -11
- package/styles/drop-down-tree/icons/_bootstrap.scss +11 -11
- package/styles/drop-down-tree/icons/_bootstrap4.scss +11 -11
- package/styles/drop-down-tree/icons/_bootstrap5.scss +11 -11
- package/styles/drop-down-tree/icons/_fabric-dark.scss +11 -11
- package/styles/drop-down-tree/icons/_fabric.scss +11 -11
- package/styles/drop-down-tree/icons/_fluent.scss +11 -11
- package/styles/drop-down-tree/icons/_fusionnew.scss +11 -11
- package/styles/drop-down-tree/icons/_highcontrast-light.scss +11 -11
- package/styles/drop-down-tree/icons/_highcontrast.scss +11 -11
- package/styles/drop-down-tree/icons/_material-dark.scss +11 -11
- package/styles/drop-down-tree/icons/_material.scss +11 -11
- package/styles/drop-down-tree/icons/_material3.scss +11 -11
- package/styles/drop-down-tree/icons/_tailwind-dark.scss +11 -11
- package/styles/drop-down-tree/icons/_tailwind.scss +11 -11
- package/styles/drop-down-tree/material3-dark.scss +1 -1
- package/styles/drop-down-tree/material3.scss +1 -1
- package/styles/fabric-dark.css +1 -1
- package/styles/fabric.css +1 -1
- package/styles/fluent-dark.css +1 -3
- package/styles/fluent.css +1 -3
- package/styles/highcontrast-light.css +1 -1
- package/styles/highcontrast.css +1 -1
- package/styles/list-box/_all.scss +2 -2
- package/styles/list-box/_bootstrap-dark-definition.scss +126 -126
- package/styles/list-box/_bootstrap-definition.scss +119 -119
- package/styles/list-box/_bootstrap4-definition.scss +124 -124
- package/styles/list-box/_bootstrap5-definition.scss +120 -120
- package/styles/list-box/_fabric-dark-definition.scss +126 -126
- package/styles/list-box/_fabric-definition.scss +119 -119
- package/styles/list-box/_fluent-definition.scss +120 -120
- package/styles/list-box/_fusionnew-definition.scss +111 -111
- package/styles/list-box/_highcontrast-definition.scss +119 -119
- package/styles/list-box/_highcontrast-light-definition.scss +126 -126
- package/styles/list-box/_layout.scss +542 -542
- package/styles/list-box/_material-dark-definition.scss +126 -126
- package/styles/list-box/_material-definition.scss +119 -119
- package/styles/list-box/_material3-definition.scss +119 -119
- package/styles/list-box/_tailwind-definition.scss +119 -119
- package/styles/list-box/_theme.scss +382 -382
- package/styles/list-box/bootstrap-dark.css +1 -1
- package/styles/list-box/bootstrap.css +1 -1
- package/styles/list-box/bootstrap4.css +1 -1
- package/styles/list-box/bootstrap5-dark.css +1 -1
- package/styles/list-box/bootstrap5.css +1 -1
- package/styles/list-box/fabric-dark.css +1 -1
- package/styles/list-box/fabric.css +1 -1
- package/styles/list-box/fluent-dark.css +1 -1
- package/styles/list-box/fluent.css +1 -1
- package/styles/list-box/highcontrast-light.css +1 -1
- package/styles/list-box/highcontrast.css +1 -1
- package/styles/list-box/icons/_bootstrap-dark.scss +25 -25
- package/styles/list-box/icons/_bootstrap.scss +25 -25
- package/styles/list-box/icons/_bootstrap4.scss +25 -25
- package/styles/list-box/icons/_bootstrap5.scss +25 -25
- package/styles/list-box/icons/_fabric-dark.scss +25 -25
- package/styles/list-box/icons/_fabric.scss +25 -25
- package/styles/list-box/icons/_fluent.scss +25 -25
- package/styles/list-box/icons/_fusionnew.scss +25 -25
- package/styles/list-box/icons/_highcontrast-light.scss +25 -25
- package/styles/list-box/icons/_highcontrast.scss +25 -25
- package/styles/list-box/icons/_material-dark.scss +25 -25
- package/styles/list-box/icons/_material.scss +25 -25
- package/styles/list-box/icons/_material3.scss +25 -25
- package/styles/list-box/icons/_tailwind-dark.scss +25 -25
- package/styles/list-box/icons/_tailwind.scss +25 -25
- package/styles/list-box/material-dark.css +1 -1
- package/styles/list-box/material.css +1 -1
- package/styles/list-box/material3-dark.css +1 -1
- package/styles/list-box/material3-dark.scss +1 -1
- package/styles/list-box/material3.css +1 -1
- package/styles/list-box/material3.scss +1 -1
- package/styles/list-box/tailwind-dark.css +1 -1
- package/styles/list-box/tailwind.css +1 -1
- package/styles/material-dark.css +1 -1
- package/styles/material.css +1 -1
- package/styles/material3-dark.css +1 -1
- package/styles/material3-dark.scss +1 -1
- package/styles/material3.css +1 -1
- package/styles/material3.scss +1 -1
- package/styles/mention/_all.scss +1 -1
- package/styles/mention/_bootstrap-dark-definition.scss +3 -3
- package/styles/mention/_bootstrap-definition.scss +3 -3
- package/styles/mention/_bootstrap4-definition.scss +3 -3
- package/styles/mention/_bootstrap5-definition.scss +1 -1
- package/styles/mention/_fabric-dark-definition.scss +2 -2
- package/styles/mention/_fabric-definition.scss +3 -3
- package/styles/mention/_fluent-definition.scss +1 -1
- package/styles/mention/_fusionnew-definition.scss +1 -1
- package/styles/mention/_highcontrast-definition.scss +3 -3
- package/styles/mention/_highcontrast-light-definition.scss +3 -3
- package/styles/mention/_layout.scss +6 -6
- package/styles/mention/_material-dark-definition.scss +3 -3
- package/styles/mention/_material-definition.scss +3 -3
- package/styles/mention/_material3-definition.scss +1 -1
- package/styles/mention/_tailwind-definition.scss +1 -1
- package/styles/mention/material3-dark.scss +1 -1
- package/styles/mention/material3.scss +1 -1
- package/styles/multi-select/_all.scss +2 -2
- package/styles/multi-select/_bootstrap-dark-definition.scss +198 -198
- package/styles/multi-select/_bootstrap-definition.scss +192 -192
- package/styles/multi-select/_bootstrap4-definition.scss +278 -278
- package/styles/multi-select/_bootstrap5-definition.scss +229 -229
- package/styles/multi-select/_fabric-dark-definition.scss +187 -187
- package/styles/multi-select/_fabric-definition.scss +183 -183
- package/styles/multi-select/_fluent-definition.scss +240 -240
- package/styles/multi-select/_fusionnew-definition.scss +227 -227
- package/styles/multi-select/_highcontrast-definition.scss +298 -298
- package/styles/multi-select/_highcontrast-light-definition.scss +297 -297
- package/styles/multi-select/_layout.scss +2199 -2199
- package/styles/multi-select/_material-dark-definition.scss +230 -230
- package/styles/multi-select/_material-definition.scss +223 -223
- package/styles/multi-select/_material3-definition.scss +246 -246
- package/styles/multi-select/_tailwind-definition.scss +234 -234
- package/styles/multi-select/_theme.scss +586 -586
- package/styles/multi-select/icons/_bootstrap-dark.scss +26 -26
- package/styles/multi-select/icons/_bootstrap.scss +26 -26
- package/styles/multi-select/icons/_bootstrap4.scss +37 -37
- package/styles/multi-select/icons/_bootstrap5.scss +26 -26
- package/styles/multi-select/icons/_fabric-dark.scss +26 -26
- package/styles/multi-select/icons/_fabric.scss +26 -26
- package/styles/multi-select/icons/_fluent.scss +55 -55
- package/styles/multi-select/icons/_fusionnew.scss +26 -26
- package/styles/multi-select/icons/_highcontrast-light.scss +26 -26
- package/styles/multi-select/icons/_highcontrast.scss +26 -26
- package/styles/multi-select/icons/_material-dark.scss +693 -693
- package/styles/multi-select/icons/_material.scss +693 -693
- package/styles/multi-select/icons/_material3.scss +692 -692
- package/styles/multi-select/icons/_tailwind.scss +26 -26
- package/styles/multi-select/material3-dark.scss +1 -1
- package/styles/multi-select/material3.scss +1 -1
- package/styles/tailwind-dark.css +1 -1
- package/styles/tailwind.css +1 -1
- package/tslint.json +111 -0
- package/dist/ts/auto-complete/auto-complete.ts +0 -615
- package/dist/ts/combo-box/combo-box.ts +0 -1028
- package/dist/ts/common/highlight-search.ts +0 -57
- package/dist/ts/common/incremental-search.ts +0 -131
- package/dist/ts/common/interface.ts +0 -72
- package/dist/ts/common/virtual-scroll.ts +0 -354
- package/dist/ts/drop-down-base/drop-down-base.ts +0 -1838
- package/dist/ts/drop-down-list/drop-down-list.ts +0 -3889
- package/dist/ts/drop-down-tree/drop-down-tree.ts +0 -3750
- package/dist/ts/list-box/list-box.ts +0 -2736
- package/dist/ts/mention/mention.ts +0 -1828
- package/dist/ts/multi-select/checkbox-selection.ts +0 -547
- package/dist/ts/multi-select/float-label.ts +0 -176
- package/dist/ts/multi-select/interface.ts +0 -70
- package/dist/ts/multi-select/multi-select.ts +0 -4874
|
@@ -1,1828 +0,0 @@
|
|
|
1
|
-
import { KeyboardEvents, compile, Property, EventHandler, Animation, AnimationModel, KeyboardEventArgs, formatUnit, append, attributes } from '@syncfusion/ej2-base';
|
|
2
|
-
import { isNullOrUndefined, detach, Event, EmitType, Complex, addClass, removeClass, closest, isUndefined, getValue, NotifyPropertyChanges, Browser } from '@syncfusion/ej2-base';
|
|
3
|
-
import { FieldSettingsModel } from '../drop-down-base/drop-down-base-model';
|
|
4
|
-
import { FieldSettings, FilteringEventArgs, FilterType } from '../drop-down-base/drop-down-base';
|
|
5
|
-
import { DropDownBase, PopupEventArgs, SelectEventArgs, BeforeOpenEventArgs, dropDownBaseClasses } from '../drop-down-base/drop-down-base';
|
|
6
|
-
import { DataManager, Query } from '@syncfusion/ej2-data';
|
|
7
|
-
import { MentionModel } from '../mention/mention-model';
|
|
8
|
-
import { SortOrder } from '@syncfusion/ej2-lists';
|
|
9
|
-
import { Popup, isCollide, createSpinner, showSpinner, hideSpinner, getZindexPartial } from '@syncfusion/ej2-popups';
|
|
10
|
-
import { highlightSearch, revertHighlightSearch } from '../common/highlight-search';
|
|
11
|
-
|
|
12
|
-
export interface MentionChangeEventArgs extends SelectEventArgs {
|
|
13
|
-
/**
|
|
14
|
-
* Specifies the selected value.
|
|
15
|
-
*
|
|
16
|
-
* @isGenericType true
|
|
17
|
-
*/
|
|
18
|
-
value: number | string | boolean
|
|
19
|
-
/**
|
|
20
|
-
* Specifies the element of previous selected list item.
|
|
21
|
-
*/
|
|
22
|
-
previousItem: HTMLLIElement
|
|
23
|
-
/**
|
|
24
|
-
* Specifies the previously selected item as a JSON Object from the data source.
|
|
25
|
-
*
|
|
26
|
-
*/
|
|
27
|
-
previousItemData: FieldSettingsModel
|
|
28
|
-
/**
|
|
29
|
-
* Specifies the component root element.
|
|
30
|
-
*/
|
|
31
|
-
element: HTMLElement
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* The Mention component is used to list someone or something based on user input in textarea, input,
|
|
36
|
-
* or any other editable element from which the user can select.
|
|
37
|
-
*/
|
|
38
|
-
@NotifyPropertyChanges
|
|
39
|
-
export class Mention extends DropDownBase {
|
|
40
|
-
private initRemoteRender: boolean;
|
|
41
|
-
private inputElement: HTMLInputElement | HTMLTextAreaElement | HTMLElement;
|
|
42
|
-
private popupObj: Popup;
|
|
43
|
-
private isPopupOpen: boolean;
|
|
44
|
-
private isSelected: boolean;
|
|
45
|
-
private selectedLI: HTMLLIElement;
|
|
46
|
-
private previousSelectedLI: HTMLElement;
|
|
47
|
-
private previousItemData: { [key: string]: Object } | string | number | boolean;
|
|
48
|
-
private activeIndex: number;
|
|
49
|
-
private keyConfigure: { [key: string]: string };
|
|
50
|
-
private isFiltered: boolean;
|
|
51
|
-
private beforePopupOpen: boolean;
|
|
52
|
-
private listHeight: string;
|
|
53
|
-
private isListResetted: boolean;
|
|
54
|
-
private range: Range;
|
|
55
|
-
private displayTempElement: HTMLElement;
|
|
56
|
-
private isCollided: boolean;
|
|
57
|
-
private spinnerElement: HTMLElement;
|
|
58
|
-
private spinnerTemplateElement: HTMLElement;
|
|
59
|
-
private lineBreak: boolean;
|
|
60
|
-
private selectedElementID : string;
|
|
61
|
-
private isSelectCancel: boolean;
|
|
62
|
-
private isTyped: boolean;
|
|
63
|
-
private didPopupOpenByTypingInitialChar: boolean;
|
|
64
|
-
private isUpDownKey: boolean;
|
|
65
|
-
|
|
66
|
-
// Mention Options
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Defines class/multiple classes separated by a space for the mention component.
|
|
70
|
-
*
|
|
71
|
-
* @default null
|
|
72
|
-
*/
|
|
73
|
-
@Property(null)
|
|
74
|
-
public cssClass: string;
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Specifies the symbol or single character which triggers the search action in the mention component.
|
|
78
|
-
*
|
|
79
|
-
* @default '@'
|
|
80
|
-
* @aspType char
|
|
81
|
-
*/
|
|
82
|
-
@Property('@')
|
|
83
|
-
public mentionChar: string;
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Specifies whether to show the configured mentionChar with the text.
|
|
87
|
-
*
|
|
88
|
-
* @default false
|
|
89
|
-
*/
|
|
90
|
-
@Property(false)
|
|
91
|
-
public showMentionChar: boolean;
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Defines whether to allow the space in the middle of mention while searching.
|
|
95
|
-
* When disabled, the space ends the mention component search.
|
|
96
|
-
*
|
|
97
|
-
* @default false
|
|
98
|
-
*/
|
|
99
|
-
@Property(false)
|
|
100
|
-
public allowSpaces: boolean;
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Specifies the custom suffix to append along with the mention component selected item while inserting.
|
|
104
|
-
* You can append space or new line character as suffix.
|
|
105
|
-
*
|
|
106
|
-
* @default null
|
|
107
|
-
*/
|
|
108
|
-
@Property(null)
|
|
109
|
-
public suffixText: string;
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Specifies the number of items in the suggestion list.
|
|
113
|
-
*
|
|
114
|
-
* @default 25
|
|
115
|
-
* @aspType int
|
|
116
|
-
*/
|
|
117
|
-
@Property(25)
|
|
118
|
-
public suggestionCount: number;
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Specifies the minimum length of user input to initiate the search action.
|
|
122
|
-
* The default value is zero, where suggestion the list opened as soon as the user inputs the mention character.
|
|
123
|
-
*
|
|
124
|
-
* @default 0
|
|
125
|
-
* @aspType int
|
|
126
|
-
*/
|
|
127
|
-
@Property(0)
|
|
128
|
-
public minLength: number;
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Specifies the order to sort the data source. The possible sort orders are,
|
|
132
|
-
* * `None` - The data source is not sorted.
|
|
133
|
-
* * `Ascending` - The data source is sorted in ascending order.
|
|
134
|
-
* * `Descending` - The data source is sorted in descending order.
|
|
135
|
-
*
|
|
136
|
-
* @default 'None'
|
|
137
|
-
*/
|
|
138
|
-
@Property('None')
|
|
139
|
-
public sortOrder: SortOrder;
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Specifies whether the searches are case sensitive to find suggestions.
|
|
143
|
-
*
|
|
144
|
-
* @default true
|
|
145
|
-
*/
|
|
146
|
-
@Property(true)
|
|
147
|
-
public ignoreCase: boolean;
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Specifies whether to highlight the searched characters on suggestion list items.
|
|
151
|
-
*
|
|
152
|
-
* @default false
|
|
153
|
-
*/
|
|
154
|
-
@Property(false)
|
|
155
|
-
public highlight: boolean;
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Overrides the global culture and localization value for this component. Default global culture is ‘en-US’.
|
|
159
|
-
*
|
|
160
|
-
* @default 'en-US'
|
|
161
|
-
*/
|
|
162
|
-
@Property()
|
|
163
|
-
public locale: string;
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Specifies the width of the popup in pixels/number/percentage. The number value is considered as pixels.
|
|
167
|
-
*
|
|
168
|
-
* @default 'auto'
|
|
169
|
-
* @aspType string
|
|
170
|
-
*/
|
|
171
|
-
@Property('auto')
|
|
172
|
-
public popupWidth: string | number;
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Specifies the height of the popup in pixels/number/percentage. The number value is considered as pixels.
|
|
176
|
-
*
|
|
177
|
-
* @default '300px'
|
|
178
|
-
* @aspType string
|
|
179
|
-
*/
|
|
180
|
-
@Property('300px')
|
|
181
|
-
public popupHeight: string | number;
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Specifies the template for the selected value from the suggestion list.
|
|
185
|
-
*
|
|
186
|
-
* @default null
|
|
187
|
-
* @aspType string
|
|
188
|
-
*/
|
|
189
|
-
@Property(null)
|
|
190
|
-
public displayTemplate: string | Function;
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Specifies the template for the suggestion list.
|
|
194
|
-
*
|
|
195
|
-
* @default null
|
|
196
|
-
*/
|
|
197
|
-
@Property(null)
|
|
198
|
-
public itemTemplate: string;
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Specifies the template for no matched item which is displayed when there are no items to display in the suggestion list.
|
|
202
|
-
*
|
|
203
|
-
* @default 'No records found'
|
|
204
|
-
*/
|
|
205
|
-
@Property('No records found')
|
|
206
|
-
public noRecordsTemplate: string;
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Specifies the template for showing until data is loaded in the popup.
|
|
210
|
-
*
|
|
211
|
-
* @default null
|
|
212
|
-
* @aspType string
|
|
213
|
-
*/
|
|
214
|
-
@Property(null)
|
|
215
|
-
public spinnerTemplate: string | Function;
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Specifies the target selector where the mention component needs to be displayed.
|
|
219
|
-
* The mention component listens to the target's user input and displays suggestions as soon as the user inputs the mention character.
|
|
220
|
-
*
|
|
221
|
-
*/
|
|
222
|
-
@Property()
|
|
223
|
-
public target: HTMLElement | string;
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Accepts the list items either through local or remote service and binds it to the component.
|
|
227
|
-
* It can be an array of JSON Objects or an instance of `DataManager`.
|
|
228
|
-
*
|
|
229
|
-
* @default []
|
|
230
|
-
*/
|
|
231
|
-
@Property([])
|
|
232
|
-
public dataSource: { [key: string]: Object }[] | DataManager | string[] | number[] | boolean[];
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Specifies the external query, which can be customized and filtered against the data source.
|
|
236
|
-
*
|
|
237
|
-
* @default null
|
|
238
|
-
*/
|
|
239
|
-
@Property(null)
|
|
240
|
-
public query: Query;
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Determines on which filter type, the component needs to be considered on search action.
|
|
244
|
-
* and its supported data types are
|
|
245
|
-
*
|
|
246
|
-
* <table>
|
|
247
|
-
* <tr>
|
|
248
|
-
* <td colSpan=1 rowSpan=1>
|
|
249
|
-
* FilterType<br/></td><td colSpan=1 rowSpan=1>
|
|
250
|
-
* Description<br/></td><td colSpan=1 rowSpan=1>
|
|
251
|
-
* Supported Types<br/></td></tr>
|
|
252
|
-
* <tr>
|
|
253
|
-
* <td colSpan=1 rowSpan=1>
|
|
254
|
-
* StartsWith<br/></td><td colSpan=1 rowSpan=1>
|
|
255
|
-
* Checks whether a value begins with the specified value.<br/></td><td colSpan=1 rowSpan=1>
|
|
256
|
-
* String<br/></td></tr>
|
|
257
|
-
* <tr>
|
|
258
|
-
* <td colSpan=1 rowSpan=1>
|
|
259
|
-
* EndsWith<br/></td><td colSpan=1 rowSpan=1>
|
|
260
|
-
* Checks whether a value ends with a specified value.<br/><br/></td><td colSpan=1 rowSpan=1>
|
|
261
|
-
* <br/>String<br/></td></tr>
|
|
262
|
-
* <tr>
|
|
263
|
-
* <td colSpan=1 rowSpan=1>
|
|
264
|
-
* Contains<br/></td><td colSpan=1 rowSpan=1>
|
|
265
|
-
* Checks whether a value contains with a specified value.<br/><br/></td><td colSpan=1 rowSpan=1>
|
|
266
|
-
* <br/>String<br/></td></tr>
|
|
267
|
-
* </table>
|
|
268
|
-
*
|
|
269
|
-
* The default value set to `Contains`, all the suggestion items which contain typed characters to listed in the suggestion popup.
|
|
270
|
-
*
|
|
271
|
-
* @default 'Contains'
|
|
272
|
-
*/
|
|
273
|
-
@Property('Contains')
|
|
274
|
-
public filterType: FilterType;
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Defines the fields of the Mention to map with the data source and binds the data to the component.
|
|
278
|
-
* * text - Specifies the text that maps the text filed from the data source for each list item.
|
|
279
|
-
* * value - Specifies the value that maps the value filed from the data source for each list item.
|
|
280
|
-
* * iconCss - Specifies the iconCss that map the icon class filed from the data source for each list item.
|
|
281
|
-
* * groupBy - Specifies the groupBy that groups the list items with its related items by mapping groupBy field.
|
|
282
|
-
*
|
|
283
|
-
* @default
|
|
284
|
-
* {
|
|
285
|
-
* text: null, value: null, iconCss: null, groupBy: null
|
|
286
|
-
* }
|
|
287
|
-
*/
|
|
288
|
-
@Complex<FieldSettingsModel>({ text: null, value: null, iconCss: null, groupBy: null }, FieldSettings)
|
|
289
|
-
public fields: FieldSettingsModel;
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* Triggers before fetching data from the remote server.
|
|
293
|
-
*
|
|
294
|
-
* @event actionBegin
|
|
295
|
-
*/
|
|
296
|
-
@Event()
|
|
297
|
-
public actionBegin: EmitType<Object>;
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Triggers after data is fetched successfully from the remote server.
|
|
301
|
-
*
|
|
302
|
-
* @event actionComplete
|
|
303
|
-
*/
|
|
304
|
-
@Event()
|
|
305
|
-
public actionComplete: EmitType<Object>;
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* Triggers when the data fetch request from the remote server fails.
|
|
309
|
-
*
|
|
310
|
-
* @event actionFailure
|
|
311
|
-
*/
|
|
312
|
-
@Event()
|
|
313
|
-
public actionFailure: EmitType<Object>;
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Triggers when an item in a popup is selected and updated in an editor.
|
|
317
|
-
*
|
|
318
|
-
* @event change
|
|
319
|
-
*/
|
|
320
|
-
@Event()
|
|
321
|
-
public change: EmitType<MentionChangeEventArgs>;
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Triggers before the popup is opened.
|
|
325
|
-
*
|
|
326
|
-
* @event beforeOpen
|
|
327
|
-
*/
|
|
328
|
-
@Event()
|
|
329
|
-
public beforeOpen: EmitType<PopupEventArgs>;
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* Triggers after the popup opens.
|
|
333
|
-
*
|
|
334
|
-
* @event opened
|
|
335
|
-
*/
|
|
336
|
-
@Event()
|
|
337
|
-
public opened: EmitType<PopupEventArgs>;
|
|
338
|
-
|
|
339
|
-
/**
|
|
340
|
-
* Triggers after the popup is closed.
|
|
341
|
-
*
|
|
342
|
-
* @event closed
|
|
343
|
-
*/
|
|
344
|
-
@Event()
|
|
345
|
-
public closed: EmitType<PopupEventArgs>;
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* Triggers when an item in the popup is selected by the user either with the mouse/tap or with keyboard navigation.
|
|
349
|
-
*
|
|
350
|
-
* @event select
|
|
351
|
-
*/
|
|
352
|
-
@Event()
|
|
353
|
-
public select: EmitType<SelectEventArgs>;
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
* Triggers on typing a character in the component.
|
|
357
|
-
*
|
|
358
|
-
* @event filtering
|
|
359
|
-
*/
|
|
360
|
-
@Event()
|
|
361
|
-
public filtering: EmitType<FilteringEventArgs>;
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Triggers when the component is created.
|
|
365
|
-
*
|
|
366
|
-
* @event created
|
|
367
|
-
*/
|
|
368
|
-
@Event()
|
|
369
|
-
public created: EmitType<Object>;
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* Triggers when the component is destroyed.
|
|
373
|
-
*
|
|
374
|
-
* @event destroyed
|
|
375
|
-
*/
|
|
376
|
-
@Event()
|
|
377
|
-
public destroyed: EmitType<Object>;
|
|
378
|
-
|
|
379
|
-
/**
|
|
380
|
-
* * Constructor for creating the widget
|
|
381
|
-
*
|
|
382
|
-
* @param {MentionModel} options - Specifies the MentionComponent model.
|
|
383
|
-
* @param {string | HTMLElement} element - Specifies the element to render as component.
|
|
384
|
-
* @private
|
|
385
|
-
*/
|
|
386
|
-
public constructor(options?: MentionModel, element?: string | HTMLElement) {
|
|
387
|
-
super(options, element);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
/**
|
|
391
|
-
* When property value changes happened, then onPropertyChanged method will execute the respective changes in this component.
|
|
392
|
-
*
|
|
393
|
-
* @param {MentionModel} newProp - Returns the dynamic property value of the component.
|
|
394
|
-
* @param {MentionModel} oldProp - Returns the previous property value of the component.
|
|
395
|
-
* @private
|
|
396
|
-
* @returns {void}
|
|
397
|
-
*/
|
|
398
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
399
|
-
public onPropertyChanged(newProp: MentionModel, oldProp: MentionModel): void {
|
|
400
|
-
for (const prop of Object.keys(newProp)) {
|
|
401
|
-
switch (prop) {
|
|
402
|
-
case 'minLength':
|
|
403
|
-
this.minLength = newProp.minLength;
|
|
404
|
-
break;
|
|
405
|
-
case 'suffixText':
|
|
406
|
-
this.suffixText = newProp.suffixText;
|
|
407
|
-
break;
|
|
408
|
-
case 'allowSpaces':
|
|
409
|
-
this.allowSpaces = newProp.allowSpaces;
|
|
410
|
-
break;
|
|
411
|
-
case 'mentionChar':
|
|
412
|
-
this.mentionChar = newProp.mentionChar;
|
|
413
|
-
break;
|
|
414
|
-
case 'showMentionChar':
|
|
415
|
-
this.showMentionChar = newProp.showMentionChar;
|
|
416
|
-
break;
|
|
417
|
-
case 'cssClass': this.updateCssClass(newProp.cssClass, oldProp.cssClass); break;
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
private updateCssClass(newClass: string, oldClass: string): void {
|
|
423
|
-
if (!isNullOrUndefined(oldClass)) {
|
|
424
|
-
oldClass = (oldClass.replace(/\s+/g, ' ')).trim();
|
|
425
|
-
}
|
|
426
|
-
if (!isNullOrUndefined(newClass)) {
|
|
427
|
-
newClass = (newClass.replace(/\s+/g, ' ')).trim();
|
|
428
|
-
}
|
|
429
|
-
this.setCssClass(newClass, [this.inputElement], oldClass);
|
|
430
|
-
if (this.popupObj) {
|
|
431
|
-
this.setCssClass(newClass, [this.popupObj.element], oldClass);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
private setCssClass(cssClass: string, elements: Element[] | NodeList, oldClass?: string): void {
|
|
436
|
-
if (!isNullOrUndefined(oldClass) && oldClass !== '') {
|
|
437
|
-
removeClass(elements, oldClass.split(' '));
|
|
438
|
-
}
|
|
439
|
-
if (!isNullOrUndefined(cssClass) && cssClass !== '') {
|
|
440
|
-
addClass(elements, cssClass.split(' '));
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
private initializeData(): void {
|
|
445
|
-
this.isSelected = false;
|
|
446
|
-
this.isFiltered = false;
|
|
447
|
-
this.beforePopupOpen = false;
|
|
448
|
-
this.initRemoteRender = false;
|
|
449
|
-
this.isListResetted = false;
|
|
450
|
-
this.isPopupOpen = false;
|
|
451
|
-
this.isCollided = false;
|
|
452
|
-
this.lineBreak = false;
|
|
453
|
-
this.keyConfigure = {
|
|
454
|
-
tab: 'tab',
|
|
455
|
-
enter: '13',
|
|
456
|
-
escape: '27',
|
|
457
|
-
end: '35',
|
|
458
|
-
home: '36',
|
|
459
|
-
down: '40',
|
|
460
|
-
up: '38',
|
|
461
|
-
pageUp: '33',
|
|
462
|
-
pageDown: '34',
|
|
463
|
-
open: 'alt+40',
|
|
464
|
-
close: 'shift+tab',
|
|
465
|
-
hide: 'alt+38',
|
|
466
|
-
space: '32'
|
|
467
|
-
};
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
/**
|
|
471
|
-
* Execute before render the list items
|
|
472
|
-
*
|
|
473
|
-
* @private
|
|
474
|
-
* @returns {void}
|
|
475
|
-
*/
|
|
476
|
-
protected preRender(): void {
|
|
477
|
-
this.initializeData();
|
|
478
|
-
super.preRender();
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
/**
|
|
482
|
-
* To Initialize the control rendering
|
|
483
|
-
*
|
|
484
|
-
* @private
|
|
485
|
-
* @returns {void}
|
|
486
|
-
*/
|
|
487
|
-
public render(): void {
|
|
488
|
-
const isSelector = typeof this.target === 'string';
|
|
489
|
-
this.inputElement = !isNullOrUndefined(this.target) ?
|
|
490
|
-
this.checkAndUpdateInternalComponent(isSelector
|
|
491
|
-
? <HTMLElement>document.querySelector(<string>this.target)
|
|
492
|
-
: <HTMLElement>this.target) : this.element;
|
|
493
|
-
if (this.isContentEditable(this.inputElement)) {
|
|
494
|
-
this.inputElement.setAttribute('contenteditable', 'true');
|
|
495
|
-
addClass([this.inputElement], ['e-mention']);
|
|
496
|
-
if (isNullOrUndefined(this.target)) {
|
|
497
|
-
addClass([this.inputElement], ['e-editable-element']);
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
this.inputElement.setAttribute('role', 'textbox');
|
|
501
|
-
this.queryString = this.elementValue();
|
|
502
|
-
this.wireEvent();
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
private wireEvent(): void {
|
|
506
|
-
EventHandler.add(this.inputElement, 'keyup', this.onKeyUp, this);
|
|
507
|
-
this.bindCommonEvent();
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
private unWireEvent(): void {
|
|
511
|
-
EventHandler.remove(this.inputElement, 'keyup', this.onKeyUp);
|
|
512
|
-
this.unBindCommonEvent();
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
private bindCommonEvent(): void {
|
|
516
|
-
if (!Browser.isDevice) {
|
|
517
|
-
this.keyboardModule = new KeyboardEvents(
|
|
518
|
-
this.inputElement, {
|
|
519
|
-
keyAction: this.keyActionHandler.bind(this), keyConfigs: this.keyConfigure, eventName: 'keydown'
|
|
520
|
-
});
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
/**
|
|
525
|
-
* Hides the spinner loader.
|
|
526
|
-
*
|
|
527
|
-
* @private
|
|
528
|
-
* @returns {void}
|
|
529
|
-
*/
|
|
530
|
-
public hideSpinner(): void {
|
|
531
|
-
this.hideWaitingSpinner();
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
private hideWaitingSpinner(): void {
|
|
535
|
-
if (!isNullOrUndefined(this.spinnerElement)) {
|
|
536
|
-
hideSpinner(this.spinnerElement);
|
|
537
|
-
}
|
|
538
|
-
if (!isNullOrUndefined(this.spinnerTemplate) && !isNullOrUndefined(this.spinnerTemplateElement)) {
|
|
539
|
-
detach(this.spinnerTemplateElement);
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
private checkAndUpdateInternalComponent(targetElement: HTMLElement): HTMLElement {
|
|
544
|
-
if (!(this as any).isVue && targetElement.classList.contains('e-richtexteditor')) {
|
|
545
|
-
return targetElement.querySelector('.e-content') as HTMLElement;
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
if ((this as any).isVue && targetElement.nodeName === 'TEXTAREA' && targetElement.classList.contains('e-rte-hidden')) {
|
|
549
|
-
const parentElement = targetElement.parentElement;
|
|
550
|
-
if (parentElement && parentElement.classList.contains('e-richtexteditor')) {
|
|
551
|
-
return parentElement.querySelector('.e-content') as HTMLElement;
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
return targetElement;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
/**
|
|
559
|
-
* Shows the spinner loader.
|
|
560
|
-
*
|
|
561
|
-
* @returns {void}
|
|
562
|
-
*/
|
|
563
|
-
private showWaitingSpinner(): void {
|
|
564
|
-
if (!isNullOrUndefined(this.popupObj)) {
|
|
565
|
-
if (isNullOrUndefined(this.spinnerTemplate) && isNullOrUndefined(this.spinnerElement)) {
|
|
566
|
-
this.spinnerElement = this.popupObj.element;
|
|
567
|
-
createSpinner(
|
|
568
|
-
{
|
|
569
|
-
target: this.spinnerElement,
|
|
570
|
-
width: Browser.isDevice ? '16px' : '14px'
|
|
571
|
-
},
|
|
572
|
-
this.createElement);
|
|
573
|
-
showSpinner(this.spinnerElement);
|
|
574
|
-
}
|
|
575
|
-
if (!isNullOrUndefined(this.spinnerTemplate)) {
|
|
576
|
-
this.setSpinnerTemplate();
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
private keyActionHandler(e: KeyboardEventArgs): void {
|
|
582
|
-
const isNavigation: boolean = (e.action === 'down' || e.action === 'up' || e.action === 'pageUp' || e.action === 'pageDown'
|
|
583
|
-
|| e.action === 'home' || e.action === 'end');
|
|
584
|
-
const isTabAction: boolean = e.action === 'tab' || e.action === 'close';
|
|
585
|
-
if (this.list === undefined && !this.isRequested && !isTabAction && e.action !== 'escape' && e.action !== 'space') {
|
|
586
|
-
this.renderList();
|
|
587
|
-
}
|
|
588
|
-
if (isNullOrUndefined(this.list) || (!isNullOrUndefined(this.liCollections) &&
|
|
589
|
-
isNavigation && this.liCollections.length === 0) || this.isRequested) {
|
|
590
|
-
return;
|
|
591
|
-
}
|
|
592
|
-
if (e.action === 'escape') {
|
|
593
|
-
e.preventDefault();
|
|
594
|
-
}
|
|
595
|
-
this.isSelected = e.action === 'escape' ? false : this.isSelected;
|
|
596
|
-
switch (e.action) {
|
|
597
|
-
case 'down':
|
|
598
|
-
case 'up':
|
|
599
|
-
this.isUpDownKey = true;
|
|
600
|
-
this.updateUpDownAction(e);
|
|
601
|
-
break;
|
|
602
|
-
case 'tab':
|
|
603
|
-
if (this.isPopupOpen) {
|
|
604
|
-
e.preventDefault();
|
|
605
|
-
const li: Element = this.list.querySelector('.' + dropDownBaseClasses.selected);
|
|
606
|
-
if (li) {
|
|
607
|
-
this.setSelection(li, e);
|
|
608
|
-
}
|
|
609
|
-
if (this.isPopupOpen) { this.hidePopup(e); }
|
|
610
|
-
}
|
|
611
|
-
break;
|
|
612
|
-
case 'enter':
|
|
613
|
-
if (this.isPopupOpen) {
|
|
614
|
-
e.preventDefault();
|
|
615
|
-
if (this.popupObj && this.popupObj.element.contains(this.selectedLI)) {
|
|
616
|
-
this.updateSelectedItem(this.selectedLI, e, false, true);
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
break;
|
|
620
|
-
case 'escape':
|
|
621
|
-
if (this.isPopupOpen) {
|
|
622
|
-
this.hidePopup(e);
|
|
623
|
-
}
|
|
624
|
-
break;
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
private updateUpDownAction(e: KeyboardEventArgs): void {
|
|
629
|
-
const focusEle: Element = this.list.querySelector('.' + dropDownBaseClasses.focus);
|
|
630
|
-
if (this.isSelectFocusItem(focusEle)) {
|
|
631
|
-
this.setSelection(focusEle, e);
|
|
632
|
-
} else if (!isNullOrUndefined(this.liCollections)) {
|
|
633
|
-
const li: Element = this.list.querySelector('.' + dropDownBaseClasses.selected);
|
|
634
|
-
if (!isNullOrUndefined(li)) {
|
|
635
|
-
const value: string | number | boolean = this.getFormattedValue(li.getAttribute('data-value'));
|
|
636
|
-
this.activeIndex = this.getIndexByValue(value);
|
|
637
|
-
}
|
|
638
|
-
let index: number = e.action === 'down' ? this.activeIndex + 1 : this.activeIndex - 1;
|
|
639
|
-
let startIndex: number = 0;
|
|
640
|
-
startIndex = e.action === 'down' && isNullOrUndefined(this.activeIndex) ? 0 : this.liCollections.length - 1;
|
|
641
|
-
index = index < 0 ? this.liCollections.length - 1 : index === this.liCollections.length ? 0 : index;
|
|
642
|
-
const nextItem: Element = isNullOrUndefined(this.activeIndex) ?
|
|
643
|
-
this.liCollections[startIndex as number] : this.liCollections[index as number];
|
|
644
|
-
if (!isNullOrUndefined(nextItem)) {
|
|
645
|
-
this.setSelection(nextItem, e);
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
if (this.isPopupOpen) {
|
|
649
|
-
e.preventDefault();
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
private isSelectFocusItem(element: Element): boolean {
|
|
654
|
-
return !isNullOrUndefined(element);
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
private unBindCommonEvent(): void {
|
|
658
|
-
if (!Browser.isDevice) {
|
|
659
|
-
this.keyboardModule.destroy();
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
private onKeyUp(e: KeyboardEventArgs): void {
|
|
664
|
-
let rangetextContent: string[];
|
|
665
|
-
if(this.isUpDownKey && this.isPopupOpen && e.keyCode === 229) {
|
|
666
|
-
this.isUpDownKey = false;
|
|
667
|
-
return;
|
|
668
|
-
}
|
|
669
|
-
this.isTyped = e.code !== 'Enter' && e.code !== 'Space' && e.code !== 'ArrowDown' && e.code !== 'ArrowUp' ? true : false;
|
|
670
|
-
if (document.activeElement != this.inputElement) {
|
|
671
|
-
this.inputElement.focus(); }
|
|
672
|
-
if (this.isContentEditable(this.inputElement)) {
|
|
673
|
-
this.range = this.getCurrentRange();
|
|
674
|
-
rangetextContent = this.range.startContainer.textContent.split('');
|
|
675
|
-
}
|
|
676
|
-
let currentRange: string = this.getTextRange();
|
|
677
|
-
const lastWordRange: string = this.getLastLetter(currentRange);
|
|
678
|
-
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
679
|
-
const Regex: RegExp = new RegExp(this.mentionChar, 'g');
|
|
680
|
-
const charRegex: RegExp = new RegExp('[a-zA-Z]', 'g');
|
|
681
|
-
if (e.key === 'Shift' || e.keyCode === 37 || e.keyCode === 39) { return; }
|
|
682
|
-
if ((!currentRange || !lastWordRange) || e.code === 'Enter' || e.keyCode === 27 ||
|
|
683
|
-
(lastWordRange.match(Regex) && lastWordRange.match(Regex).length > 1) ||
|
|
684
|
-
(this.isContentEditable(this.inputElement) && this.range.startContainer &&
|
|
685
|
-
(this.range.startContainer as HTMLElement).previousElementSibling && this.range.startContainer.textContent.split('').length > 0 &&
|
|
686
|
-
(rangetextContent.length === 1 || rangetextContent[rangetextContent.length - 2].indexOf('') === -1 ||
|
|
687
|
-
this.range.startContainer.nodeType === 1))) {
|
|
688
|
-
if (this.allowSpaces && currentRange && currentRange.trim() !== '' && charRegex.test(currentRange) && currentRange.indexOf(this.mentionChar) !== -1
|
|
689
|
-
&& !this.isMatchedText() && (currentRange.length > 1 && currentRange.replace(/\u00A0/g, ' ').charAt(currentRange.length - 2) !== ' ') &&
|
|
690
|
-
(this.list && this.list.querySelectorAll('ul').length > 0)) {
|
|
691
|
-
this.queryString = currentRange.substring(currentRange.lastIndexOf(this.mentionChar) + 1).replace('\u00a0', ' ');
|
|
692
|
-
this.searchLists(e);
|
|
693
|
-
} else if (this.isPopupOpen && (!this.allowSpaces || !lastWordRange) && (e.code !== 'ArrowDown' && e.code !== 'ArrowUp')) {
|
|
694
|
-
this.hidePopup();
|
|
695
|
-
this.lineBreak = true;
|
|
696
|
-
}
|
|
697
|
-
return;
|
|
698
|
-
}
|
|
699
|
-
this.queryString = lastWordRange.replace(this.mentionChar, '');
|
|
700
|
-
if (this.mentionChar.charCodeAt(0) === lastWordRange.charCodeAt(0) &&
|
|
701
|
-
this.queryString !== '' && e.keyCode !== 38 && e.keyCode !== 40 && !this.lineBreak) {
|
|
702
|
-
this.searchLists(e);
|
|
703
|
-
if (!this.isPopupOpen && this.queryString.length >= this.minLength) {
|
|
704
|
-
if (!this.isContentEditable(this.inputElement)) {
|
|
705
|
-
this.showPopup();
|
|
706
|
-
} else if (this.isContentEditable(this.inputElement) && this.range && this.range.startContainer !== this.inputElement && e.keyCode !== 9) {
|
|
707
|
-
this.showPopup();
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
} else if (lastWordRange.indexOf(this.mentionChar) === 0 && !this.isPopupOpen && e.keyCode !== 8 && (!this.popupObj ||
|
|
711
|
-
(isNullOrUndefined(this.target) && !document.body.contains(this.popupObj.element) ||
|
|
712
|
-
!isNullOrUndefined(this.target) && document.body.contains(this.popupObj.element)))) {
|
|
713
|
-
if (this.initRemoteRender && this.list && this.list.classList.contains('e-nodata')) {
|
|
714
|
-
this.searchLists(e);
|
|
715
|
-
}
|
|
716
|
-
this.resetList(this.dataSource, this.fields);
|
|
717
|
-
if (isNullOrUndefined(this.list)) {
|
|
718
|
-
this.initValue();
|
|
719
|
-
}
|
|
720
|
-
if (!this.isPopupOpen && e.keyCode !== 38 && e.keyCode !== 40) {
|
|
721
|
-
this.didPopupOpenByTypingInitialChar = true;
|
|
722
|
-
this.showPopup();
|
|
723
|
-
if (this.initRemoteRender && this.list.querySelectorAll('li').length === 0) { this.showWaitingSpinner(); }
|
|
724
|
-
this.lineBreak = false;
|
|
725
|
-
}
|
|
726
|
-
} else if (this.allowSpaces && this.queryString !== '' && currentRange && currentRange.trim() !== '' && currentRange.replace('\u00a0', ' ').lastIndexOf(' ') < currentRange.length - 1 &&
|
|
727
|
-
e.keyCode !== 38 && e.keyCode !== 40 && e.keyCode !== 8 && this.mentionChar.charCodeAt(0) === lastWordRange.charCodeAt(0)) {
|
|
728
|
-
this.queryString = currentRange.substring(currentRange.lastIndexOf(this.mentionChar) + 1).replace('\u00a0', ' ');
|
|
729
|
-
this.searchLists(e);
|
|
730
|
-
} else if (this.queryString === '' && this.isPopupOpen && e.keyCode !== 38 && e.keyCode !== 40 && this.mentionChar.charCodeAt(0) === lastWordRange.charCodeAt(0)) {
|
|
731
|
-
this.searchLists(e);
|
|
732
|
-
if(!this.isListResetted) {
|
|
733
|
-
this.resetList(this.dataSource, this.fields);
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
this.isListResetted = false;
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
private isMatchedText(): boolean {
|
|
740
|
-
let isMatched: boolean = false;
|
|
741
|
-
for (let i: number = 0; i < (this.liCollections && this.liCollections.length); i++) {
|
|
742
|
-
if (this.getTextRange() &&
|
|
743
|
-
this.getTextRange().substring(this.getTextRange().lastIndexOf(this.mentionChar) + 1).replace('\u00a0', ' ').trim() === this.liCollections[i as number].getAttribute('data-value').toLowerCase()) {
|
|
744
|
-
isMatched = true;
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
return isMatched;
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
private getCurrentRange(): Range {
|
|
751
|
-
this.range = this.inputElement.ownerDocument.getSelection().getRangeAt(0);
|
|
752
|
-
return this.range;
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
private searchLists(e: KeyboardEventArgs | MouseEvent): void {
|
|
756
|
-
this.isDataFetched = false;
|
|
757
|
-
if (isNullOrUndefined(this.list)) {
|
|
758
|
-
super.render();
|
|
759
|
-
this.unWireListEvents();
|
|
760
|
-
this.wireListEvents();
|
|
761
|
-
}
|
|
762
|
-
if (e.type !== 'mousedown' && ((<KeyboardEventArgs>e).keyCode === 40 || (<KeyboardEventArgs>e).keyCode === 38)) {
|
|
763
|
-
this.queryString = this.queryString === '' ? null : this.queryString;
|
|
764
|
-
this.beforePopupOpen = true;
|
|
765
|
-
this.resetList(this.dataSource, this.fields);
|
|
766
|
-
return;
|
|
767
|
-
}
|
|
768
|
-
this.isSelected = false;
|
|
769
|
-
this.activeIndex = null;
|
|
770
|
-
const eventArgs: { [key: string]: Object } = {
|
|
771
|
-
preventDefaultAction: false,
|
|
772
|
-
text: this.queryString,
|
|
773
|
-
updateData: (
|
|
774
|
-
dataSource: { [key: string]: Object }[] | DataManager | string[] | number[], query?: Query,
|
|
775
|
-
fields?: FieldSettingsModel) => {
|
|
776
|
-
if (eventArgs.cancel) {
|
|
777
|
-
return;
|
|
778
|
-
}
|
|
779
|
-
this.isFiltered = true;
|
|
780
|
-
this.filterAction(dataSource, query, fields);
|
|
781
|
-
},
|
|
782
|
-
cancel: false
|
|
783
|
-
};
|
|
784
|
-
this.trigger('filtering', eventArgs, (eventArgs: FilteringEventArgs) => {
|
|
785
|
-
if (!eventArgs.cancel && !this.isFiltered && !eventArgs.preventDefaultAction) {
|
|
786
|
-
this.filterAction(this.dataSource, null, this.fields);
|
|
787
|
-
}
|
|
788
|
-
});
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
private filterAction(
|
|
792
|
-
dataSource: { [key: string]: Object }[] | DataManager | string[] | number[] | boolean[],
|
|
793
|
-
query?: Query, fields?: FieldSettingsModel): void {
|
|
794
|
-
this.beforePopupOpen = true;
|
|
795
|
-
if (this.queryString.length >= this.minLength) {
|
|
796
|
-
this.resetList(dataSource, fields, query);
|
|
797
|
-
this.isListResetted = true;
|
|
798
|
-
} else {
|
|
799
|
-
if (this.isPopupOpen) { this.hidePopup(); }
|
|
800
|
-
this.beforePopupOpen = false;
|
|
801
|
-
}
|
|
802
|
-
this.setDataIndex();
|
|
803
|
-
this.renderReactTemplates();
|
|
804
|
-
}
|
|
805
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
806
|
-
protected onActionComplete(ulElement: HTMLElement, list: { [key: string]: Object }[], e?: Object, isUpdated?: boolean): void {
|
|
807
|
-
super.onActionComplete(ulElement, list, e);
|
|
808
|
-
if (this.isActive) {
|
|
809
|
-
if (!isNullOrUndefined(ulElement)) {
|
|
810
|
-
attributes(ulElement, { 'id': this.inputElement.id + '_options', 'role': 'listbox', 'aria-hidden': 'false' });
|
|
811
|
-
}
|
|
812
|
-
let focusItem: HTMLLIElement = ulElement.querySelector('.' + dropDownBaseClasses.li);
|
|
813
|
-
if (focusItem) {
|
|
814
|
-
focusItem.classList.add(dropDownBaseClasses.selected);
|
|
815
|
-
this.selectedLI = focusItem;
|
|
816
|
-
const value: string | number | boolean = this.getFormattedValue(focusItem.getAttribute('data-value'));
|
|
817
|
-
this.selectEventCallback(focusItem, this.getDataByValue(value), value, true);
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
private setDataIndex(): void {
|
|
822
|
-
for (let i: number = 0; this.liCollections && i < this.liCollections.length; i++) {
|
|
823
|
-
this.liCollections[i as number].setAttribute('data-index', i.toString());
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
protected listOption(dataSource: { [key: string]: Object }[], fieldsSettings: FieldSettingsModel): FieldSettingsModel {
|
|
828
|
-
const fields: { [key: string]: Object } = <{ [key: string]: Object }>super.listOption(dataSource, fieldsSettings);
|
|
829
|
-
if (isNullOrUndefined(fields.itemCreated)) {
|
|
830
|
-
fields.itemCreated = (e: { [key: string]: HTMLElement }) => {
|
|
831
|
-
if (this.highlight) {
|
|
832
|
-
if (this.inputElement.tagName === this.getNgDirective() && this.itemTemplate) {
|
|
833
|
-
setTimeout((): void => {
|
|
834
|
-
highlightSearch(e.item, this.queryString, this.ignoreCase, this.filterType);
|
|
835
|
-
}, 0);
|
|
836
|
-
} else {
|
|
837
|
-
highlightSearch(e.item, this.queryString, this.ignoreCase, this.filterType);
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
};
|
|
841
|
-
} else {
|
|
842
|
-
const itemCreated: Function = <Function>fields.itemCreated;
|
|
843
|
-
fields.itemCreated = (e: { [key: string]: HTMLElement }) => {
|
|
844
|
-
if (this.highlight) {
|
|
845
|
-
highlightSearch(e.item, this.queryString, this.ignoreCase, this.filterType);
|
|
846
|
-
}
|
|
847
|
-
itemCreated.apply(this, [e]);
|
|
848
|
-
};
|
|
849
|
-
}
|
|
850
|
-
return fields;
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
private elementValue(): string {
|
|
854
|
-
if (!this.isContentEditable(this.inputElement)) {
|
|
855
|
-
return (this.inputElement as HTMLInputElement | HTMLTextAreaElement).value.replace(this.mentionChar, '');
|
|
856
|
-
} else {
|
|
857
|
-
return (this.inputElement as HTMLElement).textContent.replace(this.mentionChar, '');
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
protected getQuery(query: Query): Query {
|
|
862
|
-
const filterQuery: Query = query ? query.clone() : this.query ? this.query.clone() : new Query();
|
|
863
|
-
const filterType: string = (this.queryString === '' && !isNullOrUndefined(this.elementValue())) ? 'equal' : this.filterType;
|
|
864
|
-
const queryString: string = (this.queryString === '' && !isNullOrUndefined(this.elementValue())) ?
|
|
865
|
-
this.elementValue() : this.queryString;
|
|
866
|
-
if (this.isFiltered) {
|
|
867
|
-
return filterQuery;
|
|
868
|
-
}
|
|
869
|
-
if (this.queryString !== null && this.queryString !== '') {
|
|
870
|
-
const dataType: string = <string>this.typeOfData(this.dataSource as { [key: string]: Object }[]).typeof;
|
|
871
|
-
if (!(this.dataSource instanceof DataManager) && dataType === 'string' || dataType === 'number') {
|
|
872
|
-
filterQuery.where('', filterType, queryString, this.ignoreCase, this.ignoreAccent);
|
|
873
|
-
} else {
|
|
874
|
-
const mapping: string = !isNullOrUndefined(this.fields.text) ? this.fields.text : '';
|
|
875
|
-
filterQuery.where(mapping, filterType, queryString, this.ignoreCase, this.ignoreAccent);
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
if (!isNullOrUndefined(this.suggestionCount)) {
|
|
879
|
-
// Since defualt value of suggestioncount is 25, checked the condition
|
|
880
|
-
if (this.suggestionCount !== 25) {
|
|
881
|
-
for (let queryElements: number = 0; queryElements < filterQuery.queries.length; queryElements++) {
|
|
882
|
-
if (filterQuery.queries[queryElements as number].fn === 'onTake') {
|
|
883
|
-
filterQuery.queries.splice(queryElements, 1);
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
filterQuery.take(this.suggestionCount);
|
|
888
|
-
}
|
|
889
|
-
return filterQuery;
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
private renderHightSearch(): void {
|
|
893
|
-
if (this.highlight) {
|
|
894
|
-
for (let i: number = 0; i < this.liCollections.length; i++) {
|
|
895
|
-
const isHighlight: HTMLElement = this.ulElement.querySelector('.e-active');
|
|
896
|
-
if (!isHighlight) {
|
|
897
|
-
revertHighlightSearch(this.liCollections[i as number]);
|
|
898
|
-
highlightSearch(this.liCollections[i as number], this.queryString, this.ignoreCase, this.filterType);
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
private getTextRange(): string {
|
|
905
|
-
let text: string;
|
|
906
|
-
if (!this.isContentEditable(this.inputElement)) {
|
|
907
|
-
const component: HTMLInputElement | HTMLTextAreaElement = (this.inputElement as HTMLInputElement | HTMLTextAreaElement);
|
|
908
|
-
if (!isNullOrUndefined(component)) {
|
|
909
|
-
const startPos: number = component.selectionStart;
|
|
910
|
-
if (component.value && startPos >= 0) {
|
|
911
|
-
text = component.value.substring(0, startPos);
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
} else {
|
|
915
|
-
if (this.range) {
|
|
916
|
-
const selectedElem: Node = this.range.startContainer;
|
|
917
|
-
if (!isNullOrUndefined(selectedElem)) {
|
|
918
|
-
const workingNodeContent: string = selectedElem.textContent;
|
|
919
|
-
const selectStartOffset: number = this.range.startOffset;
|
|
920
|
-
if (workingNodeContent && selectStartOffset >= 0) {
|
|
921
|
-
text = workingNodeContent.substring(0, selectStartOffset);
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
return text;
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
private getLastLetter(text: string): string {
|
|
930
|
-
if (isNullOrUndefined(text)) {return ''; }
|
|
931
|
-
const textValue: string = text.replace(/\u00A0/g, ' ');
|
|
932
|
-
const words: string[] = textValue.split(/\s+/);
|
|
933
|
-
const wordCnt: number = words.length - 1;
|
|
934
|
-
return words[wordCnt as number].trim();
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
private isContentEditable(element: HTMLInputElement | HTMLTextAreaElement | HTMLElement): boolean {
|
|
938
|
-
return element && element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA';
|
|
939
|
-
}
|
|
940
|
-
|
|
941
|
-
/**
|
|
942
|
-
* Opens the popup that displays the list of items.
|
|
943
|
-
*
|
|
944
|
-
* @returns {void}
|
|
945
|
-
*/
|
|
946
|
-
public showPopup(): void {
|
|
947
|
-
this.beforePopupOpen = true;
|
|
948
|
-
if (document.activeElement != this.inputElement) {
|
|
949
|
-
this.inputElement.focus();
|
|
950
|
-
}
|
|
951
|
-
this.queryString = this.didPopupOpenByTypingInitialChar ? this.queryString : '';
|
|
952
|
-
this.didPopupOpenByTypingInitialChar = false;
|
|
953
|
-
if (this.isContentEditable(this.inputElement)) {
|
|
954
|
-
this.range = this.getCurrentRange();
|
|
955
|
-
}
|
|
956
|
-
if (!this.isTyped) {
|
|
957
|
-
this.resetList(this.dataSource, this.fields);
|
|
958
|
-
}
|
|
959
|
-
if (isNullOrUndefined(this.list)) {
|
|
960
|
-
this.initValue();
|
|
961
|
-
}
|
|
962
|
-
this.renderPopup();
|
|
963
|
-
attributes(this.inputElement, { 'aria-activedescendant': this.selectedElementID});
|
|
964
|
-
if (this.selectedElementID == null)
|
|
965
|
-
{
|
|
966
|
-
this.inputElement.removeAttribute('aria-activedescendant');
|
|
967
|
-
}
|
|
968
|
-
}
|
|
969
|
-
|
|
970
|
-
/* eslint-disable valid-jsdoc, jsdoc/require-param */
|
|
971
|
-
/**
|
|
972
|
-
* Hides the popup if it is in an open state.
|
|
973
|
-
*
|
|
974
|
-
* @returns {void}
|
|
975
|
-
*/
|
|
976
|
-
public hidePopup(e?: MouseEvent | KeyboardEventArgs): void {
|
|
977
|
-
this.removeSelection();
|
|
978
|
-
this.closePopup(0, e);
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
private closePopup(delay: number, e: MouseEvent | KeyboardEventArgs): void {
|
|
982
|
-
if (!(this.popupObj && document.body.contains(this.popupObj.element) && this.beforePopupOpen)) {
|
|
983
|
-
return;
|
|
984
|
-
}
|
|
985
|
-
EventHandler.remove(document, 'mousedown', this.onDocumentClick);
|
|
986
|
-
this.inputElement.removeAttribute('aria-owns');
|
|
987
|
-
this.inputElement.removeAttribute('aria-activedescendant');
|
|
988
|
-
this.beforePopupOpen = false;
|
|
989
|
-
const animModel: AnimationModel = {
|
|
990
|
-
name: 'FadeOut',
|
|
991
|
-
duration: 100,
|
|
992
|
-
delay: delay ? delay : 0
|
|
993
|
-
};
|
|
994
|
-
const popupInstance: Popup = this.popupObj;
|
|
995
|
-
const eventArgs: PopupEventArgs = { popup: popupInstance, cancel: false, animation: animModel , event: e || null};
|
|
996
|
-
this.trigger('closed', eventArgs, (eventArgs: PopupEventArgs) => {
|
|
997
|
-
if (!eventArgs.cancel && this.popupObj) {
|
|
998
|
-
if (this.isPopupOpen) {
|
|
999
|
-
this.popupObj.hide(new Animation(eventArgs.animation));
|
|
1000
|
-
} else {
|
|
1001
|
-
this.destroyPopup();
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
});
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
private renderPopup(): void {
|
|
1008
|
-
const args: BeforeOpenEventArgs = { cancel: false };
|
|
1009
|
-
this.trigger('beforeOpen', args, (args: BeforeOpenEventArgs) => {
|
|
1010
|
-
if (!args.cancel) {
|
|
1011
|
-
let popupEle: HTMLElement;
|
|
1012
|
-
if (isNullOrUndefined(this.target)) {
|
|
1013
|
-
popupEle = this.createElement('div', {
|
|
1014
|
-
id: this.inputElement.id + '_popup', className: 'e-mention e-popup ' + (this.cssClass != null ? this.cssClass : '')
|
|
1015
|
-
});
|
|
1016
|
-
} else {
|
|
1017
|
-
popupEle = this.element;
|
|
1018
|
-
if (this.cssClass != null) { addClass([popupEle], this.cssClass.split(' ')); }
|
|
1019
|
-
}
|
|
1020
|
-
if (!isNullOrUndefined(this.target)) {
|
|
1021
|
-
popupEle.id = this.inputElement.id + '_popup';
|
|
1022
|
-
}
|
|
1023
|
-
this.listHeight = formatUnit(this.popupHeight);
|
|
1024
|
-
if (!isNullOrUndefined(this.list.querySelector('li')) && !this.initRemoteRender) {
|
|
1025
|
-
const li: HTMLLIElement = this.list.querySelector('.' + dropDownBaseClasses.focus);
|
|
1026
|
-
if (!isNullOrUndefined(li)) {
|
|
1027
|
-
this.selectedLI = li;
|
|
1028
|
-
const value: string | number | boolean = this.getFormattedValue(li.getAttribute('data-value'));
|
|
1029
|
-
this.selectEventCallback(li, this.getDataByValue(value), value, true);
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
append([this.list], popupEle);
|
|
1033
|
-
if (this.inputElement.parentElement && this.inputElement.parentElement.parentElement &&
|
|
1034
|
-
this.inputElement.parentElement.parentElement.classList.contains('e-richtexteditor')) {
|
|
1035
|
-
if (popupEle.firstElementChild && popupEle.firstElementChild.childElementCount > 0) {
|
|
1036
|
-
popupEle.firstElementChild.setAttribute('aria-owns', this.inputElement.parentElement.parentElement.id);
|
|
1037
|
-
}
|
|
1038
|
-
}
|
|
1039
|
-
if ((!this.popupObj || !document.body.contains(this.popupObj.element)) ||
|
|
1040
|
-
!document.contains(popupEle) && isNullOrUndefined(this.target)) {
|
|
1041
|
-
document.body.appendChild(popupEle);
|
|
1042
|
-
}
|
|
1043
|
-
let coordinates: { [key: string]: number };
|
|
1044
|
-
popupEle.style.visibility = 'hidden';
|
|
1045
|
-
this.setHeight(popupEle);
|
|
1046
|
-
const offsetValue: number = 0;
|
|
1047
|
-
const left: number = 0;
|
|
1048
|
-
this.initializePopup(popupEle, offsetValue, left);
|
|
1049
|
-
this.checkCollision(popupEle);
|
|
1050
|
-
popupEle.style.visibility = 'visible';
|
|
1051
|
-
addClass([popupEle], ['e-mention' , 'e-popup', 'e-popup-close']);
|
|
1052
|
-
if (!isNullOrUndefined(this.list)) {
|
|
1053
|
-
this.unWireListEvents(); this.wireListEvents();
|
|
1054
|
-
}
|
|
1055
|
-
this.selectedElementID = this.selectedLI ? this.selectedLI.id : null;
|
|
1056
|
-
attributes(this.inputElement, { 'aria-owns': this.inputElement.id + '_options', 'aria-activedescendant': this.selectedElementID });
|
|
1057
|
-
if (this.selectedElementID == null)
|
|
1058
|
-
{
|
|
1059
|
-
this.inputElement.removeAttribute('aria-activedescendant');
|
|
1060
|
-
}
|
|
1061
|
-
const animModel: AnimationModel = { name: 'FadeIn', duration: 100 };
|
|
1062
|
-
this.beforePopupOpen = true;
|
|
1063
|
-
const popupInstance: Popup = this.popupObj;
|
|
1064
|
-
const eventArgs: PopupEventArgs = { popup: popupInstance, cancel: false, animation: animModel };
|
|
1065
|
-
this.trigger('opened', eventArgs, (eventArgs: PopupEventArgs) => {
|
|
1066
|
-
if (!eventArgs.cancel) {
|
|
1067
|
-
this.renderReactTemplates();
|
|
1068
|
-
if (this.popupObj) {
|
|
1069
|
-
this.popupObj.show(new Animation(eventArgs.animation), (this.zIndex === 1000) ? this.inputElement : null);
|
|
1070
|
-
}
|
|
1071
|
-
if (isNullOrUndefined(this.getTriggerCharPosition())) { return; }
|
|
1072
|
-
coordinates = this.getCoordinates(this.inputElement, this.getTriggerCharPosition());
|
|
1073
|
-
if (!this.isCollided) {
|
|
1074
|
-
popupEle.style.cssText = 'top: '.concat(coordinates.top.toString(), 'px;\n left: ').concat(coordinates.left.toString(), 'px;\nposition: absolute;\n display: block;');
|
|
1075
|
-
} else {
|
|
1076
|
-
popupEle.style.left = formatUnit(coordinates.left);
|
|
1077
|
-
popupEle.style.top = formatUnit(coordinates.top - parseInt(this.popupHeight.toString()));
|
|
1078
|
-
this.isCollided = false;
|
|
1079
|
-
}
|
|
1080
|
-
popupEle.style.width = this.popupWidth !== '100%' && !isNullOrUndefined(this.popupWidth) ? formatUnit(this.popupWidth) : 'auto';
|
|
1081
|
-
this.setHeight(popupEle);
|
|
1082
|
-
popupEle.style.zIndex = this.zIndex === 1000 ? getZindexPartial(popupEle).toString() : this.zIndex.toString();
|
|
1083
|
-
} else {
|
|
1084
|
-
this.beforePopupOpen = false;
|
|
1085
|
-
this.destroyPopup();
|
|
1086
|
-
}
|
|
1087
|
-
});
|
|
1088
|
-
} else {
|
|
1089
|
-
this.beforePopupOpen = false;
|
|
1090
|
-
}
|
|
1091
|
-
});
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
private setHeight(popupEle: HTMLElement): void {
|
|
1095
|
-
if (this.popupHeight !== 'auto' && this.list) {
|
|
1096
|
-
this.list.style.maxHeight = (parseInt(this.listHeight, 10) - 2).toString() + 'px'; // due to box-sizing property
|
|
1097
|
-
popupEle.style.maxHeight = formatUnit(this.popupHeight);
|
|
1098
|
-
} else {
|
|
1099
|
-
popupEle.style.height = 'auto';
|
|
1100
|
-
}
|
|
1101
|
-
}
|
|
1102
|
-
|
|
1103
|
-
private checkCollision(popupEle: HTMLElement): void {
|
|
1104
|
-
if (!Browser.isDevice || (Browser.isDevice && !(this.getModuleName() === 'mention'))) {
|
|
1105
|
-
let coordinates: { [key: string]: number } = this.getCoordinates(this.inputElement, this.getTriggerCharPosition());
|
|
1106
|
-
const collision: string[] = isCollide(popupEle, null, coordinates.left, coordinates.top);
|
|
1107
|
-
if (collision.length > 0) {
|
|
1108
|
-
popupEle.style.marginTop = -parseInt(getComputedStyle(popupEle).marginTop, 10) + 'px';
|
|
1109
|
-
this.isCollided = true;
|
|
1110
|
-
}
|
|
1111
|
-
this.popupObj.resolveCollision();
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
|
-
private getTriggerCharPosition(): number {
|
|
1116
|
-
let mostRecentTriggerCharPos: number;
|
|
1117
|
-
const currentRange: string = this.getTextRange();
|
|
1118
|
-
if (currentRange !== undefined && currentRange !== null) {
|
|
1119
|
-
mostRecentTriggerCharPos = 0;
|
|
1120
|
-
const idx: number = currentRange.lastIndexOf(this.mentionChar);
|
|
1121
|
-
if (idx >= mostRecentTriggerCharPos) {
|
|
1122
|
-
mostRecentTriggerCharPos = idx;
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1125
|
-
return mostRecentTriggerCharPos ? mostRecentTriggerCharPos : 0;
|
|
1126
|
-
}
|
|
1127
|
-
|
|
1128
|
-
private initializePopup(element: HTMLElement, offsetValue: number, left: number): void {
|
|
1129
|
-
this.popupObj = new Popup(element, {
|
|
1130
|
-
width: this.setWidth(), targetType: 'relative',
|
|
1131
|
-
relateTo: this.inputElement, collision: { X: 'flip', Y: 'flip' }, offsetY: offsetValue,
|
|
1132
|
-
enableRtl: this.enableRtl, offsetX: left, position: { X: 'left', Y: 'bottom' }, actionOnScroll: 'hide',
|
|
1133
|
-
zIndex: this.zIndex,
|
|
1134
|
-
close: () => {
|
|
1135
|
-
this.destroyPopup();
|
|
1136
|
-
},
|
|
1137
|
-
open: () => {
|
|
1138
|
-
EventHandler.add(document, 'mousedown', this.onDocumentClick, this);
|
|
1139
|
-
this.isPopupOpen = true;
|
|
1140
|
-
this.setDataIndex();
|
|
1141
|
-
}
|
|
1142
|
-
});
|
|
1143
|
-
}
|
|
1144
|
-
|
|
1145
|
-
private setWidth(): string {
|
|
1146
|
-
let width: string = formatUnit(this.popupWidth);
|
|
1147
|
-
if (width.indexOf('%') > -1) {
|
|
1148
|
-
const inputWidth: number = this.inputElement.offsetWidth * parseFloat(width) / 100;
|
|
1149
|
-
width = inputWidth.toString() + 'px';
|
|
1150
|
-
}
|
|
1151
|
-
return width;
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1154
|
-
private destroyPopup(): void {
|
|
1155
|
-
this.isPopupOpen = false;
|
|
1156
|
-
this.popupObj.destroy();
|
|
1157
|
-
if (isNullOrUndefined(this.target)) {
|
|
1158
|
-
detach(this.popupObj.element);
|
|
1159
|
-
} else {
|
|
1160
|
-
this.popupObj.element.innerHTML = '';
|
|
1161
|
-
this.popupObj.element.removeAttribute('style');
|
|
1162
|
-
this.popupObj.element.removeAttribute('aria-disabled');
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1166
|
-
private onDocumentClick(e: MouseEvent): void {
|
|
1167
|
-
const target: HTMLElement = <HTMLElement>e.target;
|
|
1168
|
-
if (!(!isNullOrUndefined(this.popupObj) && closest(target, '#' + this.popupObj.element.id))) {
|
|
1169
|
-
this.hidePopup(e);
|
|
1170
|
-
}
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
|
-
private getCoordinates(element: HTMLInputElement | HTMLTextAreaElement | HTMLElement, position: number): { [key: string]: number } {
|
|
1174
|
-
const properties: string[] = ['direction', 'boxSizing', 'width', 'height', 'overflowX', 'overflowY', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', 'fontStyle', 'fontVariant', 'fontWeight', 'fontStretch', 'fontSize', 'fontSizeAdjust', 'lineHeight', 'fontFamily', 'textAlign', 'textTransform', 'textIndent', 'textDecoration', 'letterSpacing', 'wordSpacing'];
|
|
1175
|
-
let div: HTMLElement;
|
|
1176
|
-
let span: HTMLElement;
|
|
1177
|
-
let range: Range;
|
|
1178
|
-
let globalRange: Range;
|
|
1179
|
-
let coordinates: { [key: string]: number };
|
|
1180
|
-
let computed: CSSStyleDeclaration;
|
|
1181
|
-
let rect: ClientRect;
|
|
1182
|
-
if (!this.isContentEditable(this.inputElement)) {
|
|
1183
|
-
div = this.createElement('div', { className: 'e-form-mirror-div'});
|
|
1184
|
-
document.body.appendChild(div);
|
|
1185
|
-
computed = getComputedStyle((element as HTMLInputElement | HTMLTextAreaElement));
|
|
1186
|
-
div.style.position = 'absolute';
|
|
1187
|
-
div.style.visibility = 'hidden';
|
|
1188
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1189
|
-
properties.forEach((prop: any) => {
|
|
1190
|
-
// eslint-disable-next-line security/detect-object-injection
|
|
1191
|
-
div.style[prop] = computed[prop];
|
|
1192
|
-
});
|
|
1193
|
-
div.textContent = (element as HTMLInputElement | HTMLTextAreaElement).value.substring(0, position);
|
|
1194
|
-
if (this.inputElement.nodeName === 'INPUT') {
|
|
1195
|
-
div.textContent = div.textContent.replace(/\s/g, '\u00a0');
|
|
1196
|
-
}
|
|
1197
|
-
span = this.createElement('span');
|
|
1198
|
-
span.textContent = (element as HTMLInputElement | HTMLTextAreaElement).value.substring(position) || '.';
|
|
1199
|
-
div.appendChild(span);
|
|
1200
|
-
rect = (element as HTMLInputElement | HTMLTextAreaElement).getBoundingClientRect();
|
|
1201
|
-
} else {
|
|
1202
|
-
const selectedNodePosition: number = this.getTriggerCharPosition();
|
|
1203
|
-
globalRange = this.range;
|
|
1204
|
-
range = document.createRange();
|
|
1205
|
-
if (this.getTextRange() && this.getTextRange().lastIndexOf(this.mentionChar) !== -1) {
|
|
1206
|
-
range.setStart(globalRange.startContainer, selectedNodePosition);
|
|
1207
|
-
range.setEnd(globalRange.startContainer, selectedNodePosition);
|
|
1208
|
-
}
|
|
1209
|
-
else {
|
|
1210
|
-
range.setStart(globalRange.startContainer, globalRange.startOffset);
|
|
1211
|
-
range.setEnd(globalRange.startContainer, globalRange.endOffset);
|
|
1212
|
-
}
|
|
1213
|
-
this.isTyped = false;
|
|
1214
|
-
range.collapse(false);
|
|
1215
|
-
rect = range.getBoundingClientRect().top === 0 ? (range.startContainer as any).getClientRects()[0] : range.getBoundingClientRect();
|
|
1216
|
-
}
|
|
1217
|
-
const doc: HTMLElement = document.documentElement;
|
|
1218
|
-
const windowLeft: number = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
|
|
1219
|
-
const windowTop: number = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
|
|
1220
|
-
let width: number = 0;
|
|
1221
|
-
if (!isNullOrUndefined(range) && range.getBoundingClientRect().top === 0) {
|
|
1222
|
-
for (let i = 0; i < this.range.startContainer.childNodes.length; i++) {
|
|
1223
|
-
if (this.range.startContainer.childNodes[i as number].nodeType !== Node.TEXT_NODE && this.range.startContainer.childNodes[i as number].textContent.trim() !== '') {
|
|
1224
|
-
width += (this.range.startContainer.childNodes[i as number] as any).getClientRects()[0].width;
|
|
1225
|
-
}
|
|
1226
|
-
else if (this.range.startContainer.childNodes[i as number].textContent !== '') {
|
|
1227
|
-
let span = document.createElement("span");
|
|
1228
|
-
span.innerHTML = this.range.startContainer.childNodes[i as number].nodeValue;
|
|
1229
|
-
document.body.appendChild(span);
|
|
1230
|
-
let textNodeWidth : number = span.offsetWidth;
|
|
1231
|
-
document.body.removeChild(span);
|
|
1232
|
-
width += textNodeWidth;
|
|
1233
|
-
}
|
|
1234
|
-
}
|
|
1235
|
-
}
|
|
1236
|
-
if (!this.isContentEditable(this.inputElement)) {
|
|
1237
|
-
coordinates = {
|
|
1238
|
-
top: rect.top + windowTop + span.offsetTop + parseInt(computed.borderTopWidth, 10) +
|
|
1239
|
-
parseInt(computed.fontSize, 10) + 3 - (element as HTMLInputElement | HTMLTextAreaElement).scrollTop - (this.isCollided ? 10 : 0),
|
|
1240
|
-
left: rect.left + windowLeft + span.offsetLeft + parseInt(computed.borderLeftWidth, 10)
|
|
1241
|
-
};
|
|
1242
|
-
document.body.removeChild(div);
|
|
1243
|
-
} else {
|
|
1244
|
-
coordinates = {
|
|
1245
|
-
top: rect.top + windowTop + parseInt(getComputedStyle(this.inputElement).fontSize, 10) - (this.isCollided ? 10 : 0),
|
|
1246
|
-
left: rect.left + windowLeft + width
|
|
1247
|
-
};
|
|
1248
|
-
}
|
|
1249
|
-
return coordinates;
|
|
1250
|
-
}
|
|
1251
|
-
|
|
1252
|
-
private initValue(): void {
|
|
1253
|
-
this.renderList();
|
|
1254
|
-
if (this.dataSource instanceof DataManager) {
|
|
1255
|
-
this.initRemoteRender = true;
|
|
1256
|
-
} else {
|
|
1257
|
-
this.updateValues();
|
|
1258
|
-
}
|
|
1259
|
-
}
|
|
1260
|
-
|
|
1261
|
-
private updateValues(): void {
|
|
1262
|
-
const li: HTMLElement = this.list.querySelector('.' + dropDownBaseClasses.focus);
|
|
1263
|
-
if (!isNullOrUndefined(li)) {
|
|
1264
|
-
this.setSelection(li, null);
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1267
|
-
|
|
1268
|
-
protected renderList(): void {
|
|
1269
|
-
super.render();
|
|
1270
|
-
this.unWireListEvents();
|
|
1271
|
-
this.wireListEvents();
|
|
1272
|
-
}
|
|
1273
|
-
|
|
1274
|
-
/**
|
|
1275
|
-
* Event binding for list
|
|
1276
|
-
*
|
|
1277
|
-
* @returns {void}
|
|
1278
|
-
*/
|
|
1279
|
-
private wireListEvents(): void {
|
|
1280
|
-
EventHandler.add(this.list, 'click', this.onMouseClick, this);
|
|
1281
|
-
EventHandler.add(this.list, 'mouseover', this.onMouseOver, this);
|
|
1282
|
-
EventHandler.add(this.list, 'mouseout', this.onMouseLeave, this);
|
|
1283
|
-
}
|
|
1284
|
-
|
|
1285
|
-
/**
|
|
1286
|
-
* Event un binding for list items.
|
|
1287
|
-
*
|
|
1288
|
-
* @returns {void}
|
|
1289
|
-
*/
|
|
1290
|
-
private unWireListEvents(): void {
|
|
1291
|
-
EventHandler.remove(this.list, 'click', this.onMouseClick);
|
|
1292
|
-
EventHandler.remove(this.list, 'mouseover', this.onMouseOver);
|
|
1293
|
-
EventHandler.remove(this.list, 'mouseout', this.onMouseLeave);
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
|
-
private onMouseClick(e: MouseEvent): void {
|
|
1297
|
-
const target: Element = <Element>e.target;
|
|
1298
|
-
const li: HTMLElement = <HTMLElement>closest(target, '.' + dropDownBaseClasses.li);
|
|
1299
|
-
if (!this.isValidLI(li)) {
|
|
1300
|
-
return;
|
|
1301
|
-
}
|
|
1302
|
-
this.isSelected = true;
|
|
1303
|
-
this.setSelection(li, e);
|
|
1304
|
-
const delay: number = 100;
|
|
1305
|
-
this.closePopup(delay, e);
|
|
1306
|
-
this.inputElement.focus();
|
|
1307
|
-
}
|
|
1308
|
-
|
|
1309
|
-
private updateSelectedItem(
|
|
1310
|
-
li: Element,
|
|
1311
|
-
e: MouseEvent | KeyboardEvent | TouchEvent,
|
|
1312
|
-
preventSelect?: boolean,
|
|
1313
|
-
isSelection?: boolean): void {
|
|
1314
|
-
this.removeSelection();
|
|
1315
|
-
li.classList.add(dropDownBaseClasses.selected);
|
|
1316
|
-
this.removeHover();
|
|
1317
|
-
const value: string | number | boolean = this.getFormattedValue(li.getAttribute('data-value'));
|
|
1318
|
-
const selectedData: string | number | boolean | {
|
|
1319
|
-
[key: string]: Object
|
|
1320
|
-
} = this.getDataByValue(value);
|
|
1321
|
-
if (!preventSelect && !isNullOrUndefined(e) && !((e as KeyboardEventArgs).action === "down" || (e as KeyboardEventArgs).action === "up")) {
|
|
1322
|
-
const items: FieldSettingsModel = this.detachChanges(selectedData);
|
|
1323
|
-
this.isSelected = true;
|
|
1324
|
-
const eventArgs: SelectEventArgs = {
|
|
1325
|
-
e: e,
|
|
1326
|
-
item: li as HTMLLIElement,
|
|
1327
|
-
itemData: items,
|
|
1328
|
-
isInteracted: e ? true : false,
|
|
1329
|
-
cancel: false
|
|
1330
|
-
};
|
|
1331
|
-
this.trigger('select', eventArgs, (eventArgs: SelectEventArgs) => {
|
|
1332
|
-
if (eventArgs.cancel) {
|
|
1333
|
-
li.classList.remove(dropDownBaseClasses.selected);
|
|
1334
|
-
this.isSelected = false;
|
|
1335
|
-
this.isSelectCancel = true;
|
|
1336
|
-
} else {
|
|
1337
|
-
this.selectEventCallback(li, selectedData, value);
|
|
1338
|
-
if (isSelection) {
|
|
1339
|
-
this.setSelectOptions(li, e);
|
|
1340
|
-
}
|
|
1341
|
-
}
|
|
1342
|
-
});
|
|
1343
|
-
} else {
|
|
1344
|
-
this.selectEventCallback(li, selectedData, value);
|
|
1345
|
-
if (isSelection) {
|
|
1346
|
-
this.setSelectOptions(li, e);
|
|
1347
|
-
}
|
|
1348
|
-
}
|
|
1349
|
-
}
|
|
1350
|
-
|
|
1351
|
-
private setSelection(li: Element, e: MouseEvent | KeyboardEventArgs | TouchEvent): void {
|
|
1352
|
-
if (this.isValidLI(li) && (!li.classList.contains(dropDownBaseClasses.selected) || (this.isPopupOpen && this.isSelected
|
|
1353
|
-
&& li.classList.contains(dropDownBaseClasses.selected)))) {
|
|
1354
|
-
this.updateSelectedItem(li, e, false, true);
|
|
1355
|
-
} else {
|
|
1356
|
-
this.setSelectOptions(li, e);
|
|
1357
|
-
}
|
|
1358
|
-
}
|
|
1359
|
-
|
|
1360
|
-
private setSelectOptions(li: Element, e?: MouseEvent | KeyboardEventArgs | KeyboardEvent | TouchEvent): void {
|
|
1361
|
-
if (this.list) {
|
|
1362
|
-
this.removeHover();
|
|
1363
|
-
}
|
|
1364
|
-
this.previousSelectedLI = (!isNullOrUndefined(this.selectedLI)) ? this.selectedLI : null;
|
|
1365
|
-
this.selectedLI = li as HTMLLIElement;
|
|
1366
|
-
if (this.isPopupOpen && !isNullOrUndefined(this.selectedLI)) {
|
|
1367
|
-
this.setScrollPosition(e as KeyboardEventArgs);
|
|
1368
|
-
}
|
|
1369
|
-
if (e && ((e as KeyboardEventArgs).keyCode === 38 || (e as KeyboardEventArgs).keyCode === 40)) { return; }
|
|
1370
|
-
if (isNullOrUndefined(e) || this.setValue(e as KeyboardEventArgs)) {
|
|
1371
|
-
return;
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
|
|
1375
|
-
private setScrollPosition(e?: KeyboardEventArgs): void {
|
|
1376
|
-
if (!isNullOrUndefined(e)) {
|
|
1377
|
-
switch (e.action) {
|
|
1378
|
-
case 'pageDown':
|
|
1379
|
-
case 'down':
|
|
1380
|
-
case 'end':
|
|
1381
|
-
this.scrollBottom();
|
|
1382
|
-
break;
|
|
1383
|
-
default:
|
|
1384
|
-
this.scrollTop();
|
|
1385
|
-
break;
|
|
1386
|
-
}
|
|
1387
|
-
} else {
|
|
1388
|
-
this.scrollBottom(true);
|
|
1389
|
-
}
|
|
1390
|
-
}
|
|
1391
|
-
|
|
1392
|
-
private scrollBottom(isInitial?: boolean): void {
|
|
1393
|
-
if (!isNullOrUndefined(this.selectedLI)) {
|
|
1394
|
-
const currentOffset: number = this.list.offsetHeight;
|
|
1395
|
-
const nextBottom: number = this.selectedLI.offsetTop + this.selectedLI.offsetHeight - this.list.scrollTop;
|
|
1396
|
-
let nextOffset: number = this.list.scrollTop + nextBottom - currentOffset;
|
|
1397
|
-
nextOffset = isInitial ? nextOffset + parseInt(getComputedStyle(this.list).paddingTop, 10) * 2 : nextOffset;
|
|
1398
|
-
const boxRange: number = this.selectedLI.offsetTop + this.selectedLI.offsetHeight - this.list.scrollTop;
|
|
1399
|
-
if (this.activeIndex === 0) {
|
|
1400
|
-
this.list.scrollTop = 0;
|
|
1401
|
-
} else if (nextBottom > currentOffset || !(boxRange > 0 && this.list.offsetHeight > boxRange)) {
|
|
1402
|
-
this.list.scrollTop = nextOffset;
|
|
1403
|
-
}
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1406
|
-
|
|
1407
|
-
private scrollTop(): void {
|
|
1408
|
-
if (!isNullOrUndefined(this.selectedLI)) {
|
|
1409
|
-
let nextOffset: number = this.selectedLI.offsetTop - this.list.scrollTop;
|
|
1410
|
-
nextOffset = this.fields.groupBy && nextOffset;
|
|
1411
|
-
const boxRange: number = (this.selectedLI.offsetTop + this.selectedLI.offsetHeight - this.list.scrollTop);
|
|
1412
|
-
if (this.activeIndex === 0) {
|
|
1413
|
-
this.list.scrollTop = 0;
|
|
1414
|
-
} else if (nextOffset < 0) {
|
|
1415
|
-
this.list.scrollTop = this.list.scrollTop + nextOffset;
|
|
1416
|
-
} else if (!(boxRange > 0 && this.list.offsetHeight > boxRange)) {
|
|
1417
|
-
this.list.scrollTop = this.selectedLI.offsetTop;
|
|
1418
|
-
}
|
|
1419
|
-
}
|
|
1420
|
-
}
|
|
1421
|
-
|
|
1422
|
-
private selectEventCallback(
|
|
1423
|
-
li: Element,
|
|
1424
|
-
selectedData?: string | number | boolean | { [key: string]: Object },
|
|
1425
|
-
value?: string | number | boolean, selectLi?: boolean): void {
|
|
1426
|
-
this.previousItemData = (!isNullOrUndefined(this.itemData)) ? this.itemData : null;
|
|
1427
|
-
this.item = li as HTMLLIElement;
|
|
1428
|
-
this.itemData = selectedData;
|
|
1429
|
-
const focusedItem: Element = this.list.querySelector('.' + dropDownBaseClasses.focus);
|
|
1430
|
-
if (focusedItem) {
|
|
1431
|
-
removeClass([focusedItem], dropDownBaseClasses.focus);
|
|
1432
|
-
}
|
|
1433
|
-
if (selectLi) {
|
|
1434
|
-
addClass([li], dropDownBaseClasses.selected);
|
|
1435
|
-
}
|
|
1436
|
-
li.setAttribute('aria-selected', 'true');
|
|
1437
|
-
this.activeIndex = this.getIndexByValue(value);
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
|
-
private detachChanges(value: string | number | boolean | {
|
|
1441
|
-
[key: string]: Object
|
|
1442
|
-
}): FieldSettingsModel {
|
|
1443
|
-
let items: FieldSettingsModel;
|
|
1444
|
-
if (typeof value === 'string' ||
|
|
1445
|
-
typeof value === 'boolean' ||
|
|
1446
|
-
typeof value === 'number') {
|
|
1447
|
-
items = Object.defineProperties({}, {
|
|
1448
|
-
value: {
|
|
1449
|
-
value: value,
|
|
1450
|
-
enumerable: true
|
|
1451
|
-
},
|
|
1452
|
-
text: {
|
|
1453
|
-
value: value,
|
|
1454
|
-
enumerable: true
|
|
1455
|
-
}
|
|
1456
|
-
});
|
|
1457
|
-
} else {
|
|
1458
|
-
items = value;
|
|
1459
|
-
}
|
|
1460
|
-
return items;
|
|
1461
|
-
}
|
|
1462
|
-
|
|
1463
|
-
private setValue(e?: KeyboardEventArgs | MouseEvent): boolean {
|
|
1464
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1465
|
-
if (!(this as any).isReact) {
|
|
1466
|
-
if (!isNullOrUndefined(this.displayTemplate)) {
|
|
1467
|
-
this.setDisplayTemplate();
|
|
1468
|
-
}
|
|
1469
|
-
this.updateMentionValue(e);
|
|
1470
|
-
return true;
|
|
1471
|
-
}
|
|
1472
|
-
else {
|
|
1473
|
-
if (!isNullOrUndefined(this.displayTemplate)) {
|
|
1474
|
-
this.setDisplayTemplate(e);
|
|
1475
|
-
} else {
|
|
1476
|
-
this.updateMentionValue(e);
|
|
1477
|
-
}
|
|
1478
|
-
return true;
|
|
1479
|
-
}
|
|
1480
|
-
}
|
|
1481
|
-
|
|
1482
|
-
private updateMentionValue(e?: KeyboardEventArgs | MouseEvent): void {
|
|
1483
|
-
const dataItem: { [key: string]: string } = this.getItemData();
|
|
1484
|
-
let textSuffix: string;
|
|
1485
|
-
let value: string;
|
|
1486
|
-
let endPos: number;
|
|
1487
|
-
let range: Range;
|
|
1488
|
-
let globalRange: Range;
|
|
1489
|
-
const selection: Selection = this.inputElement.ownerDocument.getSelection();
|
|
1490
|
-
const startPos: number = this.getTriggerCharPosition();
|
|
1491
|
-
textSuffix = typeof this.suffixText === 'string' ? this.suffixText : '';
|
|
1492
|
-
if (this.isSelectCancel) {
|
|
1493
|
-
this.isSelectCancel = false;
|
|
1494
|
-
return;
|
|
1495
|
-
}
|
|
1496
|
-
if (dataItem.text !== null) {
|
|
1497
|
-
value = this.mentionVal(dataItem.text);
|
|
1498
|
-
}
|
|
1499
|
-
if (!this.isContentEditable(this.inputElement)) {
|
|
1500
|
-
const myField: HTMLInputElement | HTMLTextAreaElement = this.inputElement as HTMLInputElement | HTMLTextAreaElement;
|
|
1501
|
-
const currentTriggerSnippet: string =
|
|
1502
|
-
this.getTextRange().substring(startPos + this.mentionChar.length, this.getTextRange().length);
|
|
1503
|
-
value += textSuffix;
|
|
1504
|
-
endPos = startPos + this.mentionChar.length;
|
|
1505
|
-
endPos += currentTriggerSnippet.length;
|
|
1506
|
-
myField.value = myField.value.substring(0, startPos) + value + myField.value.substring(endPos, myField.value.length);
|
|
1507
|
-
myField.selectionStart = startPos + value.length;
|
|
1508
|
-
myField.selectionEnd = startPos + value.length;
|
|
1509
|
-
if (this.isPopupOpen) { this.hidePopup(); }
|
|
1510
|
-
this.onChangeEvent(e);
|
|
1511
|
-
} else {
|
|
1512
|
-
endPos = this.getTriggerCharPosition() + this.mentionChar.length;
|
|
1513
|
-
if (this.range && (this.range.startContainer.textContent.trim() !== this.mentionChar)) {
|
|
1514
|
-
endPos = this.range.endOffset;
|
|
1515
|
-
}
|
|
1516
|
-
globalRange = this.range;
|
|
1517
|
-
range = document.createRange();
|
|
1518
|
-
if (((this.getTextRange() && this.getTextRange().lastIndexOf(this.mentionChar) !== -1) || this.getTextRange() && this.getTextRange().trim() === this.mentionChar)) {
|
|
1519
|
-
range.setStart(globalRange.startContainer, startPos);
|
|
1520
|
-
range.setEnd(globalRange.startContainer, endPos); }
|
|
1521
|
-
else {
|
|
1522
|
-
if (globalRange.commonAncestorContainer.textContent.trim() !== '' && !isNullOrUndefined(globalRange.commonAncestorContainer.textContent.trim()) && this.getTextRange() && this.getTextRange().lastIndexOf(this.mentionChar) !== -1) {
|
|
1523
|
-
range.setStart(globalRange.startContainer, globalRange.startOffset - 1);
|
|
1524
|
-
range.setEnd(globalRange.startContainer, globalRange.endOffset - 1);
|
|
1525
|
-
}
|
|
1526
|
-
else {
|
|
1527
|
-
range.setStart(globalRange.startContainer, globalRange.startOffset);
|
|
1528
|
-
range.setEnd(globalRange.startContainer, globalRange.endOffset);
|
|
1529
|
-
}
|
|
1530
|
-
}
|
|
1531
|
-
this.isTyped = false;
|
|
1532
|
-
range.deleteContents();
|
|
1533
|
-
const element: HTMLElement = this.createElement('div');
|
|
1534
|
-
element.innerHTML = value;
|
|
1535
|
-
const frag: DocumentFragment = document.createDocumentFragment();
|
|
1536
|
-
let node: Node;
|
|
1537
|
-
let lastNode: Node;
|
|
1538
|
-
// eslint-disable-next-line no-cond-assign
|
|
1539
|
-
while (node = element.firstChild) {
|
|
1540
|
-
lastNode = frag.appendChild(node);
|
|
1541
|
-
}
|
|
1542
|
-
range.insertNode(frag);
|
|
1543
|
-
if (lastNode) {
|
|
1544
|
-
range = range.cloneRange();
|
|
1545
|
-
range.setStartAfter(lastNode);
|
|
1546
|
-
range.collapse(true);
|
|
1547
|
-
selection.removeAllRanges();
|
|
1548
|
-
selection.addRange(range);
|
|
1549
|
-
}
|
|
1550
|
-
if (this.isPopupOpen) { this.hidePopup(); }
|
|
1551
|
-
this.onChangeEvent(e);
|
|
1552
|
-
}
|
|
1553
|
-
}
|
|
1554
|
-
|
|
1555
|
-
private mentionVal(value: string): string {
|
|
1556
|
-
const showChar: string = this.showMentionChar ? this.mentionChar : '';
|
|
1557
|
-
if (!isNullOrUndefined(this.displayTemplate) && !isNullOrUndefined(this.displayTempElement)) {
|
|
1558
|
-
value = this.displayTempElement.innerHTML;
|
|
1559
|
-
}
|
|
1560
|
-
if (this.isContentEditable(this.inputElement)) {
|
|
1561
|
-
return '<span contenteditable="false" class="e-mention-chip">' + showChar + value + '</span>'.concat(typeof this.suffixText === 'string' ? this.suffixText : ' ');
|
|
1562
|
-
} else {
|
|
1563
|
-
return showChar + value;
|
|
1564
|
-
}
|
|
1565
|
-
}
|
|
1566
|
-
|
|
1567
|
-
private setDisplayTemplate(e?: KeyboardEventArgs | MouseEvent): void {
|
|
1568
|
-
let compiledString: Function;
|
|
1569
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1570
|
-
if ((this as any).isReact) {
|
|
1571
|
-
this.clearTemplate(['displayTemplate']);
|
|
1572
|
-
if (this.displayTempElement) {
|
|
1573
|
-
detach(this.displayTempElement);
|
|
1574
|
-
this.displayTempElement = null;
|
|
1575
|
-
}
|
|
1576
|
-
}
|
|
1577
|
-
if (!this.displayTempElement) {
|
|
1578
|
-
this.displayTempElement = this.createElement('div');
|
|
1579
|
-
}
|
|
1580
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1581
|
-
if (!(this as any).isReact) {
|
|
1582
|
-
this.displayTempElement.innerHTML = '';
|
|
1583
|
-
}
|
|
1584
|
-
compiledString = compile(this.displayTemplate);
|
|
1585
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1586
|
-
const displayCompTemp: any = compiledString(
|
|
1587
|
-
this.itemData, this, 'displayTemplate', this.displayTemplateId, this.isStringTemplate, null, this.displayTempElement);
|
|
1588
|
-
if (displayCompTemp && displayCompTemp.length > 0) {
|
|
1589
|
-
append(displayCompTemp, this.displayTempElement);
|
|
1590
|
-
}
|
|
1591
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1592
|
-
if (!(this as any).isReact) {
|
|
1593
|
-
this.renderTemplates();
|
|
1594
|
-
} else {
|
|
1595
|
-
this.renderTemplates(() => {
|
|
1596
|
-
this.updateMentionValue(e);
|
|
1597
|
-
});
|
|
1598
|
-
}
|
|
1599
|
-
}
|
|
1600
|
-
|
|
1601
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1602
|
-
private renderTemplates(callBack?: any): void {
|
|
1603
|
-
this.renderReactTemplates(callBack);
|
|
1604
|
-
}
|
|
1605
|
-
|
|
1606
|
-
private setSpinnerTemplate(): void {
|
|
1607
|
-
let compiledString: Function;
|
|
1608
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1609
|
-
if ((this as any).isReact) {
|
|
1610
|
-
this.clearTemplate(['spinnerTemplate']);
|
|
1611
|
-
if (this.spinnerTemplateElement) {
|
|
1612
|
-
detach(this.spinnerTemplateElement);
|
|
1613
|
-
this.spinnerTemplateElement = null;
|
|
1614
|
-
}
|
|
1615
|
-
}
|
|
1616
|
-
if (!this.spinnerTemplateElement) {
|
|
1617
|
-
this.spinnerTemplateElement = this.createElement('div');
|
|
1618
|
-
}
|
|
1619
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1620
|
-
if (!(this as any).isReact) {
|
|
1621
|
-
this.spinnerTemplateElement.innerHTML = '';
|
|
1622
|
-
}
|
|
1623
|
-
compiledString = compile(this.spinnerTemplate);
|
|
1624
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1625
|
-
const spinnerCompTemp: any = compiledString(
|
|
1626
|
-
null, this, 'spinnerTemplate', this.spinnerTemplateId, this.isStringTemplate, null, this.spinnerTemplateElement);
|
|
1627
|
-
if (spinnerCompTemp && spinnerCompTemp.length > 0) {
|
|
1628
|
-
for (let i: number = 0; i < spinnerCompTemp.length; i++) {
|
|
1629
|
-
this.spinnerTemplateElement.appendChild(spinnerCompTemp[i as number]);
|
|
1630
|
-
}
|
|
1631
|
-
}
|
|
1632
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1633
|
-
if (!(this as any).isReact) {
|
|
1634
|
-
this.renderTemplates();
|
|
1635
|
-
this.popupObj.element.appendChild(this.spinnerTemplateElement);
|
|
1636
|
-
}
|
|
1637
|
-
else {
|
|
1638
|
-
this.renderTemplates(() => {
|
|
1639
|
-
this.popupObj.element.appendChild(this.spinnerTemplateElement);
|
|
1640
|
-
});
|
|
1641
|
-
}
|
|
1642
|
-
}
|
|
1643
|
-
|
|
1644
|
-
private onChangeEvent(eve: MouseEvent | KeyboardEvent | TouchEvent): void {
|
|
1645
|
-
this.isSelected = false;
|
|
1646
|
-
const items: FieldSettingsModel = this.detachMentionChanges(this.itemData);
|
|
1647
|
-
let preItems: FieldSettingsModel;
|
|
1648
|
-
if (typeof this.previousItemData === 'string' ||
|
|
1649
|
-
typeof this.previousItemData === 'boolean' ||
|
|
1650
|
-
typeof this.previousItemData === 'number') {
|
|
1651
|
-
preItems = Object.defineProperties({}, {
|
|
1652
|
-
value: {
|
|
1653
|
-
value: this.previousItemData,
|
|
1654
|
-
enumerable: true
|
|
1655
|
-
},
|
|
1656
|
-
text: {
|
|
1657
|
-
value: this.previousItemData,
|
|
1658
|
-
enumerable: true
|
|
1659
|
-
}
|
|
1660
|
-
});
|
|
1661
|
-
} else {
|
|
1662
|
-
preItems = this.previousItemData;
|
|
1663
|
-
}
|
|
1664
|
-
const eventArgs: MentionChangeEventArgs = {
|
|
1665
|
-
e: eve,
|
|
1666
|
-
item: this.item,
|
|
1667
|
-
itemData: items,
|
|
1668
|
-
previousItem: this.previousSelectedLI as HTMLLIElement,
|
|
1669
|
-
previousItemData: preItems,
|
|
1670
|
-
isInteracted: eve ? true : false,
|
|
1671
|
-
value: this.item.innerHTML,
|
|
1672
|
-
element: this.inputElement
|
|
1673
|
-
};
|
|
1674
|
-
this.trigger('change', eventArgs);
|
|
1675
|
-
}
|
|
1676
|
-
|
|
1677
|
-
private detachMentionChanges(value: string | number | boolean | {
|
|
1678
|
-
[key: string]: Object
|
|
1679
|
-
}): FieldSettingsModel {
|
|
1680
|
-
let items: FieldSettingsModel;
|
|
1681
|
-
if (typeof value === 'string' ||
|
|
1682
|
-
typeof value === 'boolean' ||
|
|
1683
|
-
typeof value === 'number') {
|
|
1684
|
-
items = Object.defineProperties({}, {
|
|
1685
|
-
value: {
|
|
1686
|
-
value: value,
|
|
1687
|
-
enumerable: true
|
|
1688
|
-
},
|
|
1689
|
-
text: {
|
|
1690
|
-
value: value,
|
|
1691
|
-
enumerable: true
|
|
1692
|
-
}
|
|
1693
|
-
});
|
|
1694
|
-
} else {
|
|
1695
|
-
items = value;
|
|
1696
|
-
}
|
|
1697
|
-
return items;
|
|
1698
|
-
}
|
|
1699
|
-
|
|
1700
|
-
private getItemData(): { [key: string]: string } {
|
|
1701
|
-
const fields: FieldSettingsModel = this.fields;
|
|
1702
|
-
let dataItem: { [key: string]: string | Object } | string | boolean | number = null;
|
|
1703
|
-
dataItem = this.itemData;
|
|
1704
|
-
let dataValue: string;
|
|
1705
|
-
let dataText: string;
|
|
1706
|
-
if (!isNullOrUndefined(dataItem)) {
|
|
1707
|
-
dataValue = getValue(fields.value, dataItem);
|
|
1708
|
-
dataText = getValue(fields.text, dataItem);
|
|
1709
|
-
}
|
|
1710
|
-
const value: string = <string>(!isNullOrUndefined(dataItem) &&
|
|
1711
|
-
!isUndefined(dataValue) ? dataValue : dataItem);
|
|
1712
|
-
const text: string = <string>(!isNullOrUndefined(dataItem) &&
|
|
1713
|
-
!isUndefined(dataValue) ? dataText : dataItem);
|
|
1714
|
-
return { value: value, text: text };
|
|
1715
|
-
}
|
|
1716
|
-
|
|
1717
|
-
private removeSelection(): void {
|
|
1718
|
-
if (this.list) {
|
|
1719
|
-
const selectedItems: Element[] = <NodeListOf<Element> &
|
|
1720
|
-
Element[]>this.list.querySelectorAll('.' + dropDownBaseClasses.selected);
|
|
1721
|
-
if (selectedItems.length) {
|
|
1722
|
-
removeClass(selectedItems, dropDownBaseClasses.selected);
|
|
1723
|
-
selectedItems[0].removeAttribute('aria-selected');
|
|
1724
|
-
}
|
|
1725
|
-
}
|
|
1726
|
-
}
|
|
1727
|
-
|
|
1728
|
-
private onMouseOver(e: MouseEvent): void {
|
|
1729
|
-
const currentLi: HTMLElement = <HTMLElement>closest(<Element>e.target, '.' + dropDownBaseClasses.li);
|
|
1730
|
-
this.setHover(currentLi);
|
|
1731
|
-
}
|
|
1732
|
-
|
|
1733
|
-
private setHover(li: HTMLElement): void {
|
|
1734
|
-
if (this.isValidLI(li) && !li.classList.contains(dropDownBaseClasses.hover)) {
|
|
1735
|
-
this.removeHover();
|
|
1736
|
-
addClass([li], dropDownBaseClasses.hover);
|
|
1737
|
-
}
|
|
1738
|
-
}
|
|
1739
|
-
|
|
1740
|
-
private removeHover(): void {
|
|
1741
|
-
if (this.list) {
|
|
1742
|
-
const hoveredItem: Element[] = <NodeListOf<Element> & Element[]>this.list.querySelectorAll('.' + dropDownBaseClasses.hover);
|
|
1743
|
-
if (hoveredItem && hoveredItem.length) {
|
|
1744
|
-
removeClass(hoveredItem, dropDownBaseClasses.hover);
|
|
1745
|
-
}
|
|
1746
|
-
}
|
|
1747
|
-
}
|
|
1748
|
-
|
|
1749
|
-
private isValidLI(li: Element | HTMLElement): boolean {
|
|
1750
|
-
return (li && li.hasAttribute('role') && li.getAttribute('role') === 'option');
|
|
1751
|
-
}
|
|
1752
|
-
|
|
1753
|
-
private onMouseLeave(): void {
|
|
1754
|
-
this.removeHover();
|
|
1755
|
-
}
|
|
1756
|
-
|
|
1757
|
-
/**
|
|
1758
|
-
* Search the entered text and show it in the suggestion list if available.
|
|
1759
|
-
*
|
|
1760
|
-
* @returns {void}
|
|
1761
|
-
*/
|
|
1762
|
-
public search(text: string, positionX: number, positionY: number): void {
|
|
1763
|
-
if (this.isContentEditable(this.inputElement)) {
|
|
1764
|
-
this.range = this.getCurrentRange();
|
|
1765
|
-
}
|
|
1766
|
-
const currentRange: string = this.getTextRange();
|
|
1767
|
-
const lastWordRange: string = this.getLastLetter(currentRange);
|
|
1768
|
-
if ((this.ignoreCase && (text === lastWordRange || text === lastWordRange.toLowerCase()))
|
|
1769
|
-
|| !this.ignoreCase && text === lastWordRange) {
|
|
1770
|
-
this.resetList(this.dataSource, this.fields);
|
|
1771
|
-
} else {
|
|
1772
|
-
if (this.isPopupOpen) {
|
|
1773
|
-
this.hidePopup();
|
|
1774
|
-
}
|
|
1775
|
-
return;
|
|
1776
|
-
}
|
|
1777
|
-
if (isNullOrUndefined(this.list)) {
|
|
1778
|
-
this.renderList();
|
|
1779
|
-
this.renderPopup();
|
|
1780
|
-
}
|
|
1781
|
-
else {
|
|
1782
|
-
this.showPopup();
|
|
1783
|
-
}
|
|
1784
|
-
this.popupObj.element.style.left = formatUnit(positionX);
|
|
1785
|
-
this.popupObj.element.style.top = formatUnit(positionY);
|
|
1786
|
-
}
|
|
1787
|
-
|
|
1788
|
-
/**
|
|
1789
|
-
* Removes the component from the DOM and detaches all its related event handlers. Also it removes the attributes and classes.
|
|
1790
|
-
*
|
|
1791
|
-
* @method destroy
|
|
1792
|
-
* @returns {void}
|
|
1793
|
-
*/
|
|
1794
|
-
public destroy(): void {
|
|
1795
|
-
this.hidePopup();
|
|
1796
|
-
this.unWireEvent();
|
|
1797
|
-
if (this.list) {
|
|
1798
|
-
this.unWireListEvents();
|
|
1799
|
-
}
|
|
1800
|
-
if (this.inputElement && !this.inputElement.classList.contains('e-' + this.getModuleName())) {
|
|
1801
|
-
return;
|
|
1802
|
-
}
|
|
1803
|
-
this.previousSelectedLI = null;
|
|
1804
|
-
this.item = null;
|
|
1805
|
-
this.selectedLI = null;
|
|
1806
|
-
this.inputElement.innerText = null;
|
|
1807
|
-
this.popupObj = null;
|
|
1808
|
-
super.destroy();
|
|
1809
|
-
}
|
|
1810
|
-
|
|
1811
|
-
protected getLocaleName(): string {
|
|
1812
|
-
return 'mention';
|
|
1813
|
-
}
|
|
1814
|
-
|
|
1815
|
-
protected getNgDirective(): string {
|
|
1816
|
-
return 'EJS-MENTION';
|
|
1817
|
-
}
|
|
1818
|
-
|
|
1819
|
-
/**
|
|
1820
|
-
* Return the module name of this component.
|
|
1821
|
-
*
|
|
1822
|
-
* @private
|
|
1823
|
-
* @returns {string} Return the module name of this component.
|
|
1824
|
-
*/
|
|
1825
|
-
public getModuleName(): string {
|
|
1826
|
-
return 'mention';
|
|
1827
|
-
}
|
|
1828
|
-
}
|