@syncfusion/ej2-dropdowns 18.1.57 → 18.2.44-4569
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 +244 -0
- package/CHANGELOG.md +1524 -1514
- package/README.md +118 -118
- package/dist/ej2-dropdowns.umd.min.js +1 -10
- package/dist/ej2-dropdowns.umd.min.js.map +1 -1
- package/dist/es6/ej2-dropdowns.es2015.js +198 -126
- package/dist/es6/ej2-dropdowns.es2015.js.map +1 -1
- package/dist/es6/ej2-dropdowns.es5.js +290 -217
- package/dist/es6/ej2-dropdowns.es5.js.map +1 -1
- package/dist/global/ej2-dropdowns.min.js +1 -10
- package/dist/global/ej2-dropdowns.min.js.map +1 -1
- package/dist/global/index.d.ts +0 -9
- package/dist/ts/auto-complete/auto-complete.ts +527 -0
- package/dist/ts/combo-box/combo-box.ts +957 -0
- package/dist/ts/common/highlight-search.ts +47 -0
- package/dist/ts/common/incremental-search.ts +81 -0
- package/dist/ts/drop-down-base/drop-down-base.ts +1572 -0
- package/dist/ts/drop-down-list/drop-down-list.ts +2993 -0
- package/dist/ts/drop-down-tree/drop-down-tree.ts +3066 -0
- package/dist/ts/list-box/list-box.ts +2317 -0
- package/dist/ts/multi-select/checkbox-selection.ts +528 -0
- package/dist/ts/multi-select/float-label.ts +155 -0
- package/dist/ts/multi-select/interface.ts +66 -0
- package/dist/ts/multi-select/multi-select.ts +4216 -0
- package/helpers/e2e/index.js +3 -3
- package/license +2 -2
- package/package.json +77 -77
- package/src/auto-complete/auto-complete-model.d.ts +179 -179
- 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 +212 -212
- package/src/combo-box/combo-box.d.ts +27 -27
- package/src/combo-box/combo-box.js +29 -29
- package/src/common/incremental-search.d.ts +1 -1
- package/src/common/incremental-search.js +4 -2
- package/src/drop-down-base/drop-down-base-model.d.ts +191 -191
- package/src/drop-down-base/drop-down-base.d.ts +17 -17
- package/src/drop-down-base/drop-down-base.js +20 -20
- package/src/drop-down-list/drop-down-list-model.d.ts +222 -222
- package/src/drop-down-list/drop-down-list.d.ts +3 -2
- package/src/drop-down-list/drop-down-list.js +43 -30
- package/src/drop-down-tree/drop-down-tree-model.d.ts +344 -344
- package/src/drop-down-tree/drop-down-tree.js +32 -26
- package/src/list-box/index.d.ts +1 -0
- package/src/list-box/index.js +1 -0
- package/src/list-box/list-box-model.d.ts +156 -156
- package/src/list-box/list-box.d.ts +2 -2
- package/src/list-box/list-box.js +57 -59
- package/src/multi-select/index.d.ts +1 -0
- package/src/multi-select/index.js +1 -0
- package/src/multi-select/multi-select-model.d.ts +452 -452
- package/src/multi-select/multi-select.d.ts +2 -0
- package/src/multi-select/multi-select.js +98 -43
- package/styles/_all.scss +3 -3
- package/styles/auto-complete/_bootstrap-dark-definition.scss +3 -3
- package/styles/auto-complete/_bootstrap4-definition.scss +11 -11
- package/styles/auto-complete/_fabric-dark-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/bootstrap-dark.css +67 -61
- package/styles/bootstrap.css +69 -63
- package/styles/bootstrap4.css +81 -61
- package/styles/combo-box/_bootstrap-dark-definition.scss +2 -2
- package/styles/combo-box/_bootstrap4-definition.scss +11 -11
- package/styles/combo-box/_fabric-dark-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/drop-down-base/_all.scss +2 -2
- package/styles/drop-down-base/_bootstrap-dark-definition.scss +64 -64
- package/styles/drop-down-base/_bootstrap-definition.scss +64 -64
- package/styles/drop-down-base/_bootstrap4-definition.scss +78 -78
- package/styles/drop-down-base/_definition.scss +23 -23
- package/styles/drop-down-base/_fabric-dark-definition.scss +68 -68
- package/styles/drop-down-base/_fabric-definition.scss +66 -66
- package/styles/drop-down-base/_highcontrast-definition.scss +82 -82
- package/styles/drop-down-base/_highcontrast-light-definition.scss +81 -81
- package/styles/drop-down-base/_layout.scss +108 -108
- package/styles/drop-down-base/_material-dark-definition.scss +67 -67
- package/styles/drop-down-base/_material-definition.scss +65 -65
- package/styles/drop-down-base/_theme.scss +242 -242
- package/styles/drop-down-list/_all.scss +2 -2
- 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 +184 -184
- package/styles/drop-down-list/_fabric-dark-definition.scss +127 -127
- package/styles/drop-down-list/_fabric-definition.scss +122 -122
- package/styles/drop-down-list/_highcontrast-definition.scss +131 -131
- package/styles/drop-down-list/_highcontrast-light-definition.scss +133 -133
- package/styles/drop-down-list/_layout.scss +218 -218
- package/styles/drop-down-list/_material-dark-definition.scss +143 -143
- package/styles/drop-down-list/_material-definition.scss +166 -166
- 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/_fabric-dark.scss +14 -14
- package/styles/drop-down-list/icons/_fabric.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/material.css +9 -0
- package/styles/drop-down-tree/_all.scss +2 -2
- package/styles/drop-down-tree/_bootstrap-dark-definition.scss +62 -49
- package/styles/drop-down-tree/_bootstrap-definition.scss +62 -49
- package/styles/drop-down-tree/_bootstrap4-definition.scss +63 -50
- package/styles/drop-down-tree/_fabric-dark-definition.scss +63 -49
- package/styles/drop-down-tree/_fabric-definition.scss +63 -49
- package/styles/drop-down-tree/_highcontrast-definition.scss +63 -49
- package/styles/drop-down-tree/_highcontrast-light-definition.scss +63 -49
- package/styles/drop-down-tree/_layout.scss +437 -398
- package/styles/drop-down-tree/_material-dark-definition.scss +61 -54
- package/styles/drop-down-tree/_material-definition.scss +61 -54
- package/styles/drop-down-tree/_theme.scss +68 -63
- package/styles/drop-down-tree/bootstrap-dark.css +67 -61
- package/styles/drop-down-tree/bootstrap.css +69 -63
- package/styles/drop-down-tree/bootstrap4.css +81 -61
- package/styles/drop-down-tree/fabric-dark.css +71 -63
- package/styles/drop-down-tree/fabric.css +71 -63
- package/styles/drop-down-tree/highcontrast-light.css +71 -63
- package/styles/drop-down-tree/highcontrast.css +75 -63
- 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/_fabric-dark.scss +11 -11
- package/styles/drop-down-tree/icons/_fabric.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/material-dark.css +76 -85
- package/styles/drop-down-tree/material.css +93 -85
- package/styles/fabric-dark.css +71 -63
- package/styles/fabric.css +71 -63
- package/styles/highcontrast-light.css +71 -63
- package/styles/highcontrast.css +75 -63
- package/styles/list-box/_all.scss +2 -2
- package/styles/list-box/_bootstrap-dark-definition.scss +118 -118
- package/styles/list-box/_bootstrap-definition.scss +112 -112
- package/styles/list-box/_bootstrap4-definition.scss +118 -118
- package/styles/list-box/_fabric-dark-definition.scss +118 -118
- package/styles/list-box/_fabric-definition.scss +112 -112
- package/styles/list-box/_highcontrast-definition.scss +112 -112
- package/styles/list-box/_highcontrast-light-definition.scss +118 -118
- package/styles/list-box/_layout.scss +458 -458
- package/styles/list-box/_material-dark-definition.scss +118 -118
- package/styles/list-box/_material-definition.scss +112 -112
- package/styles/list-box/_theme.scss +273 -273
- 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/_fabric-dark.scss +25 -25
- package/styles/list-box/icons/_fabric.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/material-dark.css +4 -4
- package/styles/list-box/material.css +4 -4
- package/styles/material-dark.css +80 -89
- package/styles/material.css +115 -89
- package/styles/multi-select/_all.scss +2 -2
- package/styles/multi-select/_bootstrap-dark-definition.scss +171 -171
- package/styles/multi-select/_bootstrap-definition.scss +166 -166
- package/styles/multi-select/_bootstrap4-definition.scss +233 -233
- package/styles/multi-select/_fabric-dark-definition.scss +170 -170
- package/styles/multi-select/_fabric-definition.scss +167 -167
- package/styles/multi-select/_highcontrast-definition.scss +257 -257
- package/styles/multi-select/_highcontrast-light-definition.scss +258 -258
- package/styles/multi-select/_layout.scss +1153 -1153
- package/styles/multi-select/_material-dark-definition.scss +186 -186
- package/styles/multi-select/_material-definition.scss +191 -191
- package/styles/multi-select/_theme.scss +384 -384
- 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/_fabric-dark.scss +26 -26
- package/styles/multi-select/icons/_fabric.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 +26 -26
- package/styles/multi-select/icons/_material.scss +324 -324
- package/styles/multi-select/material.css +9 -0
|
@@ -0,0 +1,3066 @@
|
|
|
1
|
+
import { Input, InputObject, FloatLabelType, TextBox, InputEventArgs } from '@syncfusion/ej2-inputs';
|
|
2
|
+
import { createCheckBox } from '@syncfusion/ej2-buttons';
|
|
3
|
+
import { NotifyPropertyChanges, INotifyPropertyChanged, Property, Event, EmitType } from '@syncfusion/ej2-base';
|
|
4
|
+
import { Component, EventHandler, attributes, formatUnit, ChildProperty, remove, L10n, extend } from '@syncfusion/ej2-base';
|
|
5
|
+
import { addClass, removeClass, detach, prepend, Complex, closest, setValue, getValue, compile, append } from '@syncfusion/ej2-base';
|
|
6
|
+
import { select, selectAll, isNullOrUndefined as isNOU, matches, Browser, KeyboardEvents, KeyboardEventArgs } from '@syncfusion/ej2-base';
|
|
7
|
+
import { DataManager, Query, DataUtil } from '@syncfusion/ej2-data';
|
|
8
|
+
import { Popup } from '@syncfusion/ej2-popups';
|
|
9
|
+
import { updateBlazorTemplate, resetBlazorTemplate, isBlazor} from '@syncfusion/ej2-base';
|
|
10
|
+
import { TreeView, NodeSelectEventArgs, DataBoundEventArgs, FieldsSettingsModel, NodeClickEventArgs } from '@syncfusion/ej2-navigations';
|
|
11
|
+
import { NodeCheckEventArgs, FailureEventArgs} from '@syncfusion/ej2-navigations';
|
|
12
|
+
import { DropDownTreeModel, FieldsModel, TreeSettingsModel } from './drop-down-tree-model';
|
|
13
|
+
|
|
14
|
+
const RTL: string = 'e-rtl';
|
|
15
|
+
const DROPDOWNTREE: string = 'e-ddt';
|
|
16
|
+
const HIDDENELEMENT: string = 'e-ddt-hidden';
|
|
17
|
+
const DROPDOWNICON: string = 'e-input-group-icon e-ddt-icon e-icons';
|
|
18
|
+
const SHOW_CHIP: string = 'e-show-chip';
|
|
19
|
+
const SHOW_CLEAR: string = 'e-show-clear';
|
|
20
|
+
const SHOW_DD_ICON: string = 'e-show-dd-icon';
|
|
21
|
+
const CHIP_INPUT: string = 'e-chip-input';
|
|
22
|
+
const INPUTFOCUS: string = 'e-input-focus';
|
|
23
|
+
const INPUTGROUP: string = 'e-input-group';
|
|
24
|
+
const ICONANIMATION: string = 'e-icon-anim';
|
|
25
|
+
const CLOSEICON_CLASS: string = 'e-clear-icon e-icons';
|
|
26
|
+
const CHIP_WRAPPER: string = 'e-chips-wrapper';
|
|
27
|
+
const CHIP_COLLECTION: string = 'e-chips-collection';
|
|
28
|
+
const CHIP: string = 'e-chips';
|
|
29
|
+
const CHIP_CONTENT: string = 'e-chipcontent';
|
|
30
|
+
const CHIP_CLOSE: string = 'e-chips-close';
|
|
31
|
+
const HIDEICON: string = 'e-icon-hide';
|
|
32
|
+
const POPUP_CLASS: string = 'e-ddt e-popup';
|
|
33
|
+
const PARENTITEM: string = 'e-list-parent';
|
|
34
|
+
const CONTENT: string = 'e-popup-content';
|
|
35
|
+
const DROPDOWN: string = 'e-dropdown';
|
|
36
|
+
const DISABLED: string = 'e-disabled';
|
|
37
|
+
const ICONS: string = 'e-icons';
|
|
38
|
+
const CHECKALLPARENT: string = 'e-selectall-parent';
|
|
39
|
+
const CHECKALLHIDE: string = 'e-hide-selectall';
|
|
40
|
+
const BIGGER: string = 'e-bigger';
|
|
41
|
+
const SMALL: string = 'e-small';
|
|
42
|
+
const ALLTEXT: string = 'e-all-text';
|
|
43
|
+
const CHECKBOXFRAME: string = 'e-frame';
|
|
44
|
+
const CHECK: string = 'e-check';
|
|
45
|
+
const CHECKBOXWRAP: string = 'e-checkbox-wrapper';
|
|
46
|
+
const FILTERWRAP: string = 'e-filter-wrap';
|
|
47
|
+
const DDTICON: string = 'e-ddt-icon';
|
|
48
|
+
const FOOTER: string = 'e-ddt-footer';
|
|
49
|
+
const HEADER: string = 'e-ddt-header';
|
|
50
|
+
const NODATACONTAINER: string = 'e-ddt-nodata';
|
|
51
|
+
const NODATA: string = 'e-no-data';
|
|
52
|
+
const HEADERTEMPLATE: string = 'HeaderTemplate';
|
|
53
|
+
const FOOTERTEMPLATE: string = 'FooterTemplate';
|
|
54
|
+
const NORECORDSTEMPLATE: string = 'NoRecordsTemplate';
|
|
55
|
+
const ACTIONFAILURETEMPLATE: string = 'ActionFailureTemplate';
|
|
56
|
+
|
|
57
|
+
export type TreeFilterType = 'StartsWith' | 'EndsWith' | 'Contains';
|
|
58
|
+
|
|
59
|
+
export class Fields extends ChildProperty<Fields> {
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* This field specifies the child items or mapping field for the nested child items that contains an array of JSON objects.
|
|
63
|
+
*/
|
|
64
|
+
@Property('child')
|
|
65
|
+
public child: string | FieldsModel;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Specifies the array of JavaScript objects or instance of Data Manager to populate the dropdown tree items.
|
|
69
|
+
* @default []
|
|
70
|
+
*/
|
|
71
|
+
@Property([])
|
|
72
|
+
public dataSource: DataManager | { [key: string]: Object }[];
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* This fields specifies the mapping field to define the expanded state of a Dropdown tree item.
|
|
76
|
+
*/
|
|
77
|
+
@Property('expanded')
|
|
78
|
+
public expanded: string;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* This field specifies the mapping field to indicate whether the Dropdown tree item has children or not.
|
|
82
|
+
*/
|
|
83
|
+
@Property('hasChildren')
|
|
84
|
+
public hasChildren: string;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Specifies the mapping field for htmlAttributes to be added to the Dropdown Tree item.
|
|
88
|
+
*/
|
|
89
|
+
@Property('htmlAttributes')
|
|
90
|
+
public htmlAttributes: string;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Specifies the mapping field for icon class of each Dropdown Tree item that will be added before the text.
|
|
94
|
+
*/
|
|
95
|
+
@Property('iconCss')
|
|
96
|
+
public iconCss: string;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Specifies the mapping field for image URL of each Dropdown Tree item where image will be added before the text.
|
|
100
|
+
*/
|
|
101
|
+
@Property('imageUrl')
|
|
102
|
+
public imageUrl: string;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Specifies the parent value field mapped in the data source.
|
|
106
|
+
*/
|
|
107
|
+
@Property('parentValue')
|
|
108
|
+
public parentValue: string;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Defines the external [`Query`](http://ej2.syncfusion.com/documentation/data/api-query.html)
|
|
112
|
+
* that will execute along with the data processing.
|
|
113
|
+
* @default null
|
|
114
|
+
*/
|
|
115
|
+
@Property(null)
|
|
116
|
+
public query: Query;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Specifies the mapping field for the selected state of the Dropdown Tree item.
|
|
120
|
+
*/
|
|
121
|
+
@Property('selected')
|
|
122
|
+
public selected: string;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Specifies the table name used to fetch data from a specific table in the server.
|
|
126
|
+
*/
|
|
127
|
+
@Property(null)
|
|
128
|
+
public tableName: string;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Specifies the mapping field for text displayed as Dropdown Tree items display text.
|
|
132
|
+
*/
|
|
133
|
+
@Property('text')
|
|
134
|
+
public text: string;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Specifies the mapping field for tooltip that will be displayed as hovering text of the Dropdown Tree item.
|
|
138
|
+
*/
|
|
139
|
+
@Property('tooltip')
|
|
140
|
+
public tooltip: string;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Specifies the value(ID) field mapped in the data source.
|
|
144
|
+
*/
|
|
145
|
+
@Property('value')
|
|
146
|
+
public value: string;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export class TreeSettings extends ChildProperty<TreeSettings> {
|
|
150
|
+
/**
|
|
151
|
+
* Specifies whether the child and parent tree items check states are dependent over each other when checkboxes are enabled.
|
|
152
|
+
* @default false
|
|
153
|
+
*/
|
|
154
|
+
|
|
155
|
+
@Property(false)
|
|
156
|
+
public autoCheck: boolean;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Specifies the action on which the parent items in the pop-up should expand or collapse. The available actions are
|
|
160
|
+
* * `Auto` - In desktop, the expand or collapse operation happens when you double-click the node,
|
|
161
|
+
* and in mobile devices it happens on single-tap.
|
|
162
|
+
* * `Click` - The expand or collapse operation happens when you perform single-click/tap
|
|
163
|
+
* on the pop-up item in both desktop and mobile devices.
|
|
164
|
+
* * `DblClick` - The expand or collapse operation happens when you perform a double-click/tap
|
|
165
|
+
* on the pop-up item in both desktop and mobile devices.
|
|
166
|
+
* * `None` - The expand or collapse operation will not happen when you perform single-click/tap
|
|
167
|
+
* or double-click/tap on the pop-up items in both desktop and mobile devices.
|
|
168
|
+
* @default 'Auto'
|
|
169
|
+
*/
|
|
170
|
+
@Property('Auto')
|
|
171
|
+
public expandOn: ExpandOn;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* By default, the load on demand (Lazy load) is set to false.
|
|
175
|
+
* Enabling this property will render only the parent tree items in the popup and
|
|
176
|
+
* the child items will be rendered on demand when expanding the corresponding parent node.
|
|
177
|
+
* @default false
|
|
178
|
+
*/
|
|
179
|
+
@Property(false)
|
|
180
|
+
public loadOnDemand: boolean;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export interface DdtChangeEventArgs {
|
|
184
|
+
/**
|
|
185
|
+
* If the event is triggered by interaction, it returns true. Otherwise, it returns false.
|
|
186
|
+
*/
|
|
187
|
+
isInteracted: boolean;
|
|
188
|
+
/**
|
|
189
|
+
* Returns the component previous values.
|
|
190
|
+
*/
|
|
191
|
+
oldValue: string[];
|
|
192
|
+
/**
|
|
193
|
+
* Returns the updated component values.
|
|
194
|
+
*/
|
|
195
|
+
value: string[];
|
|
196
|
+
/**
|
|
197
|
+
* Specifies the original event.
|
|
198
|
+
*/
|
|
199
|
+
e: MouseEvent | KeyboardEvent;
|
|
200
|
+
/**
|
|
201
|
+
* Returns the root element of the component.
|
|
202
|
+
*/
|
|
203
|
+
element: HTMLElement;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export interface DdtBeforeOpenEventArgs {
|
|
207
|
+
/**
|
|
208
|
+
* Determines whether the current action needs to be prevented or not.
|
|
209
|
+
*/
|
|
210
|
+
cancel: boolean;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export interface DdtPopupEventArgs {
|
|
214
|
+
/**
|
|
215
|
+
* Specifies the pop-up object.
|
|
216
|
+
*/
|
|
217
|
+
popup: Popup;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export interface DdtDataBoundEventArgs {
|
|
221
|
+
/**
|
|
222
|
+
* Return the DropDownTree data.
|
|
223
|
+
*/
|
|
224
|
+
data: { [key: string]: Object }[];
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
export interface DdtFocusEventArgs {
|
|
229
|
+
/**
|
|
230
|
+
* Specifies whether the element is interacted when focusing or not.
|
|
231
|
+
*/
|
|
232
|
+
isInteracted?: boolean;
|
|
233
|
+
/**
|
|
234
|
+
* Specifies the original event.
|
|
235
|
+
*/
|
|
236
|
+
event?: MouseEvent | FocusEvent | TouchEvent | KeyboardEvent;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export interface DdtFilteringEventArgs {
|
|
240
|
+
/**
|
|
241
|
+
* To prevent the internal filtering action.
|
|
242
|
+
*/
|
|
243
|
+
preventDefaultAction: boolean;
|
|
244
|
+
/**
|
|
245
|
+
* Gets the `input` event arguments.
|
|
246
|
+
*/
|
|
247
|
+
event: Event;
|
|
248
|
+
/**
|
|
249
|
+
* Determines whether the current action needs to be prevented or not.
|
|
250
|
+
*/
|
|
251
|
+
cancel: boolean;
|
|
252
|
+
/**
|
|
253
|
+
* Filter text value.
|
|
254
|
+
*/
|
|
255
|
+
text: string;
|
|
256
|
+
/**
|
|
257
|
+
* Gets or sets the fields of Dropdown Tree.
|
|
258
|
+
*/
|
|
259
|
+
fields: FieldsModel;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export interface DdtSelectEventArgs {
|
|
263
|
+
/**
|
|
264
|
+
* Returns the name of action like select or unselect.
|
|
265
|
+
*/
|
|
266
|
+
action: string;
|
|
267
|
+
/**
|
|
268
|
+
* If the event is triggered by interacting the Dropdown Tree, it returns true. Otherwise, it returns false.
|
|
269
|
+
*/
|
|
270
|
+
isInteracted: boolean;
|
|
271
|
+
/**
|
|
272
|
+
* Returns the currently selected Dropdown item.
|
|
273
|
+
*/
|
|
274
|
+
item: HTMLLIElement;
|
|
275
|
+
/**
|
|
276
|
+
* Return the currently selected item as JSON object from the data source.
|
|
277
|
+
*/
|
|
278
|
+
itemData: { [key: string]: Object };
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export interface DdtKeyPressEventArgs {
|
|
282
|
+
/**
|
|
283
|
+
* If you want to cancel this event then, set cancel as true. Otherwise, false.
|
|
284
|
+
*/
|
|
285
|
+
cancel: boolean;
|
|
286
|
+
/**
|
|
287
|
+
* Return the actual event.
|
|
288
|
+
*/
|
|
289
|
+
event: KeyboardEventArgs;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export type Mode = 'Default' | 'Delimiter' | 'Box';
|
|
293
|
+
|
|
294
|
+
export type SortOrder = 'None' | 'Ascending' | 'Descending';
|
|
295
|
+
|
|
296
|
+
export type ExpandOn = 'Auto' | 'Click' | 'DblClick' | 'None';
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* The Dropdown Tree control allows you to select single or multiple values from hierarchical data in a tree-like structure.
|
|
300
|
+
* It has several out-of-the-box features, such as data binding, check boxes, templates, filter,
|
|
301
|
+
* UI customization, accessibility, and preselected values.
|
|
302
|
+
* ```html
|
|
303
|
+
* <input type="text" id="tree"></input>
|
|
304
|
+
* ```
|
|
305
|
+
* ```typescript
|
|
306
|
+
* let ddtObj: DropDownTree = new DropDownTree();
|
|
307
|
+
* ddtObj.appendTo("#tree");
|
|
308
|
+
* ```
|
|
309
|
+
*/
|
|
310
|
+
|
|
311
|
+
@NotifyPropertyChanges
|
|
312
|
+
export class DropDownTree extends Component<HTMLElement> implements INotifyPropertyChanged {
|
|
313
|
+
private inputEle: HTMLInputElement;
|
|
314
|
+
private inputObj: InputObject;
|
|
315
|
+
private hiddenElement: HTMLSelectElement;
|
|
316
|
+
private isReverseUpdate: boolean;
|
|
317
|
+
private checkSelectAll: boolean;
|
|
318
|
+
private inputWrapper: HTMLElement;
|
|
319
|
+
private popupDiv: HTMLElement;
|
|
320
|
+
private tree: HTMLElement;
|
|
321
|
+
private isPopupOpen: boolean;
|
|
322
|
+
private inputFocus: boolean;
|
|
323
|
+
private popupObj: Popup;
|
|
324
|
+
private treeObj: TreeView;
|
|
325
|
+
private overAllClear: HTMLElement;
|
|
326
|
+
private isClearButtonClick: boolean;
|
|
327
|
+
private isDocumentClick: boolean;
|
|
328
|
+
private isFirstRender: boolean;
|
|
329
|
+
private isInitialized: boolean;
|
|
330
|
+
private treeDataType: number;
|
|
331
|
+
private oldValue: string[];
|
|
332
|
+
private removeValue: boolean;
|
|
333
|
+
private currentValue: string[];
|
|
334
|
+
private currentText: string;
|
|
335
|
+
private treeItems: { [key: string]: Object }[];
|
|
336
|
+
private filterTimer: number = null;
|
|
337
|
+
private filterContainer: HTMLElement;
|
|
338
|
+
private isRemoteData: boolean;
|
|
339
|
+
private selectedText: string[];
|
|
340
|
+
private chipWrapper: HTMLElement;
|
|
341
|
+
private chipCollection: HTMLElement;
|
|
342
|
+
private isChipDelete: boolean;
|
|
343
|
+
private checkAllParent: HTMLElement;
|
|
344
|
+
private selectAllSpan: HTMLElement;
|
|
345
|
+
private checkBoxElement: Element;
|
|
346
|
+
private checkWrapper: HTMLElement;
|
|
347
|
+
private isNodeSelected: boolean;
|
|
348
|
+
private dataValue: string;
|
|
349
|
+
private popupEle: HTMLElement;
|
|
350
|
+
private isDynamicChange: boolean;
|
|
351
|
+
private header: HTMLElement;
|
|
352
|
+
private footer: HTMLElement;
|
|
353
|
+
private noRecord: HTMLElement;
|
|
354
|
+
private headerTemplateId: string;
|
|
355
|
+
private footerTemplateId: string;
|
|
356
|
+
private l10n: L10n;
|
|
357
|
+
private actionFailureTemplateId: string;
|
|
358
|
+
private noRecordsTemplateId: string;
|
|
359
|
+
private isValueChange: boolean;
|
|
360
|
+
private keyEventArgs: KeyboardEvent;
|
|
361
|
+
private keyboardModule: KeyboardEvents;
|
|
362
|
+
private keyConfigs: { [key: string]: string };
|
|
363
|
+
private isBlazorPlatForm: boolean;
|
|
364
|
+
|
|
365
|
+
private isFilteredData: boolean = false;
|
|
366
|
+
private isFilterRestore: boolean = false;
|
|
367
|
+
private treeData: { [key: string]: Object }[];
|
|
368
|
+
private selectedData: { [key: string]: Object }[] = [];
|
|
369
|
+
private filterObj: TextBox;
|
|
370
|
+
private filterDelayTime: number = 300;
|
|
371
|
+
private nestedTableUpdate: { flag: boolean, fields: FieldsModel };
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Specifies the template that renders to the popup list content of the
|
|
375
|
+
* Dropdown Tree component when the data fetch request from the remote server fails.
|
|
376
|
+
* @default 'The Request Failed'
|
|
377
|
+
*/
|
|
378
|
+
@Property('The Request Failed')
|
|
379
|
+
public actionFailureTemplate: string;
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* When allowFiltering is set to true, it shows the filter bar (search text box) of the component.
|
|
383
|
+
* The filter action retrieves matched items through the **filtering** event based on the characters typed in the search text box.
|
|
384
|
+
* If no match is found, the value of the **noRecordsTemplate** property will be displayed.
|
|
385
|
+
*
|
|
386
|
+
* @default false
|
|
387
|
+
*/
|
|
388
|
+
@Property(false)
|
|
389
|
+
public allowFiltering: boolean;
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Enables or disables the multi-selection of items. To select multiple items:
|
|
393
|
+
* * Select the items by holding down the **CTRL** key when clicking on the items.
|
|
394
|
+
* * Select consecutive items by clicking the first item to select and hold down the **SHIFT** key and click the last item to select.
|
|
395
|
+
*
|
|
396
|
+
* @default false
|
|
397
|
+
*/
|
|
398
|
+
@Property(false)
|
|
399
|
+
public allowMultiSelection: boolean;
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* By default, the Dropdown Tree component fires the change event while focusing out the component.
|
|
403
|
+
* If you want to fire the change event on every value selection and remove, then disable this property.
|
|
404
|
+
*
|
|
405
|
+
* @default true
|
|
406
|
+
*/
|
|
407
|
+
@Property(true)
|
|
408
|
+
public changeOnBlur: boolean;
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Specifies the CSS classes to be added with the root and popup element of the Dropdown Tree component.
|
|
412
|
+
* that allows customization of appearance.
|
|
413
|
+
* @default ''
|
|
414
|
+
*/
|
|
415
|
+
@Property('')
|
|
416
|
+
public cssClass: string;
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Defines the value separator character in the input element when multi-selection or checkbox is enabled in the Dropdown Tree.
|
|
420
|
+
* The delimiter character is applicable only for **default** and **delimiter** visibility modes.
|
|
421
|
+
* @default ","
|
|
422
|
+
*/
|
|
423
|
+
@Property(',')
|
|
424
|
+
public delimiterChar: string;
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Specifies a value that indicates whether the Dropdown Tree component is enabled or not.
|
|
428
|
+
* @default true
|
|
429
|
+
*/
|
|
430
|
+
@Property(true)
|
|
431
|
+
public enabled: boolean;
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Specifies the data source and mapping fields to render Dropdown Tree items.
|
|
435
|
+
* @default {value: 'value', text: 'text', dataSource: [], child: 'child', parentValue: 'parentValue', hasChildren: 'hasChildren',
|
|
436
|
+
* expanded: 'expanded', htmlAttributes: 'htmlAttributes', iconCss: 'iconCss', imageUrl: 'imageUrl',
|
|
437
|
+
* query: null, selected: 'selected', tableName: null, tooltip: 'tooltip'}
|
|
438
|
+
*/
|
|
439
|
+
@Complex<FieldsModel>({}, Fields)
|
|
440
|
+
public fields: FieldsModel;
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Accepts the value to be displayed as a watermark text on the filter bar.
|
|
444
|
+
* @default null
|
|
445
|
+
*/
|
|
446
|
+
@Property(null)
|
|
447
|
+
public filterBarPlaceholder: string;
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Determines on which filter type, the component needs to be considered on search action.
|
|
451
|
+
* The **TreeFilterType** and its supported data types are,
|
|
452
|
+
*
|
|
453
|
+
* <table>
|
|
454
|
+
* <tr>
|
|
455
|
+
* <td colSpan=1 rowSpan=1><b>
|
|
456
|
+
* TreeFilterType</b></td><td colSpan=1 rowSpan=1><b>
|
|
457
|
+
* Description</b></td><td colSpan=1 rowSpan=1><b>
|
|
458
|
+
* Supported Types</b></td></tr>
|
|
459
|
+
* <tr>
|
|
460
|
+
* <td colSpan=1 rowSpan=1>
|
|
461
|
+
* StartsWith<br/></td><td colSpan=1 rowSpan=1>
|
|
462
|
+
* Checks whether a value begins with the specified value.<br/></td><td colSpan=1 rowSpan=1>
|
|
463
|
+
* String<br/></td></tr>
|
|
464
|
+
* <tr>
|
|
465
|
+
* <td colSpan=1 rowSpan=1>
|
|
466
|
+
* EndsWith<br/></td><td colSpan=1 rowSpan=1>
|
|
467
|
+
* Checks whether a value ends with the specified value.<br/></td><td colSpan=1 rowSpan=1>
|
|
468
|
+
* String<br/></td></tr>
|
|
469
|
+
* <tr>
|
|
470
|
+
* <td colSpan=1 rowSpan=1>
|
|
471
|
+
* Contains<br/></td><td colSpan=1 rowSpan=1>
|
|
472
|
+
* Checks whether a value contains with specified value.<br/></td><td colSpan=1 rowSpan=1>
|
|
473
|
+
* String<br/></td></tr>
|
|
474
|
+
* </table>
|
|
475
|
+
*
|
|
476
|
+
* The default value set to **StartsWith**, all the suggestion items which starts with typed characters to listed in the
|
|
477
|
+
* suggestion popup.
|
|
478
|
+
* @default 'StartsWith'
|
|
479
|
+
*/
|
|
480
|
+
@Property('StartsWith')
|
|
481
|
+
public filterType: TreeFilterType;
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Specifies whether to display the floating label above the input element.
|
|
485
|
+
* Possible values are:
|
|
486
|
+
* * Never: The label will never float in the input when the placeholder is available.
|
|
487
|
+
* * Always: The floating label will always float above the input.
|
|
488
|
+
* * Auto: The floating label will float above the input after focusing or entering a value in the input.
|
|
489
|
+
* @default Syncfusion.EJ2.Inputs.FloatLabelType.Never
|
|
490
|
+
* @isEnumeration true
|
|
491
|
+
*/
|
|
492
|
+
@Property('Never')
|
|
493
|
+
public floatLabelType: FloatLabelType;
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Specifies the template that renders a customized footer container at the bottom of the pop-up list.
|
|
497
|
+
* By default, the footerTemplate will be null and there will be no footer container for the pop-up list.
|
|
498
|
+
* @default null
|
|
499
|
+
*/
|
|
500
|
+
@Property(null)
|
|
501
|
+
public footerTemplate: string;
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* When **ignoreAccent** is set to true, then it ignores the diacritic characters or accents when filtering.
|
|
505
|
+
*/
|
|
506
|
+
@Property(false)
|
|
507
|
+
public ignoreAccent: boolean;
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* When set to false, consider the case-sensitive on performing the search to find suggestions. By default, consider the casing.
|
|
511
|
+
* @default true
|
|
512
|
+
*/
|
|
513
|
+
@Property(true)
|
|
514
|
+
public ignoreCase: boolean;
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Specifies the template that renders a customized header container at the top of the pop-up list.
|
|
518
|
+
* By default, the headerTemplate will be null and there will be no header container for the pop-up list.
|
|
519
|
+
* @default null
|
|
520
|
+
*/
|
|
521
|
+
@Property(null)
|
|
522
|
+
public headerTemplate: string;
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Allows additional HTML attributes such as title, name, etc., and accepts n number of attributes in a key-value pair format.
|
|
526
|
+
* @default {}
|
|
527
|
+
*/
|
|
528
|
+
@Property({})
|
|
529
|
+
public htmlAttributes: { [key: string]: string; };
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Specifies a template to render customized content for all the items.
|
|
533
|
+
* If the **itemTemplate** property is set, the template content overrides the displayed item text.
|
|
534
|
+
* The property accepts [template string](http://ej2.syncfusion.com/documentation/base/template-engine.html)
|
|
535
|
+
* or HTML element ID holding the content.
|
|
536
|
+
* @default null
|
|
537
|
+
*/
|
|
538
|
+
@Property(null)
|
|
539
|
+
public itemTemplate: string;
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Configures visibility mode for component interaction when allowMultiSelection or checkbox is enabled.
|
|
543
|
+
* Different modes are:
|
|
544
|
+
* * Box : Selected items will be visualized in chip.
|
|
545
|
+
* * Delimiter : Selected items will be visualized in the text content.
|
|
546
|
+
* * Default : On focus in component will act in the box mode. On blur component will act in the delimiter mode.
|
|
547
|
+
*/
|
|
548
|
+
@Property('Default')
|
|
549
|
+
public mode: Mode;
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Specifies the template that renders a customized pop-up list content when there is no data available
|
|
553
|
+
* to be displayed within the pop-up.
|
|
554
|
+
* @default 'No Records Found'
|
|
555
|
+
*/
|
|
556
|
+
@Property('No Records Found')
|
|
557
|
+
public noRecordsTemplate: string;
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* Specifies a short hint that describes the expected value of the Dropdown Tree component.
|
|
561
|
+
* @default null
|
|
562
|
+
*/
|
|
563
|
+
@Property(null)
|
|
564
|
+
public placeholder: string;
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Specifies the height of the pop-up list.
|
|
568
|
+
* @default '300px'
|
|
569
|
+
*/
|
|
570
|
+
@Property('300px')
|
|
571
|
+
public popupHeight: string | number;
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* Specifies the width of the popup list. By default, the popup width sets based on the width of the Dropdown Tree element.
|
|
575
|
+
* @default '100%'
|
|
576
|
+
*/
|
|
577
|
+
@Property('100%')
|
|
578
|
+
public popupWidth: string | number;
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* When set to true, the user interactions on the component will be disabled.
|
|
582
|
+
* @default false
|
|
583
|
+
*/
|
|
584
|
+
@Property(false)
|
|
585
|
+
public readonly: boolean;
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Specifies whether to show or hide the selectAll checkbox in the pop-up which allows you to select all the items in the pop-up.
|
|
589
|
+
* @default false
|
|
590
|
+
*/
|
|
591
|
+
@Property(false)
|
|
592
|
+
public showSelectAll: boolean;
|
|
593
|
+
/**
|
|
594
|
+
* Specifies the display text for the selectAll checkbox in the pop-up.
|
|
595
|
+
* @default 'Select All'
|
|
596
|
+
*/
|
|
597
|
+
@Property('Select All')
|
|
598
|
+
public selectAllText: string;
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Enables or disables the checkbox option in the Dropdown Tree component.
|
|
602
|
+
* If enabled, the Checkbox will be displayed next to the expand or collapse icon of the tree items.
|
|
603
|
+
* @default false
|
|
604
|
+
*/
|
|
605
|
+
@Property(false)
|
|
606
|
+
public showCheckBox: boolean;
|
|
607
|
+
|
|
608
|
+
/**
|
|
609
|
+
* Specifies whether to show or hide the clear icon in textbox.
|
|
610
|
+
* When the clear button is clicked, `value`, `text` properties will be reset to null.
|
|
611
|
+
* @default true
|
|
612
|
+
*/
|
|
613
|
+
@Property(true)
|
|
614
|
+
public showClearButton: boolean;
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Specifies whether to show or hide the Dropdown button.
|
|
618
|
+
*
|
|
619
|
+
* @default true
|
|
620
|
+
*/
|
|
621
|
+
@Property(true)
|
|
622
|
+
public showDropDownIcon: boolean;
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* Specifies a value that indicates whether the items are sorted in the ascending or descending order, or not sorted at all.
|
|
626
|
+
* The available types of sort order are,
|
|
627
|
+
* * `None` - The items are not sorted.
|
|
628
|
+
* * `Ascending` - The items are sorted in the ascending order.
|
|
629
|
+
* * `Descending` - The items are sorted in the descending order.
|
|
630
|
+
* @default 'None'
|
|
631
|
+
*/
|
|
632
|
+
@Property('None')
|
|
633
|
+
public sortOrder: SortOrder;
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* Gets or sets the display text of the selected item which maps the data **text** field in the component.
|
|
638
|
+
* @default null
|
|
639
|
+
*/
|
|
640
|
+
@Property(null)
|
|
641
|
+
public text: string;
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Configures the pop-up tree settings.
|
|
645
|
+
* @default {autoCheck: false, loadOnDemand: true}
|
|
646
|
+
*/
|
|
647
|
+
@Complex<TreeSettingsModel>({}, TreeSettings)
|
|
648
|
+
public treeSettings: TreeSettingsModel;
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Specifies the display text for the unselect all checkbox in the pop-up.
|
|
652
|
+
* @default 'Unselect All'
|
|
653
|
+
*/
|
|
654
|
+
@Property('Unselect All')
|
|
655
|
+
public unSelectAllText: string;
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Gets or sets the value of selected item(s) which maps the data **value** field in the component.
|
|
659
|
+
* @default null
|
|
660
|
+
* @aspType Object
|
|
661
|
+
*/
|
|
662
|
+
@Property(null)
|
|
663
|
+
public value: string[];
|
|
664
|
+
/**
|
|
665
|
+
* Specifies the width of the component. By default, the component width sets based on the width of its parent container.
|
|
666
|
+
* You can also set the width in pixel values.
|
|
667
|
+
* @default '100%'
|
|
668
|
+
*/
|
|
669
|
+
@Property('100%')
|
|
670
|
+
public width: string | number;
|
|
671
|
+
|
|
672
|
+
/**
|
|
673
|
+
* Specifies the z-index value of the pop-up element.
|
|
674
|
+
* @default 1000
|
|
675
|
+
*/
|
|
676
|
+
@Property(1000)
|
|
677
|
+
public zIndex: number;
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Triggers when the data fetch request from the remote server fails.
|
|
681
|
+
* @event
|
|
682
|
+
*/
|
|
683
|
+
@Event()
|
|
684
|
+
public actionFailure: EmitType<Object>;
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Fires when popup opens before animation.
|
|
688
|
+
* @event
|
|
689
|
+
*/
|
|
690
|
+
@Event()
|
|
691
|
+
public beforeOpen: EmitType<DdtBeforeOpenEventArgs>;
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* Triggers when an item in a popup is selected or when the model value is changed by user.
|
|
695
|
+
* @event
|
|
696
|
+
*/
|
|
697
|
+
@Event()
|
|
698
|
+
public change: EmitType<DdtChangeEventArgs>;
|
|
699
|
+
/**
|
|
700
|
+
* Fires when popup close after animation completion.
|
|
701
|
+
* @event
|
|
702
|
+
*/
|
|
703
|
+
@Event()
|
|
704
|
+
public close: EmitType<DdtPopupEventArgs>;
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
* Triggers when the Dropdown Tree input element gets focus-out.
|
|
708
|
+
* @event
|
|
709
|
+
*/
|
|
710
|
+
@Event()
|
|
711
|
+
public blur: EmitType<Object>;
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* Triggers when the Dropdown Tree is created successfully.
|
|
715
|
+
* @event
|
|
716
|
+
*/
|
|
717
|
+
@Event()
|
|
718
|
+
public created: EmitType<Object>;
|
|
719
|
+
|
|
720
|
+
/**
|
|
721
|
+
* Triggers when data source is populated in the Dropdown Tree.
|
|
722
|
+
* @event
|
|
723
|
+
*/
|
|
724
|
+
@Event()
|
|
725
|
+
public dataBound: EmitType<DdtDataBoundEventArgs>;
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* Triggers when the Dropdown Tree is destroyed successfully.
|
|
729
|
+
* @event
|
|
730
|
+
*/
|
|
731
|
+
@Event()
|
|
732
|
+
public destroyed: EmitType<Object>;
|
|
733
|
+
|
|
734
|
+
/**
|
|
735
|
+
* Triggers on typing a character in the filter bar when the **allowFiltering** is enabled.
|
|
736
|
+
*
|
|
737
|
+
* @event
|
|
738
|
+
* @blazorProperty 'Filtering'
|
|
739
|
+
*/
|
|
740
|
+
@Event()
|
|
741
|
+
public filtering: EmitType<DdtFilteringEventArgs>;
|
|
742
|
+
|
|
743
|
+
/**
|
|
744
|
+
* Triggers when the Dropdown Tree input element is focused.
|
|
745
|
+
* @event
|
|
746
|
+
*/
|
|
747
|
+
@Event()
|
|
748
|
+
public focus: EmitType<DdtFocusEventArgs>;
|
|
749
|
+
|
|
750
|
+
/**
|
|
751
|
+
* Triggers when key press is successful. It helps to customize the operations at key press.
|
|
752
|
+
* @event
|
|
753
|
+
*/
|
|
754
|
+
@Event()
|
|
755
|
+
public keyPress: EmitType<DdtKeyPressEventArgs>;
|
|
756
|
+
|
|
757
|
+
/**
|
|
758
|
+
* Fires when popup opens after animation completion.
|
|
759
|
+
* @event
|
|
760
|
+
*/
|
|
761
|
+
@Event()
|
|
762
|
+
public open: EmitType<DdtPopupEventArgs>;
|
|
763
|
+
|
|
764
|
+
/**
|
|
765
|
+
* Triggers when an item in the popup is selected by the user either with mouse/tap or with keyboard navigation.
|
|
766
|
+
* @event
|
|
767
|
+
*/
|
|
768
|
+
@Event()
|
|
769
|
+
public select: EmitType<DdtSelectEventArgs>;
|
|
770
|
+
|
|
771
|
+
constructor(options?: DropDownTreeModel, element?: string | HTMLElement) {
|
|
772
|
+
super(options, <HTMLElement | string>element);
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/**
|
|
776
|
+
* Get the properties to be maintained in the persisted state.
|
|
777
|
+
* @returns string
|
|
778
|
+
* @hidden
|
|
779
|
+
*/
|
|
780
|
+
|
|
781
|
+
public getPersistData(): string {
|
|
782
|
+
let keyEntity: string[] = ['value'];
|
|
783
|
+
return this.addOnPersist(keyEntity);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
/**
|
|
787
|
+
* Initialize the event handler.
|
|
788
|
+
* @private
|
|
789
|
+
*/
|
|
790
|
+
protected preRender(): void {
|
|
791
|
+
this.inputFocus = false;
|
|
792
|
+
this.isPopupOpen = false;
|
|
793
|
+
this.isFirstRender = true;
|
|
794
|
+
this.isInitialized = false;
|
|
795
|
+
this.currentText = null;
|
|
796
|
+
this.currentValue = null;
|
|
797
|
+
this.oldValue = null;
|
|
798
|
+
this.removeValue = false;
|
|
799
|
+
this.selectedText = [];
|
|
800
|
+
this.treeItems = [];
|
|
801
|
+
this.dataValue = null;
|
|
802
|
+
this.isNodeSelected = false;
|
|
803
|
+
this.isDynamicChange = false;
|
|
804
|
+
this.isBlazorPlatForm = isBlazor();
|
|
805
|
+
this.headerTemplateId = `${this.element.id}${HEADERTEMPLATE}`;
|
|
806
|
+
this.footerTemplateId = `${this.element.id}${FOOTERTEMPLATE}`;
|
|
807
|
+
this.actionFailureTemplateId = `${this.element.id}${ACTIONFAILURETEMPLATE}`;
|
|
808
|
+
this.noRecordsTemplateId = `${this.element.id}${NORECORDSTEMPLATE}`;
|
|
809
|
+
this.keyConfigs = {
|
|
810
|
+
escape: 'escape',
|
|
811
|
+
altUp: 'alt+uparrow',
|
|
812
|
+
altDown: 'alt+downarrow',
|
|
813
|
+
tab: 'tab',
|
|
814
|
+
shiftTab: 'shift+tab',
|
|
815
|
+
end: 'end',
|
|
816
|
+
enter: 'enter',
|
|
817
|
+
home: 'home',
|
|
818
|
+
moveDown: 'downarrow',
|
|
819
|
+
moveLeft: 'leftarrow',
|
|
820
|
+
moveRight: 'rightarrow',
|
|
821
|
+
moveUp: 'uparrow',
|
|
822
|
+
ctrlDown: 'ctrl+downarrow',
|
|
823
|
+
ctrlUp: 'ctrl+uparrow',
|
|
824
|
+
ctrlEnter: 'ctrl+enter',
|
|
825
|
+
ctrlHome: 'ctrl+home',
|
|
826
|
+
ctrlEnd: 'ctrl+end',
|
|
827
|
+
shiftDown: 'shift+downarrow',
|
|
828
|
+
shiftUp: 'shift+uparrow',
|
|
829
|
+
shiftEnter: 'shift+enter',
|
|
830
|
+
shiftHome: 'shift+home',
|
|
831
|
+
shiftEnd: 'shift+end',
|
|
832
|
+
csDown: 'ctrl+shift+downarrow',
|
|
833
|
+
csUp: 'ctrl+shift+uparrow',
|
|
834
|
+
csEnter: 'ctrl+shift+enter',
|
|
835
|
+
csHome: 'ctrl+shift+home',
|
|
836
|
+
csEnd: 'ctrl+shift+end',
|
|
837
|
+
space: 'space',
|
|
838
|
+
ctrlA: 'ctrl+A'
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
/**
|
|
843
|
+
* To Initialize the control rendering
|
|
844
|
+
* @private
|
|
845
|
+
*/
|
|
846
|
+
public render(): void {
|
|
847
|
+
this.ensureAutoCheck();
|
|
848
|
+
if (this.element.tagName === 'INPUT') {
|
|
849
|
+
this.inputEle = this.element as HTMLInputElement;
|
|
850
|
+
if (isNOU(this.inputEle.getAttribute('role'))) {
|
|
851
|
+
this.inputEle.setAttribute('role', 'textbox');
|
|
852
|
+
}
|
|
853
|
+
if (isNOU(this.inputEle.getAttribute('type'))) {
|
|
854
|
+
this.inputEle.setAttribute('type', 'text');
|
|
855
|
+
}
|
|
856
|
+
} else {
|
|
857
|
+
this.inputEle = this.createElement('input', { attrs: { role: 'textbox', type: 'text' } }) as HTMLInputElement;
|
|
858
|
+
this.element.parentElement.insertBefore(this.inputEle, this.element);
|
|
859
|
+
}
|
|
860
|
+
this.inputObj = Input.createInput(
|
|
861
|
+
{
|
|
862
|
+
element: this.inputEle,
|
|
863
|
+
floatLabelType: this.floatLabelType,
|
|
864
|
+
buttons: this.showDropDownIcon ? [DROPDOWNICON] : null,
|
|
865
|
+
properties: {
|
|
866
|
+
readonly: true,
|
|
867
|
+
placeholder: this.placeholder,
|
|
868
|
+
enabled: this.enabled,
|
|
869
|
+
cssClass: this.cssClass,
|
|
870
|
+
enableRtl: this.enableRtl,
|
|
871
|
+
},
|
|
872
|
+
},
|
|
873
|
+
this.createElement
|
|
874
|
+
);
|
|
875
|
+
this.inputWrapper = this.inputObj.container;
|
|
876
|
+
if (!this.inputWrapper.classList.contains(INPUTGROUP)) {
|
|
877
|
+
this.inputWrapper.classList.add(INPUTGROUP);
|
|
878
|
+
}
|
|
879
|
+
if (this.showDropDownIcon) {
|
|
880
|
+
this.inputWrapper.classList.add(SHOW_DD_ICON);
|
|
881
|
+
}
|
|
882
|
+
if (this.element.tagName === this.getDirective()) {
|
|
883
|
+
this.element.appendChild(this.inputWrapper);
|
|
884
|
+
}
|
|
885
|
+
this.createHiddenElement();
|
|
886
|
+
this.createClearIcon();
|
|
887
|
+
this.inputWrapper.classList.add(DROPDOWNTREE);
|
|
888
|
+
this.setElementWidth(this.width);
|
|
889
|
+
this.setAttributes();
|
|
890
|
+
this.updateDataAttribute();
|
|
891
|
+
this.setHTMLAttributes();
|
|
892
|
+
this.popupDiv = this.createElement('div', { className: CONTENT, attrs: { 'tabindex': '0' } });
|
|
893
|
+
this.popupDiv.classList.add(DROPDOWN);
|
|
894
|
+
this.tree = this.createElement('div', { id: this.element.id + '_tree', });
|
|
895
|
+
this.popupDiv.appendChild(this.tree);
|
|
896
|
+
document.body.appendChild(this.popupDiv);
|
|
897
|
+
this.wireTreeEvents();
|
|
898
|
+
this.popupDiv.style.display = 'none';
|
|
899
|
+
this.renderTree();
|
|
900
|
+
this.isRemoteData = this.fields.dataSource instanceof DataManager;
|
|
901
|
+
if (!this.isRemoteData) {
|
|
902
|
+
this.setTreeValue();
|
|
903
|
+
this.setTreeText();
|
|
904
|
+
this.updateHiddenValue();
|
|
905
|
+
this.setSelectedValue();
|
|
906
|
+
}
|
|
907
|
+
if ((this.allowMultiSelection || this.showCheckBox) && this.mode !== 'Delimiter') {
|
|
908
|
+
this.createChip();
|
|
909
|
+
}
|
|
910
|
+
this.wireEvents();
|
|
911
|
+
this.oldValue = this.value;
|
|
912
|
+
this.isInitialized = true;
|
|
913
|
+
this.renderComplete();
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
private ensureAutoCheck(): void {
|
|
917
|
+
if (this.allowFiltering && this.treeSettings.autoCheck) {
|
|
918
|
+
this.setProperties({ treeSettings: { autoCheck: false } }, true);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
private hideCheckAll(flag: boolean): void {
|
|
923
|
+
let checkAllEle : HTMLElement = !isNOU(this.popupEle) ? (this.popupEle.querySelector('.' + CHECKALLPARENT) as HTMLElement) : null;
|
|
924
|
+
if (!isNOU(checkAllEle)) {
|
|
925
|
+
if (flag && !checkAllEle.classList.contains(CHECKALLHIDE)) {
|
|
926
|
+
addClass([checkAllEle], CHECKALLHIDE);
|
|
927
|
+
} else if (!flag && checkAllEle.classList.contains(CHECKALLHIDE)) {
|
|
928
|
+
removeClass([checkAllEle], CHECKALLHIDE);
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
private renderFilter(): void {
|
|
934
|
+
this.filterContainer = this.createElement('div', {
|
|
935
|
+
id: this.element.id + '_filter_wrap',
|
|
936
|
+
className: FILTERWRAP
|
|
937
|
+
});
|
|
938
|
+
let filterInput: HTMLElement = this.createElement('input', {
|
|
939
|
+
id: this.element.id + '_filter',
|
|
940
|
+
attrs: { autocomplete: 'off', 'aria-label': this.filterBarPlaceholder }
|
|
941
|
+
});
|
|
942
|
+
this.filterContainer.appendChild(filterInput);
|
|
943
|
+
prepend([this.filterContainer], this.popupEle);
|
|
944
|
+
this.filterObj = new TextBox({
|
|
945
|
+
value: '',
|
|
946
|
+
showClearButton: true,
|
|
947
|
+
placeholder: this.filterBarPlaceholder,
|
|
948
|
+
input: this.filterChangeHandler.bind(this),
|
|
949
|
+
});
|
|
950
|
+
this.filterObj.appendTo('#' + this.element.id + '_filter');
|
|
951
|
+
}
|
|
952
|
+
private filterChangeHandler(args?: InputEventArgs): void {
|
|
953
|
+
if (!isNOU(args.value)) {
|
|
954
|
+
window.clearTimeout(this.filterTimer);
|
|
955
|
+
this.filterTimer = window.setTimeout(() => { this.filterHandler(args.value, args.event); }, this.filterDelayTime);
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
private filterHandler(value: string, event: Event): void {
|
|
960
|
+
if (!this.isFilteredData) { this.treeData = this.treeObj.getTreeData(); }
|
|
961
|
+
let filterFields: FieldsModel = this.cloneFields(this.fields);
|
|
962
|
+
let args: DdtFilteringEventArgs = {
|
|
963
|
+
cancel: false,
|
|
964
|
+
preventDefaultAction: false,
|
|
965
|
+
event: event,
|
|
966
|
+
text: value,
|
|
967
|
+
fields: filterFields
|
|
968
|
+
};
|
|
969
|
+
this.trigger('filtering', args, (args: DdtFilteringEventArgs) => {
|
|
970
|
+
if (!args.cancel) {
|
|
971
|
+
let flag: boolean = false;
|
|
972
|
+
let fields: FieldsModel;
|
|
973
|
+
this.isFilteredData = true;
|
|
974
|
+
if (value === '') {
|
|
975
|
+
this.isFilteredData = false;
|
|
976
|
+
this.isFilterRestore = true;
|
|
977
|
+
fields = this.cloneFields(this.fields);
|
|
978
|
+
} else if (args.preventDefaultAction) {
|
|
979
|
+
fields = args.fields;
|
|
980
|
+
} else {
|
|
981
|
+
if (this.treeDataType === 1) {
|
|
982
|
+
fields = this.selfReferencefilter(value, args.fields);
|
|
983
|
+
} else {
|
|
984
|
+
if (this.fields.dataSource instanceof DataManager) {
|
|
985
|
+
flag = true;
|
|
986
|
+
} else {
|
|
987
|
+
fields = this.nestedFilter(value, args.fields);
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
this.hideCheckAll(this.isFilteredData);
|
|
992
|
+
if (flag) { return; }
|
|
993
|
+
this.treeObj.fields = this.getTreeFields(fields);
|
|
994
|
+
this.treeObj.dataBind();
|
|
995
|
+
}
|
|
996
|
+
});
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
private nestedFilter(value: string, filteredFields: FieldsModel): FieldsModel {
|
|
1000
|
+
let matchedDataSource: { [key: string]: Object }[] = [];
|
|
1001
|
+
for (let i: number = 0; i < this.treeData.length; i++) {
|
|
1002
|
+
let filteredChild: { [key: string]: Object } = this.nestedChildFilter(value, this.treeData[i]);
|
|
1003
|
+
if (!isNOU(filteredChild)) { matchedDataSource.push(filteredChild); }
|
|
1004
|
+
}
|
|
1005
|
+
filteredFields.dataSource = matchedDataSource;
|
|
1006
|
+
return filteredFields;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
private nestedChildFilter(value: string, node: { [key: string]: Object }): { [key: string]: Object } {
|
|
1010
|
+
let children: { [key: string]: Object }[] = <{ [key: string]: Object }[]>node[this.fields.child as string];
|
|
1011
|
+
if (isNOU(children)) {
|
|
1012
|
+
return (this.isMatchedNode(value, node)) ? node : null;
|
|
1013
|
+
} else {
|
|
1014
|
+
let matchedChildren: { [key: string]: Object }[] = [];
|
|
1015
|
+
for (let i: number = 0; i < children.length; i++) {
|
|
1016
|
+
let filteredChild: { [key: string]: Object } = this.nestedChildFilter(value, children[i]);
|
|
1017
|
+
if (!isNOU(filteredChild)) { matchedChildren.push(filteredChild); }
|
|
1018
|
+
}
|
|
1019
|
+
if (matchedChildren.length !== 0) {
|
|
1020
|
+
node[this.fields.child as string] = matchedChildren;
|
|
1021
|
+
return node;
|
|
1022
|
+
} else {
|
|
1023
|
+
node[this.fields.child as string] = null;
|
|
1024
|
+
return (this.isMatchedNode(value, node)) ? node : null;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
private selfReferencefilter(value: string, filteredFields: FieldsModel): FieldsModel {
|
|
1030
|
+
let matchedData: { [key: string]: Object }[] = [];
|
|
1031
|
+
let matchedDataSource: { [key: string]: Object }[] = [];
|
|
1032
|
+
for (let i: number = 0; i < this.treeData.length; i++) {
|
|
1033
|
+
if (this.isMatchedNode(value, this.treeData[i])) {
|
|
1034
|
+
matchedData.push(this.treeData[i]);
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
for (let i: number = 0; i < matchedData.length; i++) {
|
|
1038
|
+
if (matchedDataSource.indexOf(matchedData[i]) === -1) {
|
|
1039
|
+
matchedDataSource.push(matchedData[i]);
|
|
1040
|
+
let parentId: object = matchedData[i][this.fields.parentValue];
|
|
1041
|
+
while (!isNOU(parentId)) {
|
|
1042
|
+
let parent: { [key: string]: Object } = null;
|
|
1043
|
+
for (let j: number = 0; j < this.treeData.length; j++) {
|
|
1044
|
+
let value: object = this.treeData[j][this.fields.value];
|
|
1045
|
+
if (!isNOU(value) && (value === parentId)) {
|
|
1046
|
+
parent = this.treeData[j];
|
|
1047
|
+
break;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
if (!isNOU(parent) && (matchedDataSource.indexOf(parent) === -1)) {
|
|
1051
|
+
matchedDataSource.push(parent);
|
|
1052
|
+
parentId = parent[this.fields.parentValue];
|
|
1053
|
+
} else {
|
|
1054
|
+
break;
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
filteredFields.dataSource = matchedDataSource;
|
|
1060
|
+
return filteredFields;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
private isMatchedNode(value: string, node: { [key: string]: Object }): boolean {
|
|
1064
|
+
let checkValue: string = node[this.fields.text] as string;
|
|
1065
|
+
if (this.ignoreCase) {
|
|
1066
|
+
checkValue = checkValue.toLowerCase();
|
|
1067
|
+
value = value.toLowerCase();
|
|
1068
|
+
}
|
|
1069
|
+
if (this.ignoreAccent) {
|
|
1070
|
+
checkValue = DataUtil.ignoreDiacritics(checkValue) as string;
|
|
1071
|
+
value = DataUtil.ignoreDiacritics(value) as string;
|
|
1072
|
+
}
|
|
1073
|
+
if (this.filterType === 'StartsWith') {
|
|
1074
|
+
return checkValue.slice(0, value.length) === value;
|
|
1075
|
+
} else if (this.filterType === 'EndsWith') {
|
|
1076
|
+
return checkValue.slice(-value.length) === value;
|
|
1077
|
+
} else {
|
|
1078
|
+
return checkValue.indexOf(value) !== -1;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
/* To wire events for the dropdown tree */
|
|
1083
|
+
private wireEvents(): void {
|
|
1084
|
+
EventHandler.add(this.inputWrapper, 'mouseup', this.dropDownClick, this);
|
|
1085
|
+
EventHandler.add(this.inputWrapper, 'focus', this.focusIn, this);
|
|
1086
|
+
EventHandler.add(this.inputWrapper, 'blur', this.focusOut, this);
|
|
1087
|
+
EventHandler.add(this.inputWrapper, 'mousemove', this.mouseIn, this);
|
|
1088
|
+
EventHandler.add(this.inputWrapper, 'mouseout', this.onMouseLeave, this);
|
|
1089
|
+
EventHandler.add(this.overAllClear, 'mousedown', this.clearAll, this);
|
|
1090
|
+
EventHandler.add(<HTMLElement & Window>window, 'resize', this.windowResize, this);
|
|
1091
|
+
let formElement: HTMLFormElement = closest(this.inputWrapper, 'form') as HTMLFormElement;
|
|
1092
|
+
if (formElement) {
|
|
1093
|
+
EventHandler.add(formElement, 'reset', this.resetValueHandler, this);
|
|
1094
|
+
}
|
|
1095
|
+
this.keyboardModule = new KeyboardEvents(
|
|
1096
|
+
this.inputWrapper,
|
|
1097
|
+
{
|
|
1098
|
+
keyAction: this.keyActionHandler.bind(this),
|
|
1099
|
+
keyConfigs: this.keyConfigs,
|
|
1100
|
+
eventName: 'keydown',
|
|
1101
|
+
}
|
|
1102
|
+
);
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
private wireTreeEvents(): void {
|
|
1106
|
+
this.keyboardModule = new KeyboardEvents(
|
|
1107
|
+
this.tree,
|
|
1108
|
+
{
|
|
1109
|
+
keyAction: this.treeAction.bind(this),
|
|
1110
|
+
keyConfigs: this.keyConfigs,
|
|
1111
|
+
eventName: 'keydown',
|
|
1112
|
+
}
|
|
1113
|
+
);
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
private wireCheckAllWrapperEvents(): void {
|
|
1117
|
+
this.keyboardModule = new KeyboardEvents(
|
|
1118
|
+
this.checkAllParent,
|
|
1119
|
+
{
|
|
1120
|
+
keyAction: this.checkAllAction.bind(this),
|
|
1121
|
+
keyConfigs: this.keyConfigs,
|
|
1122
|
+
eventName: 'keydown',
|
|
1123
|
+
}
|
|
1124
|
+
);
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
/* To unwire events for the dropdown tree */
|
|
1128
|
+
private unWireEvents(): void {
|
|
1129
|
+
EventHandler.remove(this.inputWrapper, 'mouseup', this.dropDownClick);
|
|
1130
|
+
EventHandler.remove(this.inputWrapper, 'focus', this.focusIn);
|
|
1131
|
+
EventHandler.remove(this.inputWrapper, 'blur', this.focusOut);
|
|
1132
|
+
EventHandler.remove(this.inputWrapper, 'mousemove', this.mouseIn);
|
|
1133
|
+
EventHandler.remove(this.inputWrapper, 'mouseout', this.onMouseLeave);
|
|
1134
|
+
EventHandler.remove(this.overAllClear, 'mousedown', this.clearAll);
|
|
1135
|
+
EventHandler.remove(<HTMLElement & Window>window, 'resize', this.windowResize);
|
|
1136
|
+
let formElement: HTMLFormElement = closest(this.inputWrapper, 'form') as HTMLFormElement;
|
|
1137
|
+
if (formElement) {
|
|
1138
|
+
EventHandler.remove(formElement, 'reset', this.resetValueHandler);
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
/* Trigger when the dropdown is clicked */
|
|
1143
|
+
private dropDownClick(e: MouseEvent): void {
|
|
1144
|
+
if (!this.enabled || this.readonly) {
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1147
|
+
if (this.isClearButtonClick) {
|
|
1148
|
+
this.isClearButtonClick = false;
|
|
1149
|
+
return;
|
|
1150
|
+
}
|
|
1151
|
+
if (this.isPopupOpen) {
|
|
1152
|
+
this.hidePopup();
|
|
1153
|
+
} else {
|
|
1154
|
+
this.focusIn(e);
|
|
1155
|
+
this.renderPopup();
|
|
1156
|
+
}
|
|
1157
|
+
this.showOverAllClear();
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
private mouseIn(): void {
|
|
1161
|
+
if (this.enabled || !this.readonly) {
|
|
1162
|
+
this.showOverAllClear();
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
private onMouseLeave(): void {
|
|
1167
|
+
if (!this.inputFocus) {
|
|
1168
|
+
addClass([this.overAllClear], HIDEICON);
|
|
1169
|
+
removeClass([this.inputWrapper], SHOW_CLEAR);
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
protected getDirective(): string {
|
|
1174
|
+
return 'EJS-DROPDOWNTREE';
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
private focusOut(e: MouseEvent): void {
|
|
1178
|
+
if (!this.enabled || this.readonly || !this.inputFocus) {
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
if ((Browser.isIE || Browser.info.name === 'edge') && (e.target === this.inputWrapper)) {
|
|
1182
|
+
return;
|
|
1183
|
+
}
|
|
1184
|
+
let target: HTMLElement = <HTMLElement>e.relatedTarget;
|
|
1185
|
+
if ((target !== this.inputEle) && (isNOU(target)) && (e.target !== this.inputWrapper || !this.isPopupOpen)) {
|
|
1186
|
+
this.onFocusOut(e);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
private onFocusOut(event?: MouseEvent): void {
|
|
1191
|
+
this.inputFocus = false;
|
|
1192
|
+
if (this.isPopupOpen) {
|
|
1193
|
+
this.hidePopup();
|
|
1194
|
+
}
|
|
1195
|
+
if (this.isClearButtonClick) {
|
|
1196
|
+
this.isClearButtonClick = false;
|
|
1197
|
+
}
|
|
1198
|
+
if (this.showClearButton) {
|
|
1199
|
+
addClass([this.overAllClear], HIDEICON);
|
|
1200
|
+
removeClass([this.inputWrapper], SHOW_CLEAR);
|
|
1201
|
+
}
|
|
1202
|
+
removeClass([this.inputWrapper], [INPUTFOCUS]);
|
|
1203
|
+
if ((this.allowMultiSelection || this.showCheckBox) && this.mode !== 'Delimiter') {
|
|
1204
|
+
let isValue: boolean = this.value ? (this.value.length ? true : false) : false;
|
|
1205
|
+
if (this.chipWrapper && (this.mode === 'Default') || (this.mode === 'Box' && !isValue)) {
|
|
1206
|
+
addClass([this.chipWrapper], HIDEICON);
|
|
1207
|
+
removeClass([this.inputWrapper], SHOW_CHIP);
|
|
1208
|
+
removeClass([this.inputEle], CHIP_INPUT);
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
if (this.changeOnBlur) {
|
|
1212
|
+
this.triggerChangeEvent(event);
|
|
1213
|
+
}
|
|
1214
|
+
this.removeValue = false;
|
|
1215
|
+
this.oldValue = this.value;
|
|
1216
|
+
this.trigger('blur');
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
private triggerChangeEvent(event?: MouseEvent | KeyboardEvent): void {
|
|
1220
|
+
let isEqual: boolean = this.compareValues(this.oldValue, this.value);
|
|
1221
|
+
if ((!isEqual || this.isChipDelete) && !this.removeValue) {
|
|
1222
|
+
let eventArgs: DdtChangeEventArgs = {
|
|
1223
|
+
e: event,
|
|
1224
|
+
oldValue: this.oldValue,
|
|
1225
|
+
value: this.value,
|
|
1226
|
+
isInteracted: event ? true : false,
|
|
1227
|
+
element: this.element
|
|
1228
|
+
};
|
|
1229
|
+
this.trigger('change', eventArgs);
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
private compareValues(oldValue: string[], newValue: string[]): boolean {
|
|
1234
|
+
if (oldValue === null || oldValue.length === 0) {
|
|
1235
|
+
let isValid: boolean = oldValue === null ? ((newValue === oldValue) ? true : false) :
|
|
1236
|
+
(oldValue.length === 0 ? (newValue === oldValue) : false);
|
|
1237
|
+
return isValid;
|
|
1238
|
+
} else if (oldValue.length !== newValue.length) {
|
|
1239
|
+
return false;
|
|
1240
|
+
}
|
|
1241
|
+
for (let i: number = 0; i < oldValue.length; i++) {
|
|
1242
|
+
if (oldValue[i] !== newValue[i]) {
|
|
1243
|
+
return false;
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
return true;
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
private focusIn(e?: FocusEvent | MouseEvent | KeyboardEvent | TouchEvent): void {
|
|
1250
|
+
if (!this.enabled || this.readonly || this.inputFocus) {
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
this.showOverAllClear();
|
|
1254
|
+
this.inputFocus = true;
|
|
1255
|
+
addClass([this.inputWrapper], [INPUTFOCUS]);
|
|
1256
|
+
if ((this.allowMultiSelection || this.showCheckBox) && this.mode === 'Default' && this.inputFocus) {
|
|
1257
|
+
if (this.chipWrapper && (this.value && this.value.length !== 0)) {
|
|
1258
|
+
removeClass([this.chipWrapper], HIDEICON);
|
|
1259
|
+
addClass([this.inputWrapper], SHOW_CHIP);
|
|
1260
|
+
addClass([this.inputEle], CHIP_INPUT);
|
|
1261
|
+
}
|
|
1262
|
+
if (this.popupObj) {
|
|
1263
|
+
this.popupObj.refreshPosition();
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
let args: DdtFocusEventArgs = { isInteracted: e ? true : false, event: e };
|
|
1267
|
+
this.trigger('focus', args);
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
private treeAction(e: KeyboardEventArgs): void {
|
|
1271
|
+
let eventArgs: DdtKeyPressEventArgs = {
|
|
1272
|
+
cancel: false,
|
|
1273
|
+
event: e,
|
|
1274
|
+
};
|
|
1275
|
+
this.trigger('keyPress', eventArgs, (observedArgs: DdtKeyPressEventArgs) => {
|
|
1276
|
+
if (!observedArgs.cancel) {
|
|
1277
|
+
switch (e.action) {
|
|
1278
|
+
case 'escape':
|
|
1279
|
+
case 'altUp':
|
|
1280
|
+
this.inputWrapper.focus();
|
|
1281
|
+
e.preventDefault();
|
|
1282
|
+
if (this.isPopupOpen) {
|
|
1283
|
+
this.hidePopup();
|
|
1284
|
+
}
|
|
1285
|
+
break;
|
|
1286
|
+
case 'tab':
|
|
1287
|
+
case 'shiftTab':
|
|
1288
|
+
if (this.isPopupOpen) {
|
|
1289
|
+
this.hidePopup();
|
|
1290
|
+
}
|
|
1291
|
+
break;
|
|
1292
|
+
case 'enter':
|
|
1293
|
+
case 'ctrlEnter':
|
|
1294
|
+
case 'shiftEnter':
|
|
1295
|
+
case 'csEnter':
|
|
1296
|
+
if (!this.showCheckBox) {
|
|
1297
|
+
this.isValueChange = true;
|
|
1298
|
+
this.keyEventArgs = e;
|
|
1299
|
+
}
|
|
1300
|
+
break;
|
|
1301
|
+
case 'space':
|
|
1302
|
+
this.isValueChange = true;
|
|
1303
|
+
this.keyEventArgs = e;
|
|
1304
|
+
break;
|
|
1305
|
+
case 'ctrlA':
|
|
1306
|
+
if (this.allowMultiSelection) {
|
|
1307
|
+
this.selectAll(true);
|
|
1308
|
+
}
|
|
1309
|
+
break;
|
|
1310
|
+
case 'moveRight':
|
|
1311
|
+
case 'moveLeft':
|
|
1312
|
+
case 'shiftDown':
|
|
1313
|
+
case 'moveDown':
|
|
1314
|
+
case 'ctrlDown':
|
|
1315
|
+
case 'csDown':
|
|
1316
|
+
case 'shiftUp':
|
|
1317
|
+
case 'moveUp':
|
|
1318
|
+
case 'ctrlUp':
|
|
1319
|
+
case 'csUp':
|
|
1320
|
+
case 'home':
|
|
1321
|
+
case 'shiftHome':
|
|
1322
|
+
case 'ctrlHome':
|
|
1323
|
+
case 'csHome':
|
|
1324
|
+
case 'end':
|
|
1325
|
+
case 'shiftEnd':
|
|
1326
|
+
case 'ctrlEnd':
|
|
1327
|
+
case 'csEnd':
|
|
1328
|
+
}
|
|
1329
|
+
} else {
|
|
1330
|
+
e.stopImmediatePropagation();
|
|
1331
|
+
}
|
|
1332
|
+
});
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
private keyActionHandler(e: KeyboardEventArgs): void {
|
|
1336
|
+
let eventArgs: DdtKeyPressEventArgs = {
|
|
1337
|
+
cancel: false,
|
|
1338
|
+
event: e,
|
|
1339
|
+
};
|
|
1340
|
+
this.trigger('keyPress', eventArgs, (observedArgs: DdtKeyPressEventArgs) => {
|
|
1341
|
+
if (!observedArgs.cancel) {
|
|
1342
|
+
switch (e.action) {
|
|
1343
|
+
case 'escape':
|
|
1344
|
+
case 'altUp':
|
|
1345
|
+
case 'shiftTab':
|
|
1346
|
+
case 'tab':
|
|
1347
|
+
if (this.isPopupOpen) {
|
|
1348
|
+
this.hidePopup();
|
|
1349
|
+
}
|
|
1350
|
+
break;
|
|
1351
|
+
case 'altDown':
|
|
1352
|
+
if (!this.isPopupOpen) {
|
|
1353
|
+
this.showPopup();
|
|
1354
|
+
e.preventDefault();
|
|
1355
|
+
}
|
|
1356
|
+
break;
|
|
1357
|
+
case 'moveDown':
|
|
1358
|
+
if (this.showSelectAll && this.showCheckBox) {
|
|
1359
|
+
this.checkAllParent.focus();
|
|
1360
|
+
}
|
|
1361
|
+
break;
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
private checkAllAction(e: KeyboardEventArgs): void {
|
|
1368
|
+
let eventArgs: DdtKeyPressEventArgs = {
|
|
1369
|
+
cancel: false,
|
|
1370
|
+
event: e,
|
|
1371
|
+
};
|
|
1372
|
+
this.trigger('keyPress', eventArgs, (observedArgs: DdtKeyPressEventArgs) => {
|
|
1373
|
+
if (!observedArgs.cancel) {
|
|
1374
|
+
switch (e.action) {
|
|
1375
|
+
case 'space':
|
|
1376
|
+
this.clickHandler(e);
|
|
1377
|
+
break;
|
|
1378
|
+
case 'moveDown':
|
|
1379
|
+
this.treeObj.element.focus();
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
});
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
private windowResize(): void {
|
|
1386
|
+
if (this.popupObj) {
|
|
1387
|
+
this.popupObj.setProperties({ width: this.setWidth() });
|
|
1388
|
+
this.popupObj.refreshPosition();
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
private resetValueHandler(e: Event): void {
|
|
1393
|
+
let formElement: HTMLFormElement = closest(this.inputWrapper, 'form') as HTMLFormElement;
|
|
1394
|
+
if (formElement && e.target === formElement) {
|
|
1395
|
+
this.resetValue(true);
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
protected getAriaAttributes(): { [key: string]: string } {
|
|
1400
|
+
let disable: string = this.enabled ? 'false' : 'true';
|
|
1401
|
+
return {
|
|
1402
|
+
'aria-disabled': disable,
|
|
1403
|
+
'aria-owns': this.element.id + '_options',
|
|
1404
|
+
'role': 'listbox',
|
|
1405
|
+
'aria-haspopup': 'true',
|
|
1406
|
+
'aria-expanded': 'false',
|
|
1407
|
+
'aria-activedescendant': 'null',
|
|
1408
|
+
'aria-labelledby': this.hiddenElement.id
|
|
1409
|
+
};
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
private createHiddenElement(): void {
|
|
1413
|
+
if (this.allowMultiSelection || this.showCheckBox) {
|
|
1414
|
+
this.hiddenElement = this.createElement('select', {
|
|
1415
|
+
attrs: { 'aria-hidden': 'true', 'class': HIDDENELEMENT, 'tabindex': '-1', 'multiple': '' }
|
|
1416
|
+
}) as HTMLSelectElement;
|
|
1417
|
+
} else {
|
|
1418
|
+
this.hiddenElement = this.createElement('select', {
|
|
1419
|
+
attrs: { 'aria-hidden': 'true', 'tabindex': '-1', 'class': HIDDENELEMENT }
|
|
1420
|
+
}) as HTMLSelectElement;
|
|
1421
|
+
}
|
|
1422
|
+
prepend([this.hiddenElement], this.inputWrapper);
|
|
1423
|
+
this.validationAttribute();
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1426
|
+
private createClearIcon(): void {
|
|
1427
|
+
this.overAllClear = this.createElement('span', {
|
|
1428
|
+
className: CLOSEICON_CLASS
|
|
1429
|
+
});
|
|
1430
|
+
addClass([this.overAllClear], HIDEICON);
|
|
1431
|
+
removeClass([this.inputWrapper], SHOW_CLEAR);
|
|
1432
|
+
if (this.showClearButton) {
|
|
1433
|
+
this.inputWrapper.insertBefore(this.overAllClear, this.inputObj.buttons[0]);
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
private validationAttribute(): void {
|
|
1438
|
+
let name: string = this.inputEle.getAttribute('name') ? this.inputEle.getAttribute('name') : this.inputEle.getAttribute('id');
|
|
1439
|
+
this.hiddenElement.setAttribute('name', name);
|
|
1440
|
+
this.inputEle.removeAttribute('name');
|
|
1441
|
+
let attributes: string[] = ['required', 'aria-required', 'form'];
|
|
1442
|
+
for (let i: number = 0; i < attributes.length; i++) {
|
|
1443
|
+
let attr: string = this.inputEle.getAttribute(attributes[i]);
|
|
1444
|
+
if (attr) {
|
|
1445
|
+
this.hiddenElement.setAttribute(attributes[i], attr);
|
|
1446
|
+
this.inputEle.removeAttribute(attributes[i]);
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
private createChip(): void {
|
|
1452
|
+
if (!this.inputWrapper.contains(this.chipWrapper)) {
|
|
1453
|
+
this.chipWrapper = this.createElement('span', {
|
|
1454
|
+
className: CHIP_WRAPPER,
|
|
1455
|
+
});
|
|
1456
|
+
this.chipCollection = this.createElement('span', {
|
|
1457
|
+
className: CHIP_COLLECTION
|
|
1458
|
+
});
|
|
1459
|
+
this.chipWrapper.appendChild(this.chipCollection);
|
|
1460
|
+
this.inputWrapper.insertBefore(this.chipWrapper, this.hiddenElement);
|
|
1461
|
+
addClass([this.inputWrapper], SHOW_CHIP);
|
|
1462
|
+
let isValid: boolean = this.getValidMode();
|
|
1463
|
+
if (isValid && this.value !== null) {
|
|
1464
|
+
addClass([this.inputEle], CHIP_INPUT);
|
|
1465
|
+
} else if (this.value === null) {
|
|
1466
|
+
addClass([this.chipWrapper], HIDEICON);
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
private getValidMode(): boolean {
|
|
1472
|
+
if (this.allowMultiSelection || this.showCheckBox) {
|
|
1473
|
+
return this.mode === 'Box' ? true : (this.mode === 'Default' && this.inputFocus) ? true : false;
|
|
1474
|
+
} else {
|
|
1475
|
+
return false;
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
private createSelectAllWrapper(): void {
|
|
1480
|
+
this.checkAllParent = this.createElement('div', {
|
|
1481
|
+
className: CHECKALLPARENT, attrs: { 'tabindex': '0' }
|
|
1482
|
+
});
|
|
1483
|
+
this.selectAllSpan = this.createElement('span', {
|
|
1484
|
+
className: ALLTEXT
|
|
1485
|
+
});
|
|
1486
|
+
this.selectAllSpan.textContent = '';
|
|
1487
|
+
let ele: Element = closest(this.element, '.' + BIGGER);
|
|
1488
|
+
let touchClass: string = isNOU(ele) ? '' : SMALL;
|
|
1489
|
+
this.checkBoxElement = createCheckBox(this.createElement, true, { cssClass: touchClass });
|
|
1490
|
+
this.checkBoxElement.setAttribute('role', 'checkbox');
|
|
1491
|
+
this.checkAllParent.appendChild(this.checkBoxElement);
|
|
1492
|
+
this.checkAllParent.appendChild(this.selectAllSpan);
|
|
1493
|
+
this.setLocale();
|
|
1494
|
+
EventHandler.add(this.checkAllParent, 'mouseup', this.clickHandler, this);
|
|
1495
|
+
this.wireCheckAllWrapperEvents();
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
private clickHandler(e: MouseEvent| KeyboardEvent): void {
|
|
1499
|
+
let target: EventTarget;
|
|
1500
|
+
if ((e.currentTarget && (e.currentTarget as HTMLElement).classList.contains(CHECKALLPARENT))) {
|
|
1501
|
+
target = (e.currentTarget as HTMLElement).firstElementChild.lastElementChild;
|
|
1502
|
+
} else {
|
|
1503
|
+
target = <Element>e.target;
|
|
1504
|
+
}
|
|
1505
|
+
this.checkWrapper = closest((target as HTMLElement), '.' + CHECKBOXWRAP) as HTMLElement;
|
|
1506
|
+
if (!isNOU(this.checkWrapper)) {
|
|
1507
|
+
let checkElement: Element = select('.' + CHECKBOXFRAME, this.checkWrapper);
|
|
1508
|
+
this.changeState(this.checkWrapper, checkElement.classList.contains(CHECK) ? 'uncheck' : 'check', e);
|
|
1509
|
+
}
|
|
1510
|
+
e.preventDefault();
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
private changeState(
|
|
1514
|
+
wrapper: HTMLElement | Element, state: string, e?: MouseEvent | KeyboardEvent): void {
|
|
1515
|
+
let ariaState: string;
|
|
1516
|
+
let frameSpan: Element = wrapper.getElementsByClassName(CHECKBOXFRAME)[0];
|
|
1517
|
+
if (state === 'check' && !frameSpan.classList.contains(CHECK)) {
|
|
1518
|
+
frameSpan.classList.add(CHECK);
|
|
1519
|
+
ariaState = 'true';
|
|
1520
|
+
if (!this.isReverseUpdate) {
|
|
1521
|
+
this.treeObj.checkAll();
|
|
1522
|
+
if (!this.changeOnBlur) {
|
|
1523
|
+
this.triggerChangeEvent(e);
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
this.setLocale(true);
|
|
1527
|
+
} else if (state === 'uncheck' && (frameSpan.classList.contains(CHECK))) {
|
|
1528
|
+
frameSpan.classList.remove(CHECK);
|
|
1529
|
+
ariaState = 'false';
|
|
1530
|
+
if (!this.isReverseUpdate) {
|
|
1531
|
+
this.treeObj.uncheckAll();
|
|
1532
|
+
if (!this.changeOnBlur) {
|
|
1533
|
+
this.triggerChangeEvent(e);
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
this.setLocale(false);
|
|
1537
|
+
}
|
|
1538
|
+
this.setMultiSelect();
|
|
1539
|
+
this.ensurePlaceHolder();
|
|
1540
|
+
ariaState = state === 'check' ? 'true' : 'false';
|
|
1541
|
+
if (!isNOU(ariaState)) {
|
|
1542
|
+
wrapper.setAttribute('aria-checked', ariaState);
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
private setLocale(unSelect?: boolean): void {
|
|
1547
|
+
if (!this.selectAllSpan) {return; }
|
|
1548
|
+
if (this.selectAllText !== 'Select All' || this.unSelectAllText !== 'Unselect All') {
|
|
1549
|
+
let template: string = unSelect ? this.unSelectAllText : this.selectAllText;
|
|
1550
|
+
let compiledString: Function;
|
|
1551
|
+
this.selectAllSpan.textContent = '';
|
|
1552
|
+
compiledString = compile(template);
|
|
1553
|
+
for (let item of compiledString({}, null, null, null, !this.isStringTemplate)) {
|
|
1554
|
+
this.selectAllSpan.textContent = item.textContent;
|
|
1555
|
+
}
|
|
1556
|
+
} else {
|
|
1557
|
+
this.selectAllSpan.textContent = unSelect ? this.unSelectAllText : this.selectAllText;
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
private setAttributes(): void {
|
|
1562
|
+
this.element.removeAttribute('tabindex');
|
|
1563
|
+
let id: string = this.element.getAttribute('id');
|
|
1564
|
+
this.hiddenElement.id = id + '_hidden';
|
|
1565
|
+
this.inputWrapper.setAttribute('tabindex', '0');
|
|
1566
|
+
attributes(this.inputWrapper, this.getAriaAttributes());
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
private setHTMLAttributes(): void {
|
|
1570
|
+
if (Object.keys(this.htmlAttributes).length) {
|
|
1571
|
+
for (let htmlAttr of Object.keys(this.htmlAttributes)) {
|
|
1572
|
+
if (htmlAttr === 'class') {
|
|
1573
|
+
this.inputWrapper.classList.add(this.htmlAttributes[htmlAttr]);
|
|
1574
|
+
} else if (htmlAttr === 'disabled' && this.htmlAttributes[htmlAttr] === 'disabled') {
|
|
1575
|
+
this.setProperties({ enabled: false }, true);
|
|
1576
|
+
this.setEnable();
|
|
1577
|
+
} else if (htmlAttr === 'readonly' && !isNOU(this.htmlAttributes[htmlAttr])) {
|
|
1578
|
+
this.setProperties({ readonly: true }, true);
|
|
1579
|
+
this.dataBind();
|
|
1580
|
+
} else if (htmlAttr === 'style') {
|
|
1581
|
+
this.inputWrapper.setAttribute('style', this.htmlAttributes[htmlAttr]);
|
|
1582
|
+
} else {
|
|
1583
|
+
let defaultAttr: string[] = ['title', 'id', 'placeholder', 'aria-placeholder',
|
|
1584
|
+
'role', 'autocorrect', 'autocomplete', 'autocapitalize', 'spellcheck', 'minlength', 'maxlength'];
|
|
1585
|
+
let validateAttr: string[] = ['name', 'required'];
|
|
1586
|
+
if (htmlAttr.indexOf('data') === 0 || validateAttr.indexOf(htmlAttr) > -1) {
|
|
1587
|
+
this.hiddenElement.setAttribute(htmlAttr, this.htmlAttributes[htmlAttr]);
|
|
1588
|
+
} else if (defaultAttr.indexOf(htmlAttr) > -1) {
|
|
1589
|
+
htmlAttr === 'placeholder' ? Input.setPlaceholder(this.htmlAttributes[htmlAttr], this.inputEle) :
|
|
1590
|
+
this.inputEle.setAttribute(htmlAttr, this.htmlAttributes[htmlAttr]);
|
|
1591
|
+
} else {
|
|
1592
|
+
this.inputWrapper.setAttribute(htmlAttr, this.htmlAttributes[htmlAttr]);
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
private updateDataAttribute() : void {
|
|
1600
|
+
let value: { [key: string]: string; } = this.htmlAttributes;
|
|
1601
|
+
let invalidAttr: string[] = ['class', 'style', 'id', 'type'];
|
|
1602
|
+
let attr: { [key: string]: string; } = {};
|
|
1603
|
+
for (let a: number = 0; a < this.element.attributes.length; a++) {
|
|
1604
|
+
if (invalidAttr.indexOf(this.element.attributes[a].name) === -1 &&
|
|
1605
|
+
!( this.element.attributes[a].name === 'readonly')) {
|
|
1606
|
+
attr[this.element.attributes[a].name] = this.element.getAttribute(this.element.attributes[a].name);
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
extend(attr, value, attr);
|
|
1610
|
+
this.setProperties({ htmlAttributes: attr }, true);
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
private showOverAllClear(): void {
|
|
1614
|
+
if (!this.enabled || this.readonly) {
|
|
1615
|
+
return;
|
|
1616
|
+
}
|
|
1617
|
+
if (this.overAllClear) {
|
|
1618
|
+
let isValue: boolean = this.value ? (this.value.length ? true : false) : false;
|
|
1619
|
+
if (isValue && this.showClearButton) {
|
|
1620
|
+
removeClass([this.overAllClear], HIDEICON);
|
|
1621
|
+
addClass([this.inputWrapper], SHOW_CLEAR);
|
|
1622
|
+
} else {
|
|
1623
|
+
addClass([this.overAllClear], HIDEICON);
|
|
1624
|
+
removeClass([this.inputWrapper], SHOW_CLEAR);
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
private setTreeValue(): void {
|
|
1630
|
+
if (this.value !== null && this.value.length !== 0) {
|
|
1631
|
+
let data: { [key: string]: Object };
|
|
1632
|
+
if (this.showCheckBox || this.allowMultiSelection) {
|
|
1633
|
+
for (let i: number = 0; i < this.value.length; i++) {
|
|
1634
|
+
data = this.treeObj.getTreeData(this.value[i])[0];
|
|
1635
|
+
if (isNOU(data)) {
|
|
1636
|
+
this.value.splice(this.value.indexOf(this.value[i]), 1);
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
if (this.value.length !== 0) {
|
|
1640
|
+
this.setValidValue();
|
|
1641
|
+
}
|
|
1642
|
+
} else {
|
|
1643
|
+
data = this.treeObj.getTreeData(this.value[0])[0];
|
|
1644
|
+
if (!isNOU(data)) {
|
|
1645
|
+
this.setProperties({ text: data[this.fields.text] }, true);
|
|
1646
|
+
this.setValidValue();
|
|
1647
|
+
} else {
|
|
1648
|
+
this.setProperties({ value: this.currentValue }, true);
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
private setTreeText(): void {
|
|
1655
|
+
if (this.value !== null && !this.isInitialized) {
|
|
1656
|
+
return;
|
|
1657
|
+
}
|
|
1658
|
+
if (this.text !== null) {
|
|
1659
|
+
let data: { [key: string]: Object };
|
|
1660
|
+
let valArr: string[] = [];
|
|
1661
|
+
if (this.showCheckBox || this.allowMultiSelection) {
|
|
1662
|
+
let textArr: string[] = this.text.split(this.delimiterChar);
|
|
1663
|
+
for (let i: number = 0; i < textArr.length; i++) {
|
|
1664
|
+
data = this.getItems(textArr[i]);
|
|
1665
|
+
if (!isNOU(data)) {
|
|
1666
|
+
valArr.push(data[this.fields.value].toString());
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
if (valArr.length !== 0) {
|
|
1670
|
+
this.oldValue = this.value;
|
|
1671
|
+
this.setProperties({ value: valArr }, true);
|
|
1672
|
+
this.setValidValue();
|
|
1673
|
+
} else {
|
|
1674
|
+
this.setProperties({ text: this.currentText }, true);
|
|
1675
|
+
}
|
|
1676
|
+
} else {
|
|
1677
|
+
data = this.getItems(this.text);
|
|
1678
|
+
if (!isNOU(data)) {
|
|
1679
|
+
this.oldValue = this.value;
|
|
1680
|
+
this.setProperties({ value: [data[this.fields.value].toString()] }, true);
|
|
1681
|
+
this.setValidValue();
|
|
1682
|
+
} else {
|
|
1683
|
+
this.setProperties({ text: this.currentText }, true);
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
private setSelectedValue(): void {
|
|
1690
|
+
if (this.value != null) {
|
|
1691
|
+
return;
|
|
1692
|
+
}
|
|
1693
|
+
if (!this.isInitialized) {
|
|
1694
|
+
this.oldValue = this.value;
|
|
1695
|
+
if (this.treeObj.selectedNodes.length > 0 && !this.showCheckBox) {
|
|
1696
|
+
this.setProperties({ value: this.treeObj.selectedNodes }, true);
|
|
1697
|
+
if (this.allowMultiSelection) {
|
|
1698
|
+
this.updateMode();
|
|
1699
|
+
}
|
|
1700
|
+
} else if (this.showCheckBox && this.treeObj.checkedNodes) {
|
|
1701
|
+
if (this.treeObj.checkedNodes.length > 0) {
|
|
1702
|
+
this.setProperties({ value: this.treeObj.checkedNodes }, true);
|
|
1703
|
+
setValue('selectedNodes', [], this.treeObj);
|
|
1704
|
+
this.treeObj.dataBind();
|
|
1705
|
+
this.updateMode();
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
this.updateSelectedValues();
|
|
1709
|
+
this.currentText = this.text;
|
|
1710
|
+
this.currentValue = this.value;
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
|
|
1714
|
+
private setValidValue(): void {
|
|
1715
|
+
if (!this.showCheckBox && !this.allowMultiSelection) {
|
|
1716
|
+
Input.setValue(this.text, this.inputEle, this.floatLabelType);
|
|
1717
|
+
let id: string = this.value[0].toString();
|
|
1718
|
+
if (this.treeObj.selectedNodes[0] !== id) {
|
|
1719
|
+
setValue('selectedNodes', [id], this.treeObj);
|
|
1720
|
+
}
|
|
1721
|
+
} else {
|
|
1722
|
+
if (this.showCheckBox) {
|
|
1723
|
+
this.treeObj.checkedNodes = this.value.slice();
|
|
1724
|
+
setValue('selectedNodes', [], this.treeObj);
|
|
1725
|
+
this.treeObj.dataBind();
|
|
1726
|
+
this.setMultiSelect();
|
|
1727
|
+
} else {
|
|
1728
|
+
this.treeObj.selectedNodes = this.value.slice();
|
|
1729
|
+
this.selectedText = [];
|
|
1730
|
+
this.updateSelectedValues();
|
|
1731
|
+
}
|
|
1732
|
+
this.treeObj.dataBind();
|
|
1733
|
+
}
|
|
1734
|
+
this.currentText = this.text;
|
|
1735
|
+
this.currentValue = this.value;
|
|
1736
|
+
if (this.isInitialized) {
|
|
1737
|
+
this.triggerChangeEvent();
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
private getItems(givenText: string): { [key: string]: Object } {
|
|
1742
|
+
let data: { [key: string]: Object };
|
|
1743
|
+
if (this.treeDataType === 1) {
|
|
1744
|
+
for (let i: number = 0; i < this.treeItems.length; i++) {
|
|
1745
|
+
let text: Object = getValue(this.fields.text, this.treeItems[i]);
|
|
1746
|
+
if (!isNOU(this.treeItems[i]) && !isNOU(text) && text === givenText) {
|
|
1747
|
+
data = this.treeItems[i];
|
|
1748
|
+
break;
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
} else {
|
|
1752
|
+
data = this.getNestedItems(this.treeItems, this.fields, givenText);
|
|
1753
|
+
}
|
|
1754
|
+
return data;
|
|
1755
|
+
}
|
|
1756
|
+
|
|
1757
|
+
private getNestedItems(data: { [key: string]: Object }[], field: FieldsModel, givenText: string): { [key: string]: Object } {
|
|
1758
|
+
let newData: { [key: string]: Object };
|
|
1759
|
+
for (let i: number = 0, objlen: number = data.length; i < objlen; i++) {
|
|
1760
|
+
let dataId: Object = getValue(this.fields.text, data[i]);
|
|
1761
|
+
if (data[i] && dataId && dataId.toString() === givenText) {
|
|
1762
|
+
return data[i];
|
|
1763
|
+
} else if (typeof field.child === 'string' && !isNOU(getValue(field.child, data[i]))) {
|
|
1764
|
+
let childData: Object = getValue(field.child, data[i]);
|
|
1765
|
+
newData = this.getNestedItems(<{ [key: string]: Object }[]>childData, this.getChildType(field), givenText);
|
|
1766
|
+
if (newData !== undefined) {
|
|
1767
|
+
break;
|
|
1768
|
+
}
|
|
1769
|
+
} else if (this.fields.dataSource instanceof DataManager && !isNOU(getValue('child', data[i]))) {
|
|
1770
|
+
let child: string = 'child';
|
|
1771
|
+
newData = this.getNestedItems(<{ [key: string]: Object }[]>getValue(child, data[i]), this.getChildType(field), givenText);
|
|
1772
|
+
if (newData !== undefined) {
|
|
1773
|
+
break;
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
return newData;
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
private getChildType(mapper: FieldsModel): FieldsModel {
|
|
1781
|
+
return (typeof mapper.child === 'string' || isNOU(mapper.child)) ? mapper : mapper.child;
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
/* To render the treeview */
|
|
1785
|
+
private renderTree(): void {
|
|
1786
|
+
this.treeObj = new TreeView({
|
|
1787
|
+
fields: this.getTreeFields(this.fields),
|
|
1788
|
+
enableRtl: this.enableRtl,
|
|
1789
|
+
nodeSelected: this.onNodeSelected.bind(this),
|
|
1790
|
+
nodeChecked: this.onNodeChecked.bind(this),
|
|
1791
|
+
nodeChecking: this.beforeCheck.bind(this),
|
|
1792
|
+
actionFailure: this.onActionFailure.bind(this),
|
|
1793
|
+
nodeClicked: this.onNodeClicked.bind(this),
|
|
1794
|
+
dataBound: this.OnDataBound.bind(this),
|
|
1795
|
+
allowMultiSelection: this.allowMultiSelection,
|
|
1796
|
+
showCheckBox: this.showCheckBox,
|
|
1797
|
+
autoCheck: this.treeSettings.autoCheck,
|
|
1798
|
+
sortOrder: this.sortOrder,
|
|
1799
|
+
expandOn: this.treeSettings.expandOn,
|
|
1800
|
+
loadOnDemand: this.treeSettings.loadOnDemand,
|
|
1801
|
+
nodeSelecting: this.onBeforeSelect.bind(this),
|
|
1802
|
+
nodeTemplate: this.itemTemplate
|
|
1803
|
+
});
|
|
1804
|
+
this.treeObj.appendTo('#' + this.tree.id);
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
/* To render the popup element */
|
|
1808
|
+
private renderPopup(): void {
|
|
1809
|
+
if (this.isFilteredData) {
|
|
1810
|
+
this.filterObj.value = '';
|
|
1811
|
+
this.treeObj.fields = this.getTreeFields(this.fields);
|
|
1812
|
+
this.isFilterRestore = true;
|
|
1813
|
+
this.isFilteredData = false;
|
|
1814
|
+
this.hideCheckAll(false);
|
|
1815
|
+
}
|
|
1816
|
+
let isCancelled: boolean = false;
|
|
1817
|
+
let args: DdtBeforeOpenEventArgs = { cancel: false };
|
|
1818
|
+
this.trigger('beforeOpen', args, (args: DdtBeforeOpenEventArgs) => {
|
|
1819
|
+
if (!args.cancel) {
|
|
1820
|
+
addClass([this.inputWrapper], [ICONANIMATION]);
|
|
1821
|
+
if (this.isFirstRender) {
|
|
1822
|
+
this.popupEle = this.createElement('div', {
|
|
1823
|
+
id: this.element.id + '_popup', className: POPUP_CLASS + ' ' + (this.cssClass != null ? this.cssClass : '')
|
|
1824
|
+
});
|
|
1825
|
+
document.body.appendChild(this.popupEle);
|
|
1826
|
+
this.createPopup(this.popupEle);
|
|
1827
|
+
} else {
|
|
1828
|
+
this.popupEle = this.popupObj.element;
|
|
1829
|
+
}
|
|
1830
|
+
} else {
|
|
1831
|
+
isCancelled = true;
|
|
1832
|
+
}
|
|
1833
|
+
if (this.isFirstRender && !isCancelled) {
|
|
1834
|
+
prepend([this.popupDiv], this.popupEle);
|
|
1835
|
+
this.popupDiv.style.display = 'block';
|
|
1836
|
+
if (this.allowFiltering) { this.renderFilter(); }
|
|
1837
|
+
if (this.showCheckBox && this.showSelectAll && (!this.popupDiv.classList.contains(NODATA))) {
|
|
1838
|
+
this.createSelectAllWrapper();
|
|
1839
|
+
this.popupEle.insertBefore(this.checkAllParent, this.popupDiv);
|
|
1840
|
+
}
|
|
1841
|
+
if (this.headerTemplate) { this.setHeaderTemplate(); }
|
|
1842
|
+
if (this.footerTemplate) { this.setFooterTemplate(); }
|
|
1843
|
+
this.isFirstRender = false;
|
|
1844
|
+
}
|
|
1845
|
+
if (!isCancelled) {
|
|
1846
|
+
attributes(this.inputWrapper, { 'aria-expanded': 'true' });
|
|
1847
|
+
this.popupObj.show(null, (this.zIndex === 1000) ? this.inputEle : null);
|
|
1848
|
+
this.popupEle.style.display = 'block';
|
|
1849
|
+
this.updatePopupHeight();
|
|
1850
|
+
this.popupObj.refreshPosition();
|
|
1851
|
+
if (!(this.showCheckBox && this.showSelectAll) && (!this.popupDiv.classList.contains(NODATA)
|
|
1852
|
+
&& this.treeItems.length > 0)) {
|
|
1853
|
+
this.treeObj.element.focus();
|
|
1854
|
+
}
|
|
1855
|
+
if (this.checkSelectAll && this.checkBoxElement) {
|
|
1856
|
+
let wrap: HTMLElement = closest((this.checkBoxElement as HTMLElement), '.' + CHECKBOXWRAP) as HTMLElement;
|
|
1857
|
+
this.changeState(wrap, 'check');
|
|
1858
|
+
this.checkSelectAll = false;
|
|
1859
|
+
}
|
|
1860
|
+
if (this.allowFiltering) {
|
|
1861
|
+
removeClass([this.inputWrapper], [INPUTFOCUS]);
|
|
1862
|
+
this.filterObj.element.focus();
|
|
1863
|
+
}
|
|
1864
|
+
let eventArgs: DdtPopupEventArgs = { popup: this.popupObj };
|
|
1865
|
+
this.trigger('open', eventArgs);
|
|
1866
|
+
}
|
|
1867
|
+
});
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1870
|
+
private updatePopupHeight(): void {
|
|
1871
|
+
if (this.isFirstRender) {return; }
|
|
1872
|
+
let popupHeight: string = this.getHeight();
|
|
1873
|
+
this.popupEle.style.maxHeight = popupHeight;
|
|
1874
|
+
if (this.allowFiltering) {
|
|
1875
|
+
let height: number = Math.round(this.filterContainer.getBoundingClientRect().height);
|
|
1876
|
+
popupHeight = formatUnit(parseInt(popupHeight, 10) - height + 'px');
|
|
1877
|
+
}
|
|
1878
|
+
if (this.headerTemplate) {
|
|
1879
|
+
let height: number = Math.round(this.header.getBoundingClientRect().height);
|
|
1880
|
+
popupHeight = formatUnit(parseInt(popupHeight, 10) - height + 'px');
|
|
1881
|
+
}
|
|
1882
|
+
if (this.showCheckBox && this.showSelectAll) {
|
|
1883
|
+
let height: number = Math.round(this.checkAllParent.getBoundingClientRect().height);
|
|
1884
|
+
popupHeight = formatUnit(parseInt(popupHeight, 10) - height + 'px');
|
|
1885
|
+
}
|
|
1886
|
+
if (this.footerTemplate) {
|
|
1887
|
+
let height: number = Math.round(this.footer.getBoundingClientRect().height);
|
|
1888
|
+
popupHeight = formatUnit(parseInt(popupHeight, 10) - height + 'px');
|
|
1889
|
+
}
|
|
1890
|
+
let border: number = parseInt(window.getComputedStyle(this.popupEle).borderTopWidth, 10);
|
|
1891
|
+
border = border + parseInt(window.getComputedStyle(this.popupEle).borderBottomWidth, 10);
|
|
1892
|
+
popupHeight = formatUnit(parseInt(popupHeight, 10) - border + 'px');
|
|
1893
|
+
this.popupDiv.style.maxHeight = popupHeight;
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
private createPopup(element: HTMLElement): void {
|
|
1897
|
+
if (this.isFirstRender) {
|
|
1898
|
+
this.popupObj = new Popup(element, {
|
|
1899
|
+
width: this.setWidth(),
|
|
1900
|
+
targetType: 'relative',
|
|
1901
|
+
collision: { X: 'flip', Y: 'flip' },
|
|
1902
|
+
relateTo: this.inputWrapper,
|
|
1903
|
+
zIndex: this.zIndex,
|
|
1904
|
+
enableRtl: this.enableRtl,
|
|
1905
|
+
position: { X: 'left', Y: 'bottom' },
|
|
1906
|
+
close: () => {
|
|
1907
|
+
this.isPopupOpen = false;
|
|
1908
|
+
},
|
|
1909
|
+
open: () => {
|
|
1910
|
+
EventHandler.add(document, 'mousedown', this.onDocumentClick, this);
|
|
1911
|
+
this.isPopupOpen = true;
|
|
1912
|
+
},
|
|
1913
|
+
targetExitViewport: () => {
|
|
1914
|
+
if (!Browser.isDevice) { this.hidePopup(); }
|
|
1915
|
+
}
|
|
1916
|
+
});
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1920
|
+
/* To calculate the width when change via set model */
|
|
1921
|
+
private setElementWidth(inputWidth: string | number): void {
|
|
1922
|
+
let ddElement: HTMLElement = this.inputWrapper;
|
|
1923
|
+
if (!isNOU(inputWidth)) {
|
|
1924
|
+
if (typeof inputWidth === 'number') {
|
|
1925
|
+
ddElement.style.width = formatUnit(inputWidth);
|
|
1926
|
+
} else if (typeof inputWidth === 'string') {
|
|
1927
|
+
ddElement.style.width = (inputWidth.match(/px|%|em/)) ? (inputWidth) :
|
|
1928
|
+
(formatUnit(inputWidth));
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
}
|
|
1932
|
+
|
|
1933
|
+
/* To calculate the width of the popup */
|
|
1934
|
+
private setWidth(): string {
|
|
1935
|
+
let width: string = formatUnit(this.popupWidth);
|
|
1936
|
+
if (width.indexOf('%') > -1) {
|
|
1937
|
+
let inputWidth: number = this.inputWrapper.offsetWidth * parseFloat(width) / 100;
|
|
1938
|
+
width = inputWidth.toString() + 'px';
|
|
1939
|
+
} else if (typeof this.popupWidth === 'string') {
|
|
1940
|
+
width = (this.popupWidth.match(/px|em/)) ? (this.popupWidth) : width;
|
|
1941
|
+
}
|
|
1942
|
+
return width;
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1945
|
+
/* To calculate the height of the popup */
|
|
1946
|
+
private getHeight(): string {
|
|
1947
|
+
let height: string = formatUnit(this.popupHeight);
|
|
1948
|
+
if (height.indexOf('%') > -1) {
|
|
1949
|
+
// Will set the height of the popup according to the view port height
|
|
1950
|
+
let viewPortHeight: number = document.documentElement.clientHeight * parseFloat(height) / 100;
|
|
1951
|
+
height = viewPortHeight.toString() + 'px';
|
|
1952
|
+
} else if (typeof this.popupHeight === 'string') {
|
|
1953
|
+
height = (this.popupHeight.match(/px|em/)) ? (this.popupHeight) : height;
|
|
1954
|
+
}
|
|
1955
|
+
return height;
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1958
|
+
private onDocumentClick(e: MouseEvent): void {
|
|
1959
|
+
let target: HTMLElement = <HTMLElement>e.target;
|
|
1960
|
+
let isTree: Element = closest(target, '.' + PARENTITEM);
|
|
1961
|
+
let isFilter: Element = closest(target, '.' + FILTERWRAP);
|
|
1962
|
+
let isScroller: boolean = target.classList.contains(DROPDOWN) ? true :
|
|
1963
|
+
(matches(target, '.e-ddt .e-popup') || matches(target, '.e-ddt .e-treeview'));
|
|
1964
|
+
if ((this.isPopupOpen && (this.inputWrapper.contains(target) || isTree || isFilter || isScroller)) ||
|
|
1965
|
+
((this.allowMultiSelection || this.showCheckBox) && (this.isPopupOpen && target.classList.contains(CHIP_CLOSE) ||
|
|
1966
|
+
(this.isPopupOpen && (target.classList.contains(CHECKALLPARENT) || target.classList.contains(ALLTEXT)
|
|
1967
|
+
|| target.classList.contains(CHECKBOXFRAME)))))) {
|
|
1968
|
+
this.isDocumentClick = false;
|
|
1969
|
+
e.preventDefault();
|
|
1970
|
+
} else if (!this.inputWrapper.contains(target) && this.inputFocus) {
|
|
1971
|
+
this.focusOut(e);
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
|
|
1975
|
+
private onActionFailure(e: FailureEventArgs): void {
|
|
1976
|
+
this.trigger('actionFailure', e);
|
|
1977
|
+
this.l10nUpdate(true);
|
|
1978
|
+
addClass([this.popupDiv], NODATA);
|
|
1979
|
+
}
|
|
1980
|
+
|
|
1981
|
+
private OnDataBound(args: DataBoundEventArgs): void {
|
|
1982
|
+
this.treeItems = args.data;
|
|
1983
|
+
if (this.treeItems.length <= 0) {
|
|
1984
|
+
this.l10nUpdate();
|
|
1985
|
+
addClass([this.popupDiv], NODATA);
|
|
1986
|
+
this.hideCheckAll(true);
|
|
1987
|
+
} else if (this.popupDiv.classList.contains(NODATA) && this.treeItems.length >= 1) {
|
|
1988
|
+
removeClass([this.popupDiv], NODATA);
|
|
1989
|
+
this.hideCheckAll(false);
|
|
1990
|
+
}
|
|
1991
|
+
this.treeDataType = this.getTreeDataType(this.treeItems, this.fields);
|
|
1992
|
+
if (this.isFirstRender && this.isRemoteData) {
|
|
1993
|
+
this.setTreeValue();
|
|
1994
|
+
this.setTreeText();
|
|
1995
|
+
this.updateHiddenValue();
|
|
1996
|
+
this.setSelectedValue();
|
|
1997
|
+
this.treeObj.element.focus();
|
|
1998
|
+
}
|
|
1999
|
+
let eventArgs: DdtDataBoundEventArgs = { data: args.data };
|
|
2000
|
+
this.trigger('dataBound', eventArgs);
|
|
2001
|
+
if (this.isFilteredData) { this.treeObj.expandAll(); }
|
|
2002
|
+
if (this.isFilterRestore) {
|
|
2003
|
+
this.restoreFilterSelection();
|
|
2004
|
+
this.isFilterRestore = false;
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
|
|
2008
|
+
private restoreFilterSelection(): void {
|
|
2009
|
+
if (this.showCheckBox) {
|
|
2010
|
+
this.treeObj.checkedNodes = this.value ? this.value : [];
|
|
2011
|
+
} else {
|
|
2012
|
+
this.treeObj.selectedNodes = this.value ? this.value : [];
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
/* To set cssclass for the dropdowntree */
|
|
2017
|
+
private setCssClass(newClass: string, oldClass: string): void {
|
|
2018
|
+
let elements: HTMLElement[] = this.popupObj ? [this.inputWrapper, this.popupObj.element] : [this.inputWrapper];
|
|
2019
|
+
if (!isNOU(oldClass) && oldClass !== '') {
|
|
2020
|
+
removeClass(elements, oldClass.split(' '));
|
|
2021
|
+
}
|
|
2022
|
+
if (!isNOU(newClass) && newClass !== '') {
|
|
2023
|
+
addClass(elements, newClass.split(' '));
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
private setEnableRTL(state: boolean): void {
|
|
2028
|
+
if (state) {
|
|
2029
|
+
this.inputWrapper.classList.add(RTL);
|
|
2030
|
+
} else {
|
|
2031
|
+
this.inputWrapper.classList.remove(RTL);
|
|
2032
|
+
}
|
|
2033
|
+
if (this.popupObj) {
|
|
2034
|
+
this.popupObj.enableRtl = state;
|
|
2035
|
+
this.popupObj.dataBind();
|
|
2036
|
+
}
|
|
2037
|
+
if (this.treeObj) {
|
|
2038
|
+
this.treeObj.enableRtl = state;
|
|
2039
|
+
this.treeObj.dataBind();
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
/* To set enable property */
|
|
2044
|
+
private setEnable(): void {
|
|
2045
|
+
Input.setEnabled(this.enabled, this.inputEle);
|
|
2046
|
+
if (this.enabled) {
|
|
2047
|
+
removeClass([this.inputWrapper], DISABLED);
|
|
2048
|
+
this.inputEle.setAttribute('aria-disabled', 'false');
|
|
2049
|
+
this.inputWrapper.setAttribute('aria-disabled', 'false');
|
|
2050
|
+
} else {
|
|
2051
|
+
if (this.isPopupOpen) {
|
|
2052
|
+
this.hidePopup();
|
|
2053
|
+
}
|
|
2054
|
+
addClass([this.inputWrapper], DISABLED);
|
|
2055
|
+
if (this.inputWrapper && this.inputWrapper.classList.contains(INPUTFOCUS)) {
|
|
2056
|
+
removeClass([this.inputWrapper], [INPUTFOCUS]);
|
|
2057
|
+
}
|
|
2058
|
+
this.inputEle.setAttribute('aria-disabled', 'true');
|
|
2059
|
+
this.inputWrapper.setAttribute('aria-disabled', 'true');
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
private cloneFields(fields: FieldsModel): FieldsModel {
|
|
2063
|
+
let clonedField: FieldsModel = {
|
|
2064
|
+
dataSource: fields.dataSource, value: fields.value, text: fields.text, parentValue: fields.parentValue,
|
|
2065
|
+
child: this.cloneChildField(fields.child), hasChildren: fields.hasChildren, expanded: fields.expanded,
|
|
2066
|
+
iconCss: fields.iconCss, imageUrl: fields.imageUrl, htmlAttributes: fields.htmlAttributes, query: fields.query,
|
|
2067
|
+
selected: fields.selected, tableName: fields.tableName, tooltip: fields.tooltip
|
|
2068
|
+
};
|
|
2069
|
+
return clonedField;
|
|
2070
|
+
}
|
|
2071
|
+
private cloneChildField(fields: FieldsModel | string): string | FieldsModel {
|
|
2072
|
+
if (typeof fields === 'string') {
|
|
2073
|
+
return fields;
|
|
2074
|
+
} else {
|
|
2075
|
+
let clonedField: FieldsModel = {
|
|
2076
|
+
dataSource: fields.dataSource, value: fields.value, text: fields.text, parentValue: fields.parentValue,
|
|
2077
|
+
child: (fields.child ? this.cloneChildField(fields.child) : null), hasChildren: fields.hasChildren,
|
|
2078
|
+
expanded: fields.expanded, iconCss: fields.iconCss, imageUrl: fields.imageUrl, htmlAttributes: fields.htmlAttributes,
|
|
2079
|
+
query: fields.query, selected: fields.selected, tableName: fields.tableName, tooltip: fields.tooltip
|
|
2080
|
+
};
|
|
2081
|
+
return clonedField;
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
|
|
2085
|
+
private getTreeFields(fields: FieldsModel): FieldsSettingsModel {
|
|
2086
|
+
let treeFields: FieldsSettingsModel = {
|
|
2087
|
+
dataSource: fields.dataSource, id: fields.value, text: fields.text, parentID: fields.parentValue,
|
|
2088
|
+
child: this.getTreeChildren(fields.child), hasChildren: fields.hasChildren, expanded: fields.expanded,
|
|
2089
|
+
iconCss: fields.iconCss, imageUrl: fields.imageUrl, isChecked: fields.selected,
|
|
2090
|
+
htmlAttributes: fields.htmlAttributes, query: fields.query, selected: fields.selected,
|
|
2091
|
+
tableName: fields.tableName, tooltip: fields.tooltip
|
|
2092
|
+
};
|
|
2093
|
+
return treeFields;
|
|
2094
|
+
}
|
|
2095
|
+
|
|
2096
|
+
private getTreeChildren(mapper: FieldsModel | string): FieldsSettingsModel | string {
|
|
2097
|
+
if (typeof mapper === 'string') {
|
|
2098
|
+
return mapper;
|
|
2099
|
+
} else if (!isNOU(mapper)) {
|
|
2100
|
+
let childFields: FieldsSettingsModel | string;
|
|
2101
|
+
mapper = this.getActualProperties(mapper) as FieldsModel;
|
|
2102
|
+
childFields = mapper;
|
|
2103
|
+
if (mapper.value) {
|
|
2104
|
+
childFields.id = mapper.value;
|
|
2105
|
+
}
|
|
2106
|
+
if (mapper.parentValue) {
|
|
2107
|
+
childFields.parentID = mapper.parentValue;
|
|
2108
|
+
}
|
|
2109
|
+
if (mapper.child) {
|
|
2110
|
+
childFields.child = this.getTreeChildren(mapper.child);
|
|
2111
|
+
}
|
|
2112
|
+
if (mapper.selected && this.showCheckBox) {
|
|
2113
|
+
childFields.isChecked = mapper.selected;
|
|
2114
|
+
}
|
|
2115
|
+
return childFields;
|
|
2116
|
+
}
|
|
2117
|
+
return null;
|
|
2118
|
+
}
|
|
2119
|
+
|
|
2120
|
+
private getTreeDataType(ds: { [key: string]: Object }[], field: FieldsModel): number {
|
|
2121
|
+
if (this.fields.dataSource instanceof DataManager) {
|
|
2122
|
+
for (let i: number = 0; i < ds.length; i++) {
|
|
2123
|
+
if ((typeof field.child === 'string') && isNOU(getValue(field.child, ds[i]))) {
|
|
2124
|
+
return 1;
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
return 2;
|
|
2128
|
+
}
|
|
2129
|
+
for (let i: number = 0, len: number = ds.length; i < len; i++) {
|
|
2130
|
+
if ((typeof field.child === 'string') && !isNOU(getValue(field.child, ds[i]))) {
|
|
2131
|
+
return 2;
|
|
2132
|
+
}
|
|
2133
|
+
if (!isNOU(getValue(field.parentValue, ds[i])) || !isNOU(getValue(field.hasChildren, ds[i]))) {
|
|
2134
|
+
return 1;
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2137
|
+
return 1;
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
/* Triggers when the tree fields is changed dynamically */
|
|
2141
|
+
private setFields(): void {
|
|
2142
|
+
this.resetValue();
|
|
2143
|
+
this.treeObj.fields = this.getTreeFields(this.fields);
|
|
2144
|
+
this.treeObj.dataBind();
|
|
2145
|
+
}
|
|
2146
|
+
private getEventArgs(args: NodeCheckEventArgs | NodeSelectEventArgs): DdtSelectEventArgs {
|
|
2147
|
+
let checkData: { [key: string]: Object }[] = (args as NodeCheckEventArgs).data;
|
|
2148
|
+
let selectData: { [key: string]: Object } = (args as NodeSelectEventArgs).nodeData;
|
|
2149
|
+
let state: string;
|
|
2150
|
+
if (this.showCheckBox) {
|
|
2151
|
+
if (args.action === 'check') {
|
|
2152
|
+
state = 'select';
|
|
2153
|
+
} else if (args.action === 'uncheck') {
|
|
2154
|
+
state = 'un-select';
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
let eventArgs: DdtSelectEventArgs = {
|
|
2158
|
+
action: this.showCheckBox ? state : args.action,
|
|
2159
|
+
isInteracted: args.isInteracted,
|
|
2160
|
+
item: args.node,
|
|
2161
|
+
itemData: this.showCheckBox ? checkData[0] : selectData
|
|
2162
|
+
};
|
|
2163
|
+
return eventArgs;
|
|
2164
|
+
}
|
|
2165
|
+
|
|
2166
|
+
private onBeforeSelect(args: NodeSelectEventArgs): void {
|
|
2167
|
+
if (args.isInteracted) {
|
|
2168
|
+
this.oldValue = this.value ? this.value.slice() : this.value;
|
|
2169
|
+
if (this.value === null) {
|
|
2170
|
+
this.setProperties({ value: [] }, true);
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
|
|
2175
|
+
private updateHiddenValue(): void {
|
|
2176
|
+
if (this.allowMultiSelection || this.showCheckBox) {
|
|
2177
|
+
return;
|
|
2178
|
+
}
|
|
2179
|
+
if (this.value && this.value.length) {
|
|
2180
|
+
this.hiddenElement.innerHTML = '<option selected value ="' + this.value[0] + '">' + this.text + '</option>';
|
|
2181
|
+
} else {
|
|
2182
|
+
this.hiddenElement.innerHTML = '';
|
|
2183
|
+
}
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
/* Triggers when the tree node is selected */
|
|
2187
|
+
private onNodeSelected(args: NodeSelectEventArgs): void {
|
|
2188
|
+
if (this.showCheckBox) {
|
|
2189
|
+
return;
|
|
2190
|
+
}
|
|
2191
|
+
let selectedText: string;
|
|
2192
|
+
if (args.isInteracted) {
|
|
2193
|
+
let id: string = getValue('id', args.nodeData).toString();
|
|
2194
|
+
if (!this.allowMultiSelection) {
|
|
2195
|
+
this.hiddenElement.innerHTML = '';
|
|
2196
|
+
this.setProperties({ value: [id] }, true);
|
|
2197
|
+
if (this.itemTemplate) {
|
|
2198
|
+
selectedText = getValue('text', this.treeObj.getNode(id));
|
|
2199
|
+
} else {
|
|
2200
|
+
selectedText = getValue('text', args.nodeData).toString();
|
|
2201
|
+
}
|
|
2202
|
+
Input.setValue(selectedText, this.inputEle, this.floatLabelType);
|
|
2203
|
+
this.setProperties({ text: selectedText }, true);
|
|
2204
|
+
this.currentText = this.text;
|
|
2205
|
+
this.currentValue = this.value;
|
|
2206
|
+
attributes(this.inputWrapper, { 'aria-describedby': this.element.id });
|
|
2207
|
+
attributes(this.inputWrapper, { 'aria-activedescendant': id.toString() });
|
|
2208
|
+
this.updateHiddenValue();
|
|
2209
|
+
this.showOverAllClear();
|
|
2210
|
+
this.hidePopup();
|
|
2211
|
+
this.isNodeSelected = true;
|
|
2212
|
+
} else if (this.allowMultiSelection) {
|
|
2213
|
+
this.setMultiSelect();
|
|
2214
|
+
}
|
|
2215
|
+
}
|
|
2216
|
+
let eventArgs: DdtSelectEventArgs = this.getEventArgs(args);
|
|
2217
|
+
this.trigger('select', eventArgs);
|
|
2218
|
+
if (this.isValueChange && !this.changeOnBlur) {
|
|
2219
|
+
this.triggerChangeEvent(this.keyEventArgs);
|
|
2220
|
+
this.isValueChange = false;
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2224
|
+
private onNodeClicked(args: NodeClickEventArgs): void {
|
|
2225
|
+
if (!this.changeOnBlur && this.isNodeSelected) {
|
|
2226
|
+
this.triggerChangeEvent(args.event);
|
|
2227
|
+
this.isNodeSelected = false;
|
|
2228
|
+
}
|
|
2229
|
+
let target: Element = <Element>args.event.target;
|
|
2230
|
+
if ((target.classList.contains('e-fullrow') || target.classList.contains('e-list-text')) && this.showCheckBox) {
|
|
2231
|
+
let getNodeDetails: { [key: string]: Object } = this.treeObj.getNode(args.node);
|
|
2232
|
+
if (getNodeDetails.isChecked === 'true') {
|
|
2233
|
+
this.treeObj.uncheckAll([args.node]);
|
|
2234
|
+
} else {
|
|
2235
|
+
this.treeObj.checkAll([args.node]);
|
|
2236
|
+
}
|
|
2237
|
+
this.setMultiSelect();
|
|
2238
|
+
this.ensurePlaceHolder();
|
|
2239
|
+
}
|
|
2240
|
+
if (!this.changeOnBlur && (this.allowMultiSelection || this.showCheckBox)) {
|
|
2241
|
+
this.triggerChangeEvent(args.event);
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2245
|
+
private onNodeChecked(args: NodeCheckEventArgs): void {
|
|
2246
|
+
let eventArgs: DdtSelectEventArgs = this.getEventArgs(args);
|
|
2247
|
+
this.trigger('select', eventArgs);
|
|
2248
|
+
if (this.isFilteredData && args.action === 'uncheck') {
|
|
2249
|
+
let id: string = getValue('id', args.data[0]).toString();
|
|
2250
|
+
this.removeSelectedData(id , true);
|
|
2251
|
+
}
|
|
2252
|
+
if (!this.isChipDelete && args.isInteracted) {
|
|
2253
|
+
this.setMultiSelect();
|
|
2254
|
+
this.ensurePlaceHolder();
|
|
2255
|
+
}
|
|
2256
|
+
if (this.showSelectAll && this.checkBoxElement) {
|
|
2257
|
+
let nodes: NodeList = this.treeObj.element.querySelectorAll('li');
|
|
2258
|
+
let checkedNodes: NodeList = this.treeObj.element.querySelectorAll('li .e-checkbox-wrapper[aria-checked=true]');
|
|
2259
|
+
let wrap: HTMLElement = closest((this.checkBoxElement as HTMLElement), '.' + CHECKBOXWRAP) as HTMLElement;
|
|
2260
|
+
if (wrap && args.action === 'uncheck') {
|
|
2261
|
+
this.isReverseUpdate = true;
|
|
2262
|
+
this.changeState(wrap, 'uncheck');
|
|
2263
|
+
this.isReverseUpdate = false;
|
|
2264
|
+
} else if (wrap && args.action === 'check' && checkedNodes.length === nodes.length) {
|
|
2265
|
+
this.isReverseUpdate = true;
|
|
2266
|
+
this.changeState(wrap, 'check');
|
|
2267
|
+
this.isReverseUpdate = false;
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
|
|
2272
|
+
private beforeCheck(args: NodeCheckEventArgs): void {
|
|
2273
|
+
if (args.isInteracted) {
|
|
2274
|
+
this.oldValue = this.value ? this.value.slice() : this.value;
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2278
|
+
private updateClearButton(state: boolean): void {
|
|
2279
|
+
if (state) {
|
|
2280
|
+
if (!this.inputWrapper.contains(this.overAllClear)) {
|
|
2281
|
+
this.inputEle.parentElement.insertBefore(this.overAllClear, this.inputEle.nextSibling);
|
|
2282
|
+
} else {
|
|
2283
|
+
removeClass([this.overAllClear], HIDEICON);
|
|
2284
|
+
addClass([this.inputWrapper], SHOW_CLEAR);
|
|
2285
|
+
}
|
|
2286
|
+
} else {
|
|
2287
|
+
addClass([this.overAllClear], HIDEICON);
|
|
2288
|
+
removeClass([this.inputWrapper], SHOW_CLEAR);
|
|
2289
|
+
}
|
|
2290
|
+
if ((this.allowMultiSelection || this.showCheckBox) && this.chipWrapper) {
|
|
2291
|
+
let chipClose: Element[] = selectAll('.' + CHIP_CLOSE, this.chipWrapper);
|
|
2292
|
+
for (let i: number = 0; i < chipClose.length; i++) {
|
|
2293
|
+
if (!state) {
|
|
2294
|
+
addClass([chipClose[i]], HIDEICON);
|
|
2295
|
+
} else {
|
|
2296
|
+
removeClass([chipClose[i]], HIDEICON);
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2302
|
+
private updateDropDownIconState(state: boolean): void {
|
|
2303
|
+
let spinIcon: Element = select('.' + DDTICON, this.inputWrapper);
|
|
2304
|
+
if (state) {
|
|
2305
|
+
if (!spinIcon) {
|
|
2306
|
+
Input.appendSpan(DROPDOWNICON, this.inputWrapper, this.createElement);
|
|
2307
|
+
} else {
|
|
2308
|
+
removeClass([spinIcon], HIDEICON);
|
|
2309
|
+
}
|
|
2310
|
+
addClass([this.inputWrapper], SHOW_DD_ICON);
|
|
2311
|
+
} else {
|
|
2312
|
+
addClass([spinIcon], HIDEICON);
|
|
2313
|
+
removeClass([this.inputWrapper], SHOW_DD_ICON);
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
|
|
2317
|
+
private updateMode(): void {
|
|
2318
|
+
if (this.mode !== 'Delimiter') {
|
|
2319
|
+
if (!this.inputWrapper.contains(this.chipWrapper)) {
|
|
2320
|
+
this.createChip();
|
|
2321
|
+
}
|
|
2322
|
+
let isValid: boolean = this.getValidMode();
|
|
2323
|
+
if (this.chipWrapper.classList.contains(HIDEICON) && isValid) {
|
|
2324
|
+
removeClass([this.chipWrapper], HIDEICON);
|
|
2325
|
+
addClass([this.inputWrapper], SHOW_CHIP);
|
|
2326
|
+
} else if (!isValid) {
|
|
2327
|
+
addClass([this.chipWrapper], HIDEICON);
|
|
2328
|
+
removeClass([this.inputWrapper], SHOW_CHIP);
|
|
2329
|
+
}
|
|
2330
|
+
let isValue: boolean = this.value !== null ? (this.value.length !== 0 ? true : false) : false;
|
|
2331
|
+
if (isValid && isValue) {
|
|
2332
|
+
addClass([this.inputEle], CHIP_INPUT);
|
|
2333
|
+
} else {
|
|
2334
|
+
removeClass([this.inputEle], CHIP_INPUT);
|
|
2335
|
+
}
|
|
2336
|
+
} else if (this.inputEle.classList.contains(CHIP_INPUT)) {
|
|
2337
|
+
removeClass([this.inputEle], CHIP_INPUT);
|
|
2338
|
+
if (this.chipWrapper) {
|
|
2339
|
+
addClass([this.chipWrapper], HIDEICON);
|
|
2340
|
+
removeClass([this.inputWrapper], SHOW_CHIP);
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
|
|
2345
|
+
private ensurePlaceHolder(): void {
|
|
2346
|
+
if (this.value && this.value.length === 0) {
|
|
2347
|
+
removeClass([this.inputEle], CHIP_INPUT);
|
|
2348
|
+
if (this.chipWrapper) {
|
|
2349
|
+
addClass([this.chipWrapper], HIDEICON);
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
private ensureClearIconPosition(floatLabelType: FloatLabelType): void {
|
|
2354
|
+
if (floatLabelType !== 'Never') {
|
|
2355
|
+
this.inputWrapper.insertBefore(this.overAllClear, this.inputObj.buttons[0]);
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
|
|
2359
|
+
private setMultiSelectValue(newValues: string[]): void {
|
|
2360
|
+
if (!this.isFilteredData) {
|
|
2361
|
+
this.setProperties({ value: newValues }, true);
|
|
2362
|
+
if (newValues && newValues.length !== 0 && !this.showCheckBox) {
|
|
2363
|
+
this.treeObj.selectedNodes = this.value.slice();
|
|
2364
|
+
this.treeObj.dataBind();
|
|
2365
|
+
}
|
|
2366
|
+
} else {
|
|
2367
|
+
let selectedValues: string[] = isNOU(this.value) ? [] : this.value;
|
|
2368
|
+
for (let i: number = 0; i < newValues.length; i++) {
|
|
2369
|
+
if (isNOU(this.value) || this.value.indexOf(newValues[i]) === -1) {
|
|
2370
|
+
selectedValues.push(newValues[i]);
|
|
2371
|
+
}
|
|
2372
|
+
}
|
|
2373
|
+
this.setProperties({ value: selectedValues }, true);
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
|
|
2377
|
+
private setMultiSelect(): void {
|
|
2378
|
+
if (this.showCheckBox && !this.isDynamicChange) {
|
|
2379
|
+
this.setMultiSelectValue(this.treeObj.checkedNodes);
|
|
2380
|
+
} else {
|
|
2381
|
+
let ddtValue: string[] = this.allowMultiSelection ? (this.showCheckBox ? this.treeObj.checkedNodes
|
|
2382
|
+
: this.treeObj.selectedNodes) : (this.value ? (this.showCheckBox ? this.value : [this.value[0]]) : null);
|
|
2383
|
+
this.setMultiSelectValue(ddtValue);
|
|
2384
|
+
if (this.showCheckBox && this.value !== null) {
|
|
2385
|
+
this.treeObj.checkedNodes = this.value;
|
|
2386
|
+
this.treeObj.dataBind();
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
this.selectedText = [];
|
|
2390
|
+
let checkSelection: boolean = this.allowMultiSelection ? true : (this.showCheckBox ? true : false);
|
|
2391
|
+
if (this.inputWrapper.contains(this.chipWrapper) && !checkSelection) {
|
|
2392
|
+
removeClass([this.inputEle], CHIP_INPUT);
|
|
2393
|
+
detach(this.chipWrapper);
|
|
2394
|
+
}
|
|
2395
|
+
let isValid: boolean = this.getValidMode();
|
|
2396
|
+
if (isValid && this.value !== null) {
|
|
2397
|
+
addClass([this.inputEle], CHIP_INPUT);
|
|
2398
|
+
if (this.chipWrapper) {
|
|
2399
|
+
removeClass([this.chipWrapper], HIDEICON);
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
let isValue: boolean = this.value ? (this.value.length ? true : false) : false;
|
|
2403
|
+
if (this.chipWrapper && (this.mode === 'Box' && !isValue)) {
|
|
2404
|
+
addClass([this.chipWrapper], HIDEICON);
|
|
2405
|
+
removeClass([this.inputEle], CHIP_INPUT);
|
|
2406
|
+
}
|
|
2407
|
+
this.updateSelectedValues();
|
|
2408
|
+
}
|
|
2409
|
+
|
|
2410
|
+
private getSelectedData(value: string): { [key: string]: Object } {
|
|
2411
|
+
let data: { [key: string]: Object } = null;
|
|
2412
|
+
if (this.isFilteredData) {
|
|
2413
|
+
for (let i: number = 0; i < this.selectedData.length; i++) {
|
|
2414
|
+
if (getValue(this.treeSettings.loadOnDemand ? this.fields.value : 'id', this.selectedData[i]).toString() === value) {
|
|
2415
|
+
data = this.selectedData[i];
|
|
2416
|
+
break;
|
|
2417
|
+
}
|
|
2418
|
+
}
|
|
2419
|
+
}
|
|
2420
|
+
if (isNOU(data)) {
|
|
2421
|
+
if (this.treeSettings.loadOnDemand) {
|
|
2422
|
+
data = this.treeObj.getTreeData(value)[0];
|
|
2423
|
+
} else {
|
|
2424
|
+
data = this.treeObj.getNode(value);
|
|
2425
|
+
}
|
|
2426
|
+
if (!isNOU(data)) { this.selectedData.push(data); }
|
|
2427
|
+
}
|
|
2428
|
+
return data;
|
|
2429
|
+
}
|
|
2430
|
+
|
|
2431
|
+
private removeSelectedData(value: string, muteOnChange: boolean): void {
|
|
2432
|
+
let selectedValues: string[] = isNOU(this.value) ? [] : this.value.slice();
|
|
2433
|
+
selectedValues.splice(selectedValues.indexOf(value), 1);
|
|
2434
|
+
this.setProperties({ value: selectedValues }, muteOnChange);
|
|
2435
|
+
for (let i: number = 0; i < this.selectedData.length; i++) {
|
|
2436
|
+
if (getValue(this.treeSettings.loadOnDemand ? this.fields.value : 'id', this.selectedData[i]).toString() === value) {
|
|
2437
|
+
this.selectedData.splice(i, 1);
|
|
2438
|
+
break;
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
private updateSelectedValues(): void {
|
|
2444
|
+
this.dataValue = '';
|
|
2445
|
+
let temp: string;
|
|
2446
|
+
let text: string;
|
|
2447
|
+
let textValue: string = '';
|
|
2448
|
+
let selectedData: { [key: string]: Object };
|
|
2449
|
+
this.hiddenElement.innerHTML = '';
|
|
2450
|
+
if ((!this.isChipDelete || this.treeSettings.autoCheck) && (this.inputWrapper.contains(this.chipWrapper))) {
|
|
2451
|
+
this.chipCollection.innerHTML = '';
|
|
2452
|
+
}
|
|
2453
|
+
if (!this.isFilteredData) { this.selectedData = []; }
|
|
2454
|
+
if (!isNOU(this.value)) {
|
|
2455
|
+
for (let i: number = 0, len: number = this.value.length; i < len; i++) {
|
|
2456
|
+
selectedData = this.getSelectedData(this.value[i]);
|
|
2457
|
+
text = getValue(this.treeSettings.loadOnDemand ? this.fields.text : 'text', selectedData);
|
|
2458
|
+
this.selectedText.push(text);
|
|
2459
|
+
temp = this.selectedText[this.selectedText.length - 1];
|
|
2460
|
+
if (this.selectedText.length > 1) {
|
|
2461
|
+
this.dataValue += (this.delimiterChar + ' ' + temp);
|
|
2462
|
+
textValue += (',' + temp);
|
|
2463
|
+
this.setProperties({ text: textValue }, true);
|
|
2464
|
+
} else {
|
|
2465
|
+
this.dataValue += temp;
|
|
2466
|
+
textValue += temp;
|
|
2467
|
+
}
|
|
2468
|
+
if (this.mode !== 'Delimiter' && (!this.isChipDelete || this.treeSettings.autoCheck) &&
|
|
2469
|
+
(this.allowMultiSelection || this.showCheckBox)) {
|
|
2470
|
+
this.setChipValues(temp, this.value[i]);
|
|
2471
|
+
}
|
|
2472
|
+
this.hiddenElement.innerHTML += '<option selected value ="' + this.value[i] + '">' +
|
|
2473
|
+
this.selectedText[this.selectedText.length - 1] + '</option>';
|
|
2474
|
+
}
|
|
2475
|
+
}
|
|
2476
|
+
let isValid: boolean = this.getValidMode();
|
|
2477
|
+
if (this.mode !== 'Box' && (this.allowMultiSelection || this.showCheckBox) && !isValid) {
|
|
2478
|
+
if (this.chipWrapper) {
|
|
2479
|
+
addClass([this.chipWrapper], HIDEICON);
|
|
2480
|
+
removeClass([this.inputWrapper], SHOW_CHIP);
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
Input.setValue(this.dataValue, this.inputEle, this.floatLabelType);
|
|
2484
|
+
if (textValue === '') {
|
|
2485
|
+
this.setProperties({ text: null }, true);
|
|
2486
|
+
} else {
|
|
2487
|
+
this.setProperties({ text: textValue }, true);
|
|
2488
|
+
}
|
|
2489
|
+
if (this.showClearButton && this.inputFocus) {
|
|
2490
|
+
this.showOverAllClear();
|
|
2491
|
+
}
|
|
2492
|
+
if ((this.allowMultiSelection || this.showCheckBox) && this.popupObj) {
|
|
2493
|
+
this.popupObj.refreshPosition();
|
|
2494
|
+
}
|
|
2495
|
+
this.currentText = this.text;
|
|
2496
|
+
this.currentValue = this.value;
|
|
2497
|
+
}
|
|
2498
|
+
private setChipValues(text: string, value: string): void {
|
|
2499
|
+
if (!this.inputWrapper.contains(this.chipWrapper)) {
|
|
2500
|
+
this.createChip();
|
|
2501
|
+
}
|
|
2502
|
+
let chip: HTMLElement = this.createElement('span', {
|
|
2503
|
+
className: CHIP,
|
|
2504
|
+
attrs: { 'data-value': <string>value }
|
|
2505
|
+
});
|
|
2506
|
+
let chipContent: HTMLElement = this.createElement('span', { className: CHIP_CONTENT });
|
|
2507
|
+
let chipClose: HTMLElement = this.createElement('span', { className: CHIP_CLOSE + ' ' + ICONS });
|
|
2508
|
+
chipContent.innerHTML = text;
|
|
2509
|
+
chip.appendChild(chipContent);
|
|
2510
|
+
this.chipCollection.appendChild(chip);
|
|
2511
|
+
if (this.showClearButton) {
|
|
2512
|
+
chip.appendChild(chipClose);
|
|
2513
|
+
EventHandler.add(chipClose, 'mousedown', this.removeChip, this);
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2517
|
+
private setSelectAllWrapper(state: boolean): void {
|
|
2518
|
+
if (this.isFirstRender) {return; }
|
|
2519
|
+
if (state && !this.popupEle.contains(this.checkAllParent) && this.showCheckBox) {
|
|
2520
|
+
this.createSelectAllWrapper();
|
|
2521
|
+
this.popupEle.insertBefore(this.checkAllParent, this.popupDiv);
|
|
2522
|
+
} else if (this.popupEle.contains(this.checkAllParent)) {
|
|
2523
|
+
detach(this.checkAllParent);
|
|
2524
|
+
this.checkAllParent = null;
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
|
|
2528
|
+
private setHeaderTemplate(): void {
|
|
2529
|
+
let compiledString: Function;
|
|
2530
|
+
if (this.header) {
|
|
2531
|
+
this.header.innerHTML = '';
|
|
2532
|
+
} else {
|
|
2533
|
+
this.header = this.createElement('div');
|
|
2534
|
+
addClass([this.header], HEADER);
|
|
2535
|
+
}
|
|
2536
|
+
compiledString = this.templateComplier(this.headerTemplate);
|
|
2537
|
+
for (let item of compiledString({}, null, null, this.headerTemplateId, this.isStringTemplate)) {
|
|
2538
|
+
this.header.appendChild(item);
|
|
2539
|
+
}
|
|
2540
|
+
this.ddtupdateBlazorTemplates(false, false, true, false);
|
|
2541
|
+
this.popupEle.insertBefore(this.header, this.checkAllParent ? this.checkAllParent : this.popupDiv);
|
|
2542
|
+
}
|
|
2543
|
+
|
|
2544
|
+
private templateComplier(template: string): Function {
|
|
2545
|
+
if (template) {
|
|
2546
|
+
let e: Object;
|
|
2547
|
+
try {
|
|
2548
|
+
if (document.querySelectorAll(template).length) {
|
|
2549
|
+
return compile(document.querySelector(template).innerHTML.trim());
|
|
2550
|
+
}
|
|
2551
|
+
} catch (e) {
|
|
2552
|
+
return compile(template);
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
return compile(template);
|
|
2556
|
+
}
|
|
2557
|
+
|
|
2558
|
+
|
|
2559
|
+
private setFooterTemplate(): void {
|
|
2560
|
+
let compiledString: Function;
|
|
2561
|
+
if (this.footer) {
|
|
2562
|
+
this.footer.innerHTML = '';
|
|
2563
|
+
} else {
|
|
2564
|
+
this.footer = this.createElement('div');
|
|
2565
|
+
addClass([this.footer], FOOTER);
|
|
2566
|
+
}
|
|
2567
|
+
compiledString = this.templateComplier(this.footerTemplate);
|
|
2568
|
+
for (let item of compiledString({}, null, null, this.footerTemplateId, this.isStringTemplate)) {
|
|
2569
|
+
this.footer.appendChild(item);
|
|
2570
|
+
}
|
|
2571
|
+
this.ddtupdateBlazorTemplates(false, false, false, true);
|
|
2572
|
+
append([this.footer], this.popupEle);
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2575
|
+
private clearAll(e?: MouseEvent): void {
|
|
2576
|
+
if (!this.enabled || this.readonly) {
|
|
2577
|
+
return;
|
|
2578
|
+
}
|
|
2579
|
+
this.resetValue();
|
|
2580
|
+
this.showOverAllClear();
|
|
2581
|
+
if ((this.allowMultiSelection || this.showCheckBox) && this.popupObj) {
|
|
2582
|
+
this.popupObj.refreshPosition();
|
|
2583
|
+
}
|
|
2584
|
+
if (e) {
|
|
2585
|
+
this.isClearButtonClick = true;
|
|
2586
|
+
}
|
|
2587
|
+
if (!this.changeOnBlur) {
|
|
2588
|
+
this.triggerChangeEvent(e);
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
|
|
2592
|
+
private removeChip(e: MouseEvent): void {
|
|
2593
|
+
if (!this.enabled || this.readonly) {
|
|
2594
|
+
return;
|
|
2595
|
+
}
|
|
2596
|
+
let element: HTMLElement = (<HTMLElement>e.target).parentElement;
|
|
2597
|
+
let value: string = element.getAttribute('data-value');
|
|
2598
|
+
if (this.chipCollection) {
|
|
2599
|
+
if (element) {
|
|
2600
|
+
remove(element);
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2603
|
+
this.isChipDelete = true;
|
|
2604
|
+
this.isClearButtonClick = true;
|
|
2605
|
+
this.removeSelectedData(value, true);
|
|
2606
|
+
this.selectedText = [];
|
|
2607
|
+
if (this.allowMultiSelection) {
|
|
2608
|
+
this.treeObj.selectedNodes = this.value.slice();
|
|
2609
|
+
this.updateSelectedValues();
|
|
2610
|
+
}
|
|
2611
|
+
if (this.showCheckBox) {
|
|
2612
|
+
this.treeObj.uncheckAll([value]);
|
|
2613
|
+
this.clearCheckAll();
|
|
2614
|
+
this.setMultiSelect();
|
|
2615
|
+
}
|
|
2616
|
+
this.triggerChangeEvent(e);
|
|
2617
|
+
this.isChipDelete = false;
|
|
2618
|
+
this.ensurePlaceHolder();
|
|
2619
|
+
}
|
|
2620
|
+
|
|
2621
|
+
private resetValue(isDynamicChange?: boolean): void {
|
|
2622
|
+
Input.setValue(null, this.inputEle, this.floatLabelType);
|
|
2623
|
+
this.oldValue = this.value;
|
|
2624
|
+
this.dataValue = null;
|
|
2625
|
+
this.setProperties({ value: [] }, true);
|
|
2626
|
+
this.setProperties({ text: null }, true);
|
|
2627
|
+
this.selectedData = [];
|
|
2628
|
+
setValue('selectedNodes', [], this.treeObj);
|
|
2629
|
+
this.hiddenElement.innerHTML = '';
|
|
2630
|
+
if (this.showCheckBox) {
|
|
2631
|
+
this.treeObj.uncheckAll();
|
|
2632
|
+
this.setMultiSelect();
|
|
2633
|
+
this.clearCheckAll();
|
|
2634
|
+
}
|
|
2635
|
+
if (this.oldValue === null && !isDynamicChange) {
|
|
2636
|
+
this.removeValue = true;
|
|
2637
|
+
} else if (isDynamicChange) {
|
|
2638
|
+
this.triggerChangeEvent();
|
|
2639
|
+
}
|
|
2640
|
+
if ((this.allowMultiSelection || this.showCheckBox) && this.chipWrapper) {
|
|
2641
|
+
this.chipCollection.innerHTML = '';
|
|
2642
|
+
this.ensurePlaceHolder();
|
|
2643
|
+
}
|
|
2644
|
+
}
|
|
2645
|
+
|
|
2646
|
+
private clearCheckAll(): void {
|
|
2647
|
+
if (this.showSelectAll && this.value.length === 0) {
|
|
2648
|
+
this.setLocale(false);
|
|
2649
|
+
}
|
|
2650
|
+
}
|
|
2651
|
+
|
|
2652
|
+
private selectAllItems(state: boolean): void {
|
|
2653
|
+
if (this.showCheckBox) {
|
|
2654
|
+
state ? this.treeObj.checkAll() : this.treeObj.uncheckAll();
|
|
2655
|
+
this.checkSelectAll = true;
|
|
2656
|
+
} else if (this.allowMultiSelection) {
|
|
2657
|
+
if (!state) {
|
|
2658
|
+
this.treeObj.selectedNodes = [];
|
|
2659
|
+
} else {
|
|
2660
|
+
let li: HTMLElement[] = selectAll('li', this.treeObj.element);
|
|
2661
|
+
let id: string;
|
|
2662
|
+
let arr: string[] = [];
|
|
2663
|
+
for (let i: number = 0; i < li.length; i++) {
|
|
2664
|
+
id = li[i].getAttribute('data-uid').toString();
|
|
2665
|
+
arr.push(id);
|
|
2666
|
+
}
|
|
2667
|
+
this.treeObj.selectedNodes = arr;
|
|
2668
|
+
}
|
|
2669
|
+
}
|
|
2670
|
+
this.updateMode();
|
|
2671
|
+
this.setMultiSelect();
|
|
2672
|
+
}
|
|
2673
|
+
|
|
2674
|
+
private updateTreeSettings(prop: DropDownTreeModel): void {
|
|
2675
|
+
let value: string = Object.keys(prop.treeSettings)[0];
|
|
2676
|
+
if (value === 'autoCheck') {
|
|
2677
|
+
this.ensureAutoCheck();
|
|
2678
|
+
this.treeObj.autoCheck = this.treeSettings.autoCheck;
|
|
2679
|
+
} else if (value === 'loadOnDemand') {
|
|
2680
|
+
this.treeObj.loadOnDemand = this.treeSettings.loadOnDemand;
|
|
2681
|
+
} else if (value === 'expandOn') {
|
|
2682
|
+
this.treeObj.expandOn = this.treeSettings.expandOn;
|
|
2683
|
+
this.treeObj.dataBind();
|
|
2684
|
+
return;
|
|
2685
|
+
}
|
|
2686
|
+
this.treeObj.dataBind();
|
|
2687
|
+
this.setMultiSelect();
|
|
2688
|
+
}
|
|
2689
|
+
|
|
2690
|
+
private updateCheckBoxState(checkBox: boolean): void {
|
|
2691
|
+
this.treeObj.showCheckBox = checkBox;
|
|
2692
|
+
this.treeObj.dataBind();
|
|
2693
|
+
this.isDynamicChange = true;
|
|
2694
|
+
this.setSelectAllWrapper(this.showSelectAll);
|
|
2695
|
+
if (this.showSelectAll) {
|
|
2696
|
+
this.setLocale();
|
|
2697
|
+
}
|
|
2698
|
+
if (this.showCheckBox) {
|
|
2699
|
+
this.updateMode();
|
|
2700
|
+
}
|
|
2701
|
+
this.setMultiSelect();
|
|
2702
|
+
this.isDynamicChange = false;
|
|
2703
|
+
}
|
|
2704
|
+
|
|
2705
|
+
|
|
2706
|
+
private updateTemplate(): void {
|
|
2707
|
+
if (this.popupObj) {
|
|
2708
|
+
this.popupObj.destroy();
|
|
2709
|
+
if (this.isPopupOpen) {
|
|
2710
|
+
this.hidePopup();
|
|
2711
|
+
this.isFirstRender = true;
|
|
2712
|
+
this.renderPopup();
|
|
2713
|
+
} else {
|
|
2714
|
+
this.isFirstRender = true;
|
|
2715
|
+
}
|
|
2716
|
+
}
|
|
2717
|
+
}
|
|
2718
|
+
|
|
2719
|
+
private l10nUpdate(actionFailure?: boolean): void {
|
|
2720
|
+
if (this.noRecord) {
|
|
2721
|
+
this.noRecord.innerHTML = '';
|
|
2722
|
+
} else {
|
|
2723
|
+
this.noRecord = this.createElement('div');
|
|
2724
|
+
addClass([this.noRecord], NODATACONTAINER);
|
|
2725
|
+
prepend([this.noRecord], this.popupDiv);
|
|
2726
|
+
}
|
|
2727
|
+
if (this.noRecordsTemplate !== 'No Records Found' || this.actionFailureTemplate !== 'The Request Failed') {
|
|
2728
|
+
let template: string = actionFailure ? this.actionFailureTemplate : this.noRecordsTemplate;
|
|
2729
|
+
let compiledString: Function;
|
|
2730
|
+
let templateId: string = actionFailure ? this.actionFailureTemplateId : this.noRecordsTemplateId;
|
|
2731
|
+
compiledString = this.templateComplier(template);
|
|
2732
|
+
for (let item of compiledString({}, null, null, templateId, this.isStringTemplate)) {
|
|
2733
|
+
this.noRecord.appendChild(item);
|
|
2734
|
+
}
|
|
2735
|
+
this.ddtupdateBlazorTemplates(!actionFailure, actionFailure);
|
|
2736
|
+
} else {
|
|
2737
|
+
let l10nLocale: Object = { noRecordsTemplate: 'No Records Found', actionFailureTemplate: 'The Request Failed'};
|
|
2738
|
+
this.l10n = new L10n(this.getModuleName(), l10nLocale, this.locale);
|
|
2739
|
+
this.noRecord.innerHTML = actionFailure ?
|
|
2740
|
+
this.l10n.getConstant('actionFailureTemplate') : this.l10n.getConstant('noRecordsTemplate');
|
|
2741
|
+
}
|
|
2742
|
+
}
|
|
2743
|
+
|
|
2744
|
+
private ddtupdateBlazorTemplates(noRecord: boolean, action: boolean, header?: boolean, footer?: boolean, isEmpty?: boolean): void {
|
|
2745
|
+
if (!this.isStringTemplate) {
|
|
2746
|
+
if (this.noRecordsTemplate && noRecord) {
|
|
2747
|
+
updateBlazorTemplate(this.noRecordsTemplateId, NORECORDSTEMPLATE, this, isEmpty);
|
|
2748
|
+
}
|
|
2749
|
+
if (this.actionFailureTemplate && action) {
|
|
2750
|
+
updateBlazorTemplate(this.actionFailureTemplateId, ACTIONFAILURETEMPLATE, this, isEmpty);
|
|
2751
|
+
}
|
|
2752
|
+
if (header) {
|
|
2753
|
+
updateBlazorTemplate(this.headerTemplateId, HEADERTEMPLATE, this);
|
|
2754
|
+
}
|
|
2755
|
+
if (footer) {
|
|
2756
|
+
updateBlazorTemplate(this.footerTemplateId, FOOTERTEMPLATE, this);
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
2759
|
+
}
|
|
2760
|
+
|
|
2761
|
+
private ddtresetBlazorTemplates( noRecord: boolean, action: boolean, header?: boolean, footer?: boolean): void {
|
|
2762
|
+
if (!this.isStringTemplate) {
|
|
2763
|
+
if (this.noRecordsTemplate && noRecord) {
|
|
2764
|
+
resetBlazorTemplate(this.noRecordsTemplateId, NORECORDSTEMPLATE);
|
|
2765
|
+
}
|
|
2766
|
+
if (this.actionFailureTemplate && action) {
|
|
2767
|
+
resetBlazorTemplate(this.actionFailureTemplateId, ACTIONFAILURETEMPLATE);
|
|
2768
|
+
}
|
|
2769
|
+
if (header) {
|
|
2770
|
+
resetBlazorTemplate(this.headerTemplateId, HEADERTEMPLATE);
|
|
2771
|
+
}
|
|
2772
|
+
if (footer) {
|
|
2773
|
+
resetBlazorTemplate(this.footerTemplateId, FOOTERTEMPLATE);
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
}
|
|
2777
|
+
|
|
2778
|
+
private updateRecordTemplate(action?: boolean): void {
|
|
2779
|
+
if (this.treeItems && this.treeItems.length <= 0) {
|
|
2780
|
+
this.l10nUpdate(action);
|
|
2781
|
+
this.updateTemplate();
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
|
|
2785
|
+
private updateMultiSelection(state: boolean): void {
|
|
2786
|
+
this.treeObj.allowMultiSelection = state;
|
|
2787
|
+
this.treeObj.dataBind();
|
|
2788
|
+
this.updateOption();
|
|
2789
|
+
if (this.allowMultiSelection) {
|
|
2790
|
+
this.updateMode();
|
|
2791
|
+
}
|
|
2792
|
+
this.setMultiSelect();
|
|
2793
|
+
}
|
|
2794
|
+
|
|
2795
|
+
private updateAllowFiltering(state: boolean): void {
|
|
2796
|
+
if (!this.isFirstRender) {
|
|
2797
|
+
if (state) {
|
|
2798
|
+
this.renderFilter();
|
|
2799
|
+
} else {
|
|
2800
|
+
this.destroyFilter();
|
|
2801
|
+
}
|
|
2802
|
+
}
|
|
2803
|
+
this.ensureAutoCheck();
|
|
2804
|
+
}
|
|
2805
|
+
|
|
2806
|
+
private updateFilterPlaceHolder(): void {
|
|
2807
|
+
if (this.filterObj) {
|
|
2808
|
+
this.filterObj.placeholder = this.filterBarPlaceholder;
|
|
2809
|
+
this.filterObj.element.setAttribute('aria-label', this.filterBarPlaceholder);
|
|
2810
|
+
}
|
|
2811
|
+
}
|
|
2812
|
+
|
|
2813
|
+
private updateValue(value: string[]): void {
|
|
2814
|
+
if (isNOU(value) || value.length === 0) {
|
|
2815
|
+
this.resetValue(true);
|
|
2816
|
+
} else {
|
|
2817
|
+
this.setTreeValue();
|
|
2818
|
+
}
|
|
2819
|
+
this.updateHiddenValue();
|
|
2820
|
+
}
|
|
2821
|
+
|
|
2822
|
+
private updateText(text: string): void {
|
|
2823
|
+
if (isNOU(text)) {
|
|
2824
|
+
this.resetValue();
|
|
2825
|
+
} else {
|
|
2826
|
+
this.setTreeText();
|
|
2827
|
+
}
|
|
2828
|
+
this.updateHiddenValue();
|
|
2829
|
+
}
|
|
2830
|
+
|
|
2831
|
+
private updateModelMode(): void {
|
|
2832
|
+
let validMode: boolean = this.allowMultiSelection ? true : (this.showCheckBox ? true : false);
|
|
2833
|
+
if (!validMode) { return; }
|
|
2834
|
+
this.updateMode();
|
|
2835
|
+
this.setMultiSelect();
|
|
2836
|
+
}
|
|
2837
|
+
|
|
2838
|
+
private updateOption(): void {
|
|
2839
|
+
if (!this.hiddenElement.hasAttribute('multiple') && (this.allowMultiSelection || this.showCheckBox)) {
|
|
2840
|
+
this.hiddenElement.setAttribute('multiple', '');
|
|
2841
|
+
} else if (this.hiddenElement.hasAttribute('multiple') && (!this.allowMultiSelection && !this.showCheckBox)) {
|
|
2842
|
+
this.hiddenElement.removeAttribute('multiple');
|
|
2843
|
+
}
|
|
2844
|
+
}
|
|
2845
|
+
|
|
2846
|
+
/**
|
|
2847
|
+
* Dynamically change the value of properties.
|
|
2848
|
+
* @private
|
|
2849
|
+
*/
|
|
2850
|
+
// tslint:disable-next-line:max-func-body-length
|
|
2851
|
+
public onPropertyChanged(newProp: DropDownTreeModel, oldProp: DropDownTreeModel): void {
|
|
2852
|
+
for (let prop of Object.keys(newProp)) {
|
|
2853
|
+
switch (prop) {
|
|
2854
|
+
case 'width': this.setElementWidth(newProp.width);
|
|
2855
|
+
if (this.popupObj) {
|
|
2856
|
+
this.popupObj.element.style.width = this.setWidth();
|
|
2857
|
+
}
|
|
2858
|
+
break;
|
|
2859
|
+
case 'placeholder': Input.setPlaceholder(newProp.placeholder, this.inputEle); break;
|
|
2860
|
+
case 'cssClass': this.setCssClass(newProp.cssClass, oldProp.cssClass); break;
|
|
2861
|
+
case 'enableRtl': this.setEnableRTL(this.enableRtl); break;
|
|
2862
|
+
case 'fields': this.setFields(); break;
|
|
2863
|
+
case 'readonly': Input.setReadonly(newProp.readonly, this.inputEle); break;
|
|
2864
|
+
case 'enabled': this.setEnable(); break;
|
|
2865
|
+
case 'floatLabelType':
|
|
2866
|
+
Input.removeFloating(this.inputObj);
|
|
2867
|
+
Input.addFloating(this.inputEle, newProp.floatLabelType, this.placeholder, this.createElement);
|
|
2868
|
+
this.ensureClearIconPosition(newProp.floatLabelType);
|
|
2869
|
+
break;
|
|
2870
|
+
case 'showClearButton': this.updateClearButton(newProp.showClearButton); break;
|
|
2871
|
+
case 'allowFiltering':
|
|
2872
|
+
this.updateAllowFiltering(newProp.allowFiltering);
|
|
2873
|
+
break;
|
|
2874
|
+
case 'filterBarPlaceholder':
|
|
2875
|
+
this.updateFilterPlaceHolder();
|
|
2876
|
+
break;
|
|
2877
|
+
case 'value': this.updateValue(newProp.value); break;
|
|
2878
|
+
case 'text': this.updateText(newProp.text); break;
|
|
2879
|
+
case 'allowMultiSelection': this.updateMultiSelection(newProp.allowMultiSelection); break;
|
|
2880
|
+
case 'mode': this.updateModelMode(); break;
|
|
2881
|
+
case 'delimiterChar':
|
|
2882
|
+
if (this.mode === 'Box') { return; }
|
|
2883
|
+
if (this.showCheckBox || this.allowMultiSelection) {
|
|
2884
|
+
this.setMultiSelect();
|
|
2885
|
+
}
|
|
2886
|
+
break;
|
|
2887
|
+
case 'selectAllText':
|
|
2888
|
+
if (this.showCheckBox && this.showSelectAll) { this.setLocale(); }
|
|
2889
|
+
break;
|
|
2890
|
+
case 'unSelectAllText':
|
|
2891
|
+
if (this.showCheckBox && this.showSelectAll) { this.setLocale(false); }
|
|
2892
|
+
break;
|
|
2893
|
+
case 'showSelectAll':
|
|
2894
|
+
if (this.showCheckBox) {
|
|
2895
|
+
this.setSelectAllWrapper(newProp.showSelectAll);
|
|
2896
|
+
this.updatePopupHeight();
|
|
2897
|
+
}
|
|
2898
|
+
break;
|
|
2899
|
+
case 'showCheckBox':
|
|
2900
|
+
this.updateCheckBoxState(newProp.showCheckBox);
|
|
2901
|
+
this.updatePopupHeight();
|
|
2902
|
+
this.updateOption();
|
|
2903
|
+
break;
|
|
2904
|
+
case 'treeSettings':
|
|
2905
|
+
this.updateTreeSettings(newProp);
|
|
2906
|
+
break;
|
|
2907
|
+
case 'sortOrder':
|
|
2908
|
+
this.treeObj.sortOrder = newProp.sortOrder;
|
|
2909
|
+
this.treeObj.dataBind();
|
|
2910
|
+
break;
|
|
2911
|
+
case 'showDropDownIcon': this.updateDropDownIconState(newProp.showDropDownIcon); break;
|
|
2912
|
+
case 'popupWidth':
|
|
2913
|
+
if (this.popupObj) {
|
|
2914
|
+
this.popupObj.element.style.width = this.setWidth();
|
|
2915
|
+
}
|
|
2916
|
+
break;
|
|
2917
|
+
case 'popupHeight':
|
|
2918
|
+
if (this.popupObj) {
|
|
2919
|
+
this.updatePopupHeight();
|
|
2920
|
+
}
|
|
2921
|
+
break;
|
|
2922
|
+
case 'zIndex':
|
|
2923
|
+
if (this.popupObj) {
|
|
2924
|
+
this.popupObj.zIndex = newProp.zIndex;
|
|
2925
|
+
this.popupObj.dataBind();
|
|
2926
|
+
}
|
|
2927
|
+
break;
|
|
2928
|
+
case 'headerTemplate': this.updateTemplate(); break;
|
|
2929
|
+
case 'footerTemplate': this.updateTemplate(); break;
|
|
2930
|
+
case 'itemTemplate':
|
|
2931
|
+
this.treeObj.nodeTemplate = newProp.itemTemplate;
|
|
2932
|
+
this.treeObj.dataBind();
|
|
2933
|
+
break;
|
|
2934
|
+
case 'noRecordsTemplate': this.updateRecordTemplate(); break;
|
|
2935
|
+
case 'actionFailureTemplate':
|
|
2936
|
+
this.updateRecordTemplate(true);
|
|
2937
|
+
break;
|
|
2938
|
+
case 'htmlAttributes': this.setHTMLAttributes(); break;
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
}
|
|
2942
|
+
|
|
2943
|
+
/**
|
|
2944
|
+
* Allows you to clear the selected values from the Dropdown Tree component.
|
|
2945
|
+
* @method clear
|
|
2946
|
+
* @return {void}.
|
|
2947
|
+
*/
|
|
2948
|
+
public clear(): void {
|
|
2949
|
+
this.clearAll();
|
|
2950
|
+
if (this.inputFocus) {
|
|
2951
|
+
this.onFocusOut();
|
|
2952
|
+
} else {
|
|
2953
|
+
if (this.changeOnBlur) {
|
|
2954
|
+
this.triggerChangeEvent();
|
|
2955
|
+
}
|
|
2956
|
+
this.removeValue = false;
|
|
2957
|
+
}
|
|
2958
|
+
}
|
|
2959
|
+
|
|
2960
|
+
/**
|
|
2961
|
+
* Removes the component from the DOM and detaches all its related event handlers. Also, it removes the attributes and classes.
|
|
2962
|
+
* @method destroy
|
|
2963
|
+
* @return {void}.
|
|
2964
|
+
*/
|
|
2965
|
+
public destroy(): void {
|
|
2966
|
+
this.ddtresetBlazorTemplates( true, true, true, true);
|
|
2967
|
+
this.unWireEvents();
|
|
2968
|
+
this.setCssClass(null, this.cssClass);
|
|
2969
|
+
this.resetValue();
|
|
2970
|
+
this.treeObj.destroy();
|
|
2971
|
+
this.destroyFilter();
|
|
2972
|
+
if (this.popupObj) {
|
|
2973
|
+
this.popupObj.destroy();
|
|
2974
|
+
detach(this.popupObj.element);
|
|
2975
|
+
}
|
|
2976
|
+
if (this.element.tagName !== this.getDirective()) {
|
|
2977
|
+
this.inputWrapper.parentElement.insertBefore(this.element, this.inputWrapper);
|
|
2978
|
+
}
|
|
2979
|
+
detach(this.inputWrapper);
|
|
2980
|
+
detach(this.popupDiv);
|
|
2981
|
+
this.element.classList.remove('e-input');
|
|
2982
|
+
super.destroy();
|
|
2983
|
+
}
|
|
2984
|
+
|
|
2985
|
+
private destroyFilter(): void {
|
|
2986
|
+
if (this.filterObj) {
|
|
2987
|
+
this.filterObj.destroy();
|
|
2988
|
+
detach(this.filterObj.element);
|
|
2989
|
+
detach(this.filterContainer);
|
|
2990
|
+
this.filterObj = null;
|
|
2991
|
+
}
|
|
2992
|
+
}
|
|
2993
|
+
|
|
2994
|
+
/**
|
|
2995
|
+
* Ensures visibility of the Dropdown Tree item by using item value or item element.
|
|
2996
|
+
* If many Dropdown Tree items are present, and we are in need to find a particular item, then the `ensureVisible` property
|
|
2997
|
+
* helps you to bring the item to visibility by expanding the Dropdown Tree and scrolling to the specific item.
|
|
2998
|
+
* @param {string | Element} item - Specifies the value of Dropdown Tree item/ Dropdown Tree item element.
|
|
2999
|
+
*/
|
|
3000
|
+
public ensureVisible(item: string | Element): void {
|
|
3001
|
+
this.treeObj.ensureVisible(item);
|
|
3002
|
+
}
|
|
3003
|
+
|
|
3004
|
+
/**
|
|
3005
|
+
* To get the updated data of source of the Dropdown Tree.
|
|
3006
|
+
* @param {string | Element} item - Specifies the value of Dropdown Tree item/ Dropdown Tree item element.
|
|
3007
|
+
* @returns { { [key: string]: Object }[] }.
|
|
3008
|
+
*/
|
|
3009
|
+
public getData(item?: string | Element): { [key: string]: Object }[] {
|
|
3010
|
+
return this.treeObj.getTreeData(item);
|
|
3011
|
+
}
|
|
3012
|
+
|
|
3013
|
+
/**
|
|
3014
|
+
* Close the Dropdown tree pop-up.
|
|
3015
|
+
* @returns void.
|
|
3016
|
+
*/
|
|
3017
|
+
public hidePopup(): void {
|
|
3018
|
+
let eventArgs: DdtPopupEventArgs = { popup: this.popupObj };
|
|
3019
|
+
this.inputWrapper.classList.remove(ICONANIMATION);
|
|
3020
|
+
if (this.popupEle) {
|
|
3021
|
+
this.popupEle.style.display = 'none';
|
|
3022
|
+
}
|
|
3023
|
+
attributes(this.inputWrapper, { 'aria-expanded': 'false' });
|
|
3024
|
+
if (this.popupObj && this.isPopupOpen) {
|
|
3025
|
+
this.popupObj.hide();
|
|
3026
|
+
if (this.inputFocus) {
|
|
3027
|
+
this.inputWrapper.focus();
|
|
3028
|
+
if (this.allowFiltering) {
|
|
3029
|
+
addClass([this.inputWrapper], [INPUTFOCUS]);
|
|
3030
|
+
}
|
|
3031
|
+
}
|
|
3032
|
+
this.trigger('close', eventArgs);
|
|
3033
|
+
}
|
|
3034
|
+
}
|
|
3035
|
+
|
|
3036
|
+
/**
|
|
3037
|
+
* Based on the state parameter, entire list item will be selected or deselected.
|
|
3038
|
+
* parameter
|
|
3039
|
+
* `true` - Selects entire Dropdown Tree items.
|
|
3040
|
+
* `false` - Unselects entire Dropdown Tree items.
|
|
3041
|
+
* @returns void
|
|
3042
|
+
*/
|
|
3043
|
+
public selectAll(state: boolean): void {
|
|
3044
|
+
this.selectAllItems(state);
|
|
3045
|
+
}
|
|
3046
|
+
|
|
3047
|
+
/**
|
|
3048
|
+
* Opens the popup that displays the Dropdown Tree items.
|
|
3049
|
+
* @returns void.
|
|
3050
|
+
*/
|
|
3051
|
+
public showPopup(): void {
|
|
3052
|
+
if (!this.enabled || this.readonly || this.isPopupOpen) {
|
|
3053
|
+
return;
|
|
3054
|
+
}
|
|
3055
|
+
this.renderPopup();
|
|
3056
|
+
this.focusIn();
|
|
3057
|
+
}
|
|
3058
|
+
|
|
3059
|
+
/**
|
|
3060
|
+
* Return the module name.
|
|
3061
|
+
* @private
|
|
3062
|
+
*/
|
|
3063
|
+
public getModuleName(): string {
|
|
3064
|
+
return 'dropdowntree';
|
|
3065
|
+
}
|
|
3066
|
+
}
|