@syncfusion/ej2-dropdowns 23.1.39 → 23.1.40-85814
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2042 -2036
- package/{README.md → ReadMe.md} +217 -217
- package/dist/ej2-dropdowns.umd.min.js +0 -9
- package/dist/ej2-dropdowns.umd.min.js.map +1 -1
- package/dist/es6/ej2-dropdowns.es2015.js +56 -56
- package/dist/es6/ej2-dropdowns.es2015.js.map +1 -1
- package/dist/es6/ej2-dropdowns.es5.js +198 -198
- package/dist/es6/ej2-dropdowns.es5.js.map +1 -1
- package/dist/global/ej2-dropdowns.min.js +0 -9
- package/dist/global/ej2-dropdowns.min.js.map +1 -1
- package/dist/global/index.d.ts +0 -9
- package/dist/ts/auto-complete/auto-complete.ts +615 -0
- package/dist/ts/combo-box/combo-box.ts +1028 -0
- package/dist/ts/common/highlight-search.ts +57 -0
- package/dist/ts/common/incremental-search.ts +131 -0
- package/dist/ts/common/interface.ts +72 -0
- package/dist/ts/common/virtual-scroll.ts +354 -0
- package/dist/ts/drop-down-base/drop-down-base.ts +1838 -0
- package/dist/ts/drop-down-list/drop-down-list.ts +3889 -0
- package/dist/ts/drop-down-tree/drop-down-tree.ts +3750 -0
- package/dist/ts/list-box/list-box.ts +2736 -0
- package/dist/ts/mention/mention.ts +1828 -0
- package/dist/ts/multi-select/checkbox-selection.ts +547 -0
- package/dist/ts/multi-select/float-label.ts +176 -0
- package/dist/ts/multi-select/interface.ts +70 -0
- package/dist/ts/multi-select/multi-select.ts +4874 -0
- package/helpers/e2e/autocomplete.js +13 -13
- package/helpers/e2e/combobox.js +13 -13
- package/helpers/e2e/dropdownlist.js +13 -13
- package/helpers/e2e/index.js +3 -3
- package/helpers/e2e/listboxHelper.js +13 -13
- package/helpers/e2e/multiselect.js +13 -13
- package/license +2 -2
- package/package.json +79 -79
- package/src/auto-complete/auto-complete-model.d.ts +188 -188
- package/src/auto-complete/auto-complete.d.ts +12 -12
- package/src/auto-complete/auto-complete.js +21 -21
- package/src/combo-box/combo-box-model.d.ts +224 -224
- package/src/combo-box/combo-box.d.ts +27 -27
- package/src/combo-box/combo-box.js +29 -29
- package/src/common/virtual-scroll.js +46 -46
- package/src/drop-down-base/drop-down-base-model.d.ts +200 -200
- package/src/drop-down-base/drop-down-base.d.ts +15 -15
- package/src/drop-down-base/drop-down-base.js +20 -20
- package/src/drop-down-list/drop-down-list-model.d.ts +202 -202
- package/src/drop-down-list/drop-down-list.d.ts +4 -4
- package/src/drop-down-list/drop-down-list.js +20 -20
- package/src/drop-down-tree/drop-down-tree-model.d.ts +468 -468
- package/src/drop-down-tree/drop-down-tree.js +19 -19
- package/src/list-box/list-box-model.d.ts +193 -193
- package/src/list-box/list-box.d.ts +2 -2
- package/src/list-box/list-box.js +19 -19
- package/src/mention/mention-model.d.ts +261 -261
- package/src/mention/mention.js +19 -19
- package/src/multi-select/multi-select-model.d.ts +512 -512
- package/src/multi-select/multi-select.js +19 -19
- package/styles/auto-complete/_all.scss +1 -1
- package/styles/auto-complete/_bootstrap-dark-definition.scss +3 -3
- package/styles/auto-complete/_bootstrap-definition.scss +2 -2
- package/styles/auto-complete/_bootstrap4-definition.scss +11 -11
- package/styles/auto-complete/_bootstrap5-definition.scss +2 -2
- package/styles/auto-complete/_fabric-dark-definition.scss +2 -2
- package/styles/auto-complete/_fabric-definition.scss +2 -2
- package/styles/auto-complete/_fluent-definition.scss +2 -2
- package/styles/auto-complete/_fusionnew-definition.scss +2 -2
- package/styles/auto-complete/_highcontrast-definition.scss +2 -2
- package/styles/auto-complete/_highcontrast-light-definition.scss +2 -2
- package/styles/auto-complete/_material-dark-definition.scss +2 -2
- package/styles/auto-complete/_material-definition.scss +2 -2
- package/styles/auto-complete/_material3-definition.scss +2 -2
- package/styles/auto-complete/_tailwind-definition.scss +2 -2
- package/styles/auto-complete/bootstrap4.css +13 -2
- package/styles/auto-complete/material3-dark.scss +1 -1
- package/styles/auto-complete/material3.scss +1 -1
- package/styles/bootstrap4.css +32 -2
- package/styles/combo-box/_all.scss +1 -1
- package/styles/combo-box/_bootstrap-dark-definition.scss +2 -2
- package/styles/combo-box/_bootstrap-definition.scss +2 -2
- package/styles/combo-box/_bootstrap4-definition.scss +11 -11
- package/styles/combo-box/_bootstrap5-definition.scss +2 -2
- package/styles/combo-box/_fabric-dark-definition.scss +2 -2
- package/styles/combo-box/_fabric-definition.scss +2 -2
- package/styles/combo-box/_fluent-definition.scss +2 -2
- package/styles/combo-box/_fusionnew-definition.scss +2 -2
- package/styles/combo-box/_highcontrast-definition.scss +2 -2
- package/styles/combo-box/_highcontrast-light-definition.scss +3 -3
- package/styles/combo-box/_material-dark-definition.scss +2 -2
- package/styles/combo-box/_material-definition.scss +2 -2
- package/styles/combo-box/_material3-definition.scss +2 -2
- package/styles/combo-box/_tailwind-definition.scss +2 -2
- package/styles/combo-box/bootstrap4.css +13 -2
- package/styles/combo-box/material3-dark.scss +1 -1
- package/styles/combo-box/material3.scss +1 -1
- package/styles/drop-down-base/_all.scss +2 -2
- package/styles/drop-down-base/_bootstrap-dark-definition.scss +83 -83
- package/styles/drop-down-base/_bootstrap-definition.scss +83 -83
- package/styles/drop-down-base/_bootstrap4-definition.scss +90 -90
- package/styles/drop-down-base/_bootstrap5-definition.scss +117 -117
- package/styles/drop-down-base/_definition.scss +23 -23
- package/styles/drop-down-base/_fabric-dark-definition.scss +86 -86
- package/styles/drop-down-base/_fabric-definition.scss +84 -84
- package/styles/drop-down-base/_fluent-definition.scss +121 -121
- package/styles/drop-down-base/_fusionnew-definition.scss +117 -117
- package/styles/drop-down-base/_highcontrast-definition.scss +105 -105
- package/styles/drop-down-base/_highcontrast-light-definition.scss +105 -105
- package/styles/drop-down-base/_layout.scss +195 -195
- package/styles/drop-down-base/_material-dark-definition.scss +86 -86
- package/styles/drop-down-base/_material-definition.scss +85 -85
- package/styles/drop-down-base/_material3-definition.scss +87 -87
- package/styles/drop-down-base/_tailwind-definition.scss +129 -129
- package/styles/drop-down-base/_theme.scss +391 -391
- package/styles/drop-down-base/material3-dark.scss +1 -1
- package/styles/drop-down-base/material3.scss +1 -1
- package/styles/drop-down-list/_all.scss +3 -3
- package/styles/drop-down-list/_bootstrap-dark-definition.scss +157 -157
- package/styles/drop-down-list/_bootstrap-definition.scss +156 -156
- package/styles/drop-down-list/_bootstrap4-definition.scss +202 -191
- package/styles/drop-down-list/_bootstrap5-definition.scss +201 -201
- package/styles/drop-down-list/_fabric-dark-definition.scss +128 -128
- package/styles/drop-down-list/_fabric-definition.scss +124 -124
- package/styles/drop-down-list/_fluent-definition.scss +185 -185
- package/styles/drop-down-list/_fusionnew-definition.scss +201 -201
- package/styles/drop-down-list/_highcontrast-definition.scss +142 -142
- package/styles/drop-down-list/_highcontrast-light-definition.scss +144 -144
- package/styles/drop-down-list/_layout.scss +310 -310
- package/styles/drop-down-list/_material-dark-definition.scss +143 -143
- package/styles/drop-down-list/_material-definition.scss +167 -167
- package/styles/drop-down-list/_material3-definition.scss +180 -180
- package/styles/drop-down-list/_tailwind-definition.scss +134 -134
- package/styles/drop-down-list/_theme.scss +10 -10
- package/styles/drop-down-list/bootstrap4.css +13 -2
- package/styles/drop-down-list/icons/_bootstrap-dark.scss +14 -14
- package/styles/drop-down-list/icons/_bootstrap.scss +14 -14
- package/styles/drop-down-list/icons/_bootstrap4.scss +14 -14
- package/styles/drop-down-list/icons/_bootstrap5.scss +14 -14
- package/styles/drop-down-list/icons/_fabric-dark.scss +14 -14
- package/styles/drop-down-list/icons/_fabric.scss +14 -14
- package/styles/drop-down-list/icons/_fluent.scss +14 -14
- package/styles/drop-down-list/icons/_fusionnew.scss +14 -14
- package/styles/drop-down-list/icons/_highcontrast-light.scss +14 -14
- package/styles/drop-down-list/icons/_highcontrast.scss +14 -14
- package/styles/drop-down-list/icons/_material-dark.scss +14 -14
- package/styles/drop-down-list/icons/_material.scss +14 -14
- package/styles/drop-down-list/icons/_material3.scss +14 -14
- package/styles/drop-down-list/icons/_tailwind.scss +14 -14
- package/styles/drop-down-list/material3-dark.scss +1 -1
- package/styles/drop-down-list/material3.scss +1 -1
- package/styles/drop-down-tree/_all.scss +2 -2
- package/styles/drop-down-tree/_bootstrap-dark-definition.scss +71 -71
- package/styles/drop-down-tree/_bootstrap-definition.scss +70 -70
- package/styles/drop-down-tree/_bootstrap4-definition.scss +71 -71
- package/styles/drop-down-tree/_bootstrap5-definition.scss +59 -59
- package/styles/drop-down-tree/_fabric-dark-definition.scss +71 -71
- package/styles/drop-down-tree/_fabric-definition.scss +71 -71
- package/styles/drop-down-tree/_fluent-definition.scss +65 -65
- package/styles/drop-down-tree/_fusionnew-definition.scss +59 -59
- package/styles/drop-down-tree/_highcontrast-definition.scss +71 -71
- package/styles/drop-down-tree/_highcontrast-light-definition.scss +71 -71
- package/styles/drop-down-tree/_layout.scss +1418 -1412
- package/styles/drop-down-tree/_material-dark-definition.scss +72 -72
- package/styles/drop-down-tree/_material-definition.scss +72 -72
- package/styles/drop-down-tree/_material3-definition.scss +76 -76
- package/styles/drop-down-tree/_tailwind-definition.scss +61 -61
- package/styles/drop-down-tree/_theme.scss +132 -132
- package/styles/drop-down-tree/fluent-dark.css +2 -0
- package/styles/drop-down-tree/fluent.css +2 -0
- package/styles/drop-down-tree/icons/_bootstrap-dark.scss +11 -11
- package/styles/drop-down-tree/icons/_bootstrap.scss +11 -11
- package/styles/drop-down-tree/icons/_bootstrap4.scss +11 -11
- package/styles/drop-down-tree/icons/_bootstrap5.scss +11 -11
- package/styles/drop-down-tree/icons/_fabric-dark.scss +11 -11
- package/styles/drop-down-tree/icons/_fabric.scss +11 -11
- package/styles/drop-down-tree/icons/_fluent.scss +11 -11
- package/styles/drop-down-tree/icons/_fusionnew.scss +11 -11
- package/styles/drop-down-tree/icons/_highcontrast-light.scss +11 -11
- package/styles/drop-down-tree/icons/_highcontrast.scss +11 -11
- package/styles/drop-down-tree/icons/_material-dark.scss +11 -11
- package/styles/drop-down-tree/icons/_material.scss +11 -11
- package/styles/drop-down-tree/icons/_material3.scss +11 -11
- package/styles/drop-down-tree/icons/_tailwind-dark.scss +11 -11
- package/styles/drop-down-tree/icons/_tailwind.scss +11 -11
- package/styles/drop-down-tree/material3-dark.scss +1 -1
- package/styles/drop-down-tree/material3.scss +1 -1
- package/styles/fluent-dark.css +2 -0
- package/styles/fluent.css +2 -0
- package/styles/list-box/_all.scss +2 -2
- package/styles/list-box/_bootstrap-dark-definition.scss +126 -126
- package/styles/list-box/_bootstrap-definition.scss +119 -119
- package/styles/list-box/_bootstrap4-definition.scss +124 -124
- package/styles/list-box/_bootstrap5-definition.scss +120 -120
- package/styles/list-box/_fabric-dark-definition.scss +126 -126
- package/styles/list-box/_fabric-definition.scss +119 -119
- package/styles/list-box/_fluent-definition.scss +120 -120
- package/styles/list-box/_fusionnew-definition.scss +111 -111
- package/styles/list-box/_highcontrast-definition.scss +119 -119
- package/styles/list-box/_highcontrast-light-definition.scss +126 -126
- package/styles/list-box/_layout.scss +542 -542
- package/styles/list-box/_material-dark-definition.scss +126 -126
- package/styles/list-box/_material-definition.scss +119 -119
- package/styles/list-box/_material3-definition.scss +119 -119
- package/styles/list-box/_tailwind-definition.scss +119 -119
- package/styles/list-box/_theme.scss +382 -382
- package/styles/list-box/icons/_bootstrap-dark.scss +25 -25
- package/styles/list-box/icons/_bootstrap.scss +25 -25
- package/styles/list-box/icons/_bootstrap4.scss +25 -25
- package/styles/list-box/icons/_bootstrap5.scss +25 -25
- package/styles/list-box/icons/_fabric-dark.scss +25 -25
- package/styles/list-box/icons/_fabric.scss +25 -25
- package/styles/list-box/icons/_fluent.scss +25 -25
- package/styles/list-box/icons/_fusionnew.scss +25 -25
- package/styles/list-box/icons/_highcontrast-light.scss +25 -25
- package/styles/list-box/icons/_highcontrast.scss +25 -25
- package/styles/list-box/icons/_material-dark.scss +25 -25
- package/styles/list-box/icons/_material.scss +25 -25
- package/styles/list-box/icons/_material3.scss +25 -25
- package/styles/list-box/icons/_tailwind-dark.scss +25 -25
- package/styles/list-box/icons/_tailwind.scss +25 -25
- package/styles/list-box/material3-dark.scss +1 -1
- package/styles/list-box/material3.scss +1 -1
- package/styles/material3-dark.scss +1 -1
- package/styles/material3.scss +1 -1
- package/styles/mention/_all.scss +1 -1
- package/styles/mention/_bootstrap-dark-definition.scss +3 -3
- package/styles/mention/_bootstrap-definition.scss +3 -3
- package/styles/mention/_bootstrap4-definition.scss +3 -3
- package/styles/mention/_bootstrap5-definition.scss +1 -1
- package/styles/mention/_fabric-dark-definition.scss +2 -2
- package/styles/mention/_fabric-definition.scss +3 -3
- package/styles/mention/_fluent-definition.scss +1 -1
- package/styles/mention/_fusionnew-definition.scss +1 -1
- package/styles/mention/_highcontrast-definition.scss +3 -3
- package/styles/mention/_highcontrast-light-definition.scss +3 -3
- package/styles/mention/_layout.scss +6 -6
- package/styles/mention/_material-dark-definition.scss +3 -3
- package/styles/mention/_material-definition.scss +3 -3
- package/styles/mention/_material3-definition.scss +1 -1
- package/styles/mention/_tailwind-definition.scss +1 -1
- package/styles/mention/material3-dark.scss +1 -1
- package/styles/mention/material3.scss +1 -1
- package/styles/multi-select/_all.scss +2 -2
- package/styles/multi-select/_bootstrap-dark-definition.scss +198 -198
- package/styles/multi-select/_bootstrap-definition.scss +192 -192
- package/styles/multi-select/_bootstrap4-definition.scss +278 -259
- package/styles/multi-select/_bootstrap5-definition.scss +229 -229
- package/styles/multi-select/_fabric-dark-definition.scss +187 -187
- package/styles/multi-select/_fabric-definition.scss +183 -183
- package/styles/multi-select/_fluent-definition.scss +240 -240
- package/styles/multi-select/_fusionnew-definition.scss +227 -227
- package/styles/multi-select/_highcontrast-definition.scss +298 -298
- package/styles/multi-select/_highcontrast-light-definition.scss +297 -297
- package/styles/multi-select/_layout.scss +2199 -2199
- package/styles/multi-select/_material-dark-definition.scss +230 -230
- package/styles/multi-select/_material-definition.scss +223 -223
- package/styles/multi-select/_material3-definition.scss +246 -246
- package/styles/multi-select/_tailwind-definition.scss +234 -234
- package/styles/multi-select/_theme.scss +586 -586
- package/styles/multi-select/bootstrap4.css +19 -0
- package/styles/multi-select/icons/_bootstrap-dark.scss +26 -26
- package/styles/multi-select/icons/_bootstrap.scss +26 -26
- package/styles/multi-select/icons/_bootstrap4.scss +37 -37
- package/styles/multi-select/icons/_bootstrap5.scss +26 -26
- package/styles/multi-select/icons/_fabric-dark.scss +26 -26
- package/styles/multi-select/icons/_fabric.scss +26 -26
- package/styles/multi-select/icons/_fluent.scss +55 -55
- package/styles/multi-select/icons/_fusionnew.scss +26 -26
- package/styles/multi-select/icons/_highcontrast-light.scss +26 -26
- package/styles/multi-select/icons/_highcontrast.scss +26 -26
- package/styles/multi-select/icons/_material-dark.scss +693 -693
- package/styles/multi-select/icons/_material.scss +693 -693
- package/styles/multi-select/icons/_material3.scss +692 -692
- package/styles/multi-select/icons/_tailwind.scss +26 -26
- package/styles/multi-select/material3-dark.scss +1 -1
- package/styles/multi-select/material3.scss +1 -1
- package/.eslintrc.json +0 -260
- package/dist/ej2-dropdowns.min.js +0 -10
- package/tslint.json +0 -111
|
@@ -0,0 +1,2736 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/triple-slash-reference
|
|
2
|
+
/// <reference path='../drop-down-base/drop-down-base-model.d.ts'/>
|
|
3
|
+
import { Input, InputObject } from '@syncfusion/ej2-inputs';
|
|
4
|
+
import { DropDownBase, dropDownBaseClasses, FilteringEventArgs, SelectEventArgs } from '../drop-down-base/drop-down-base';
|
|
5
|
+
import { FieldSettingsModel } from '../drop-down-base/drop-down-base-model';
|
|
6
|
+
import { EventHandler, closest, removeClass, addClass, Complex, Property, ChildProperty, BaseEventArgs, L10n } from '@syncfusion/ej2-base';
|
|
7
|
+
import { ModuleDeclaration, NotifyPropertyChanges, getComponent, EmitType, Event, extend, detach, attributes } from '@syncfusion/ej2-base';
|
|
8
|
+
import { getUniqueID, Browser, formatUnit, isNullOrUndefined, getValue } from '@syncfusion/ej2-base';
|
|
9
|
+
import { prepend, append } from '@syncfusion/ej2-base';
|
|
10
|
+
import { cssClass, Sortable, moveTo } from '@syncfusion/ej2-lists';
|
|
11
|
+
import { SelectionSettingsModel, ListBoxModel, ToolbarSettingsModel } from './list-box-model';
|
|
12
|
+
import { Button } from '@syncfusion/ej2-buttons';
|
|
13
|
+
import { createSpinner, showSpinner, hideSpinner, getZindexPartial } from '@syncfusion/ej2-popups';
|
|
14
|
+
import { DataManager, Query } from '@syncfusion/ej2-data';
|
|
15
|
+
/**
|
|
16
|
+
* Defines the selection mode in ListBox component.
|
|
17
|
+
* ```props
|
|
18
|
+
* Multiple :- Specifies that the ListBox should allow multiple item selection.
|
|
19
|
+
* Single :- Specifies that the ListBox should allow single item selection.
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export type SelectionMode = 'Multiple' | 'Single';
|
|
23
|
+
/**
|
|
24
|
+
* Defines the position of the toolbar in ListBox component.
|
|
25
|
+
* ```props
|
|
26
|
+
* Left :- Specifies that the toolbar should be positioned to the left of the ListBox.
|
|
27
|
+
* Right :- Specifies that the toolbar should be positioned to the right of the ListBox.
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export type ToolBarPosition = 'Left' | 'Right';
|
|
31
|
+
/**
|
|
32
|
+
* Defines the position of the checkbox in ListBox component.
|
|
33
|
+
* ```props
|
|
34
|
+
* Left :- Specifies that the checkbox should be positioned to the left of the ListBox.
|
|
35
|
+
* Right :- Specifies that the checkbox should be positioned to the right of the ListBox.
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export type CheckBoxPosition = 'Left' | 'Right';
|
|
39
|
+
|
|
40
|
+
type dataType = { [key: string]: object } | string | boolean | number;
|
|
41
|
+
type obj = { [key: string]: object };
|
|
42
|
+
const ITEMTEMPLATE_PROPERTY: string = 'ItemTemplate';
|
|
43
|
+
/**
|
|
44
|
+
* Defines the Selection settings of List Box.
|
|
45
|
+
*/
|
|
46
|
+
export class SelectionSettings extends ChildProperty<SelectionSettings> {
|
|
47
|
+
/**
|
|
48
|
+
* Specifies the selection modes. The possible values are
|
|
49
|
+
* * `Single`: Allows you to select a single item in the ListBox.
|
|
50
|
+
* * `Multiple`: Allows you to select more than one item in the ListBox.
|
|
51
|
+
*
|
|
52
|
+
* @default 'Multiple'
|
|
53
|
+
*/
|
|
54
|
+
@Property('Multiple')
|
|
55
|
+
public mode: SelectionMode;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* If 'showCheckbox' is set to true, then 'checkbox' will be visualized in the list item.
|
|
59
|
+
*
|
|
60
|
+
* @default false
|
|
61
|
+
*/
|
|
62
|
+
@Property(false)
|
|
63
|
+
public showCheckbox: boolean;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Allows you to either show or hide the selectAll option on the component.
|
|
67
|
+
*
|
|
68
|
+
* @default false
|
|
69
|
+
*/
|
|
70
|
+
@Property(false)
|
|
71
|
+
public showSelectAll: boolean;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Set the position of the checkbox.
|
|
75
|
+
*
|
|
76
|
+
* @default 'Left'
|
|
77
|
+
*/
|
|
78
|
+
@Property('Left')
|
|
79
|
+
public checkboxPosition: CheckBoxPosition;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Defines the toolbar settings of List Box.
|
|
83
|
+
*/
|
|
84
|
+
export class ToolbarSettings extends ChildProperty<ToolbarSettings> {
|
|
85
|
+
/**
|
|
86
|
+
* Specifies the list of tools for dual ListBox.
|
|
87
|
+
* The predefined tools are 'moveUp', 'moveDown', 'moveTo', 'moveFrom', 'moveAllTo', and 'moveAllFrom'.
|
|
88
|
+
*
|
|
89
|
+
* @default []
|
|
90
|
+
*/
|
|
91
|
+
@Property([])
|
|
92
|
+
public items: string[];
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Positions the toolbar before/after the ListBox.
|
|
96
|
+
* The possible values are:
|
|
97
|
+
* * Left: The toolbar will be positioned to the left of the ListBox.
|
|
98
|
+
* * Right: The toolbar will be positioned to the right of the ListBox.
|
|
99
|
+
*
|
|
100
|
+
* @default 'Right'
|
|
101
|
+
*/
|
|
102
|
+
@Property('Right')
|
|
103
|
+
public position: ToolBarPosition;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The ListBox is a graphical user interface component used to display a list of items.
|
|
108
|
+
* Users can select one or more items in the list using a checkbox or by keyboard selection.
|
|
109
|
+
* It supports sorting, grouping, reordering and drag and drop of items.
|
|
110
|
+
* ```html
|
|
111
|
+
* <select id="listbox">
|
|
112
|
+
* <option value='1'>Badminton</option>
|
|
113
|
+
* <option value='2'>Basketball</option>
|
|
114
|
+
* <option value='3'>Cricket</option>
|
|
115
|
+
* <option value='4'>Football</option>
|
|
116
|
+
* <option value='5'>Tennis</option>
|
|
117
|
+
* </select>
|
|
118
|
+
* ```
|
|
119
|
+
* ```typescript
|
|
120
|
+
* <script>
|
|
121
|
+
* var listObj = new ListBox();
|
|
122
|
+
* listObj.appendTo("#listbox");
|
|
123
|
+
* </script>
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
@NotifyPropertyChanges
|
|
127
|
+
export class ListBox extends DropDownBase {
|
|
128
|
+
private prevSelIdx: number;
|
|
129
|
+
private listCurrentOptions: FieldSettingsModel;
|
|
130
|
+
private allowDragAll: boolean;
|
|
131
|
+
private checkBoxSelectionModule: { onDocumentClick: Function, checkAllParent: HTMLElement, clearIconElement: HTMLElement };
|
|
132
|
+
private tBListBox: ListBox;
|
|
133
|
+
private initLoad: boolean;
|
|
134
|
+
private spinner: HTMLElement;
|
|
135
|
+
private initialSelectedOptions: string[] | number[] | boolean[];
|
|
136
|
+
private showSelectAll: boolean;
|
|
137
|
+
private selectAllText: string;
|
|
138
|
+
private unSelectAllText: string;
|
|
139
|
+
private popupWrapper: Element;
|
|
140
|
+
private targetInputElement: HTMLInputElement | string;
|
|
141
|
+
private isValidKey: boolean = false;
|
|
142
|
+
private isFiltered: boolean;
|
|
143
|
+
private clearFilterIconElem: Element;
|
|
144
|
+
private remoteFilterAction: boolean;
|
|
145
|
+
private mainList: HTMLElement;
|
|
146
|
+
private remoteCustomValue: boolean;
|
|
147
|
+
private filterParent: HTMLElement;
|
|
148
|
+
protected inputString: string;
|
|
149
|
+
protected filterInput: HTMLInputElement;
|
|
150
|
+
protected isCustomFiltering: boolean;
|
|
151
|
+
private jsonData: { [key: string]: Object }[] | string[] | boolean[] | number[];
|
|
152
|
+
private toolbarAction: string;
|
|
153
|
+
private isDataSourceUpdate: boolean = false;
|
|
154
|
+
private dragValue: string;
|
|
155
|
+
private customDraggedItem: Object[];
|
|
156
|
+
/**
|
|
157
|
+
* Sets the CSS classes to root element of this component, which helps to customize the
|
|
158
|
+
* complete styles.
|
|
159
|
+
*
|
|
160
|
+
* @default ''
|
|
161
|
+
*/
|
|
162
|
+
@Property('')
|
|
163
|
+
public cssClass: string;
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Sets the specified item to the selected state or gets the selected item in the ListBox.
|
|
167
|
+
*
|
|
168
|
+
* @default []
|
|
169
|
+
* @aspType object
|
|
170
|
+
* @isGenericType true
|
|
171
|
+
*/
|
|
172
|
+
@Property([])
|
|
173
|
+
public value: string[] | number[] | boolean[];
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Sets the height of the ListBox component.
|
|
177
|
+
*
|
|
178
|
+
* @default ''
|
|
179
|
+
*/
|
|
180
|
+
@Property('')
|
|
181
|
+
public height: number | string;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Specifies a value that indicates whether the component is enabled or not.
|
|
185
|
+
*
|
|
186
|
+
* @default true
|
|
187
|
+
* @deprecated
|
|
188
|
+
*/
|
|
189
|
+
@Property(true)
|
|
190
|
+
public enabled: boolean;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Enable or disable persisting component's state between page reloads.
|
|
194
|
+
* If enabled, following list of states will be persisted.
|
|
195
|
+
* 1. value
|
|
196
|
+
*
|
|
197
|
+
* @default false
|
|
198
|
+
* @deprecated
|
|
199
|
+
*/
|
|
200
|
+
@Property(false)
|
|
201
|
+
public enablePersistence: boolean;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* If 'allowDragAndDrop' is set to true, then you can perform drag and drop of the list item.
|
|
205
|
+
* ListBox contains same 'scope' property enables drag and drop between multiple ListBox.
|
|
206
|
+
*
|
|
207
|
+
* @default false
|
|
208
|
+
*/
|
|
209
|
+
@Property(false)
|
|
210
|
+
public allowDragAndDrop: boolean;
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Sets limitation to the value selection.
|
|
214
|
+
* based on the limitation, list selection will be prevented.
|
|
215
|
+
*
|
|
216
|
+
* @default 1000
|
|
217
|
+
*/
|
|
218
|
+
@Property(1000)
|
|
219
|
+
public maximumSelectionLength: number;
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* To enable the filtering option in this component.
|
|
223
|
+
* Filter action performs when type in search box and collect the matched item through `filtering` event.
|
|
224
|
+
* If searching character does not match, `noRecordsTemplate` property value will be shown.
|
|
225
|
+
*
|
|
226
|
+
* @default false
|
|
227
|
+
*/
|
|
228
|
+
@Property(false)
|
|
229
|
+
public allowFiltering: boolean;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Defines the scope value to group sets of draggable and droppable ListBox.
|
|
233
|
+
* A draggable with the same scope value will be accepted by the droppable.
|
|
234
|
+
*
|
|
235
|
+
* @default ''
|
|
236
|
+
*/
|
|
237
|
+
@Property('')
|
|
238
|
+
public scope: string;
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* When set to ‘false’, consider the `case-sensitive` on performing the search to find suggestions.
|
|
242
|
+
* By default consider the casing.
|
|
243
|
+
*
|
|
244
|
+
* @default true
|
|
245
|
+
* @private
|
|
246
|
+
*/
|
|
247
|
+
@Property(true)
|
|
248
|
+
public ignoreCase: boolean;
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Accepts the value to be displayed as a watermark text on the filter bar.
|
|
252
|
+
*
|
|
253
|
+
* @default null
|
|
254
|
+
*/
|
|
255
|
+
@Property(null)
|
|
256
|
+
public filterBarPlaceholder: string;
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Triggers while rendering each list item.
|
|
260
|
+
*
|
|
261
|
+
* @event beforeItemRender
|
|
262
|
+
* @blazorProperty 'OnItemRender'
|
|
263
|
+
*/
|
|
264
|
+
@Event()
|
|
265
|
+
public beforeItemRender: EmitType<BeforeItemRenderEventArgs>;
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Triggers on typing a character in the component.
|
|
269
|
+
*
|
|
270
|
+
* @event filtering
|
|
271
|
+
* @blazorProperty 'ItemSelected'
|
|
272
|
+
*/
|
|
273
|
+
@Event()
|
|
274
|
+
public filtering: EmitType<FilteringEventArgs>;
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Triggers when an item in the popup is selected by the user either with mouse/tap or with keyboard navigation.
|
|
278
|
+
*
|
|
279
|
+
* @event select
|
|
280
|
+
* @private
|
|
281
|
+
*/
|
|
282
|
+
@Event()
|
|
283
|
+
public select: EmitType<SelectEventArgs>;
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Adds a new item to the popup list. By default, new item appends to the list as the last item,
|
|
287
|
+
* but you can insert based on the index parameter.
|
|
288
|
+
*
|
|
289
|
+
* @param { Object[] } items - Specifies an array of JSON data or a JSON data.
|
|
290
|
+
* @param { number } itemIndex - Specifies the index to place the newly added item in the popup list.
|
|
291
|
+
* @returns {void}.
|
|
292
|
+
* @private
|
|
293
|
+
*/
|
|
294
|
+
public addItem(
|
|
295
|
+
items: { [key: string]: Object }[] | { [key: string]: Object } | string | boolean | number | string[] | boolean[] | number[],
|
|
296
|
+
itemIndex?: number): void {
|
|
297
|
+
super.addItem(items, itemIndex);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Triggers while select / unselect the list item.
|
|
302
|
+
*
|
|
303
|
+
* @event change
|
|
304
|
+
* @blazorProperty 'ValueChange'
|
|
305
|
+
*/
|
|
306
|
+
@Event()
|
|
307
|
+
public change: EmitType<ListBoxChangeEventArgs>;
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Triggers before dropping the list item on another list item.
|
|
311
|
+
*
|
|
312
|
+
* @event beforeDrop
|
|
313
|
+
* @blazorProperty 'OnDrop'
|
|
314
|
+
*/
|
|
315
|
+
@Event()
|
|
316
|
+
public beforeDrop: EmitType<DropEventArgs>;
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Triggers after dragging the list item.
|
|
320
|
+
*
|
|
321
|
+
* @event dragStart
|
|
322
|
+
* @blazorProperty 'DragStart'
|
|
323
|
+
*/
|
|
324
|
+
@Event()
|
|
325
|
+
public dragStart: EmitType<DragEventArgs>;
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Triggers while dragging the list item.
|
|
329
|
+
*
|
|
330
|
+
* @event drag
|
|
331
|
+
* @blazorProperty 'Dragging'
|
|
332
|
+
*/
|
|
333
|
+
@Event()
|
|
334
|
+
public drag: EmitType<DragEventArgs>;
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Triggers before dropping the list item on another list item.
|
|
338
|
+
*
|
|
339
|
+
* @event drop
|
|
340
|
+
* @blazorProperty 'Dropped'
|
|
341
|
+
*/
|
|
342
|
+
@Event()
|
|
343
|
+
public drop: EmitType<DragEventArgs>;
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Triggers when data source is populated in the list.
|
|
347
|
+
*
|
|
348
|
+
* @event dataBound
|
|
349
|
+
*/
|
|
350
|
+
@Event()
|
|
351
|
+
public dataBound: EmitType<Object>;
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Accepts the template design and assigns it to the group headers present in the list.
|
|
355
|
+
*
|
|
356
|
+
* @default null
|
|
357
|
+
* @private
|
|
358
|
+
*/
|
|
359
|
+
@Property(null)
|
|
360
|
+
public groupTemplate: string;
|
|
361
|
+
/**
|
|
362
|
+
* Accepts the template and assigns it to the list content of the ListBox component
|
|
363
|
+
* when the data fetch request from the remote server fails.
|
|
364
|
+
*
|
|
365
|
+
* @default 'Request Failed'
|
|
366
|
+
* @private
|
|
367
|
+
*/
|
|
368
|
+
@Property('Request failed')
|
|
369
|
+
public actionFailureTemplate: string;
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* specifies the z-index value of the component popup element.
|
|
373
|
+
*
|
|
374
|
+
* @default 1000
|
|
375
|
+
* @private
|
|
376
|
+
*/
|
|
377
|
+
@Property(1000)
|
|
378
|
+
public zIndex: number;
|
|
379
|
+
/**
|
|
380
|
+
* ignoreAccent set to true, then ignores the diacritic characters or accents when filtering.
|
|
381
|
+
*
|
|
382
|
+
* @private
|
|
383
|
+
*/
|
|
384
|
+
@Property(false)
|
|
385
|
+
public ignoreAccent: boolean;
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Specifies the toolbar items and its position.
|
|
389
|
+
*
|
|
390
|
+
* @default { items: [], position: 'Right' }
|
|
391
|
+
*/
|
|
392
|
+
@Complex<ToolbarSettingsModel>({}, ToolbarSettings)
|
|
393
|
+
public toolbarSettings: ToolbarSettingsModel;
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Specifies the selection mode and its type.
|
|
397
|
+
*
|
|
398
|
+
* @default { mode: 'Multiple', type: 'Default' }
|
|
399
|
+
*/
|
|
400
|
+
@Complex<SelectionSettingsModel>({}, SelectionSettings)
|
|
401
|
+
public selectionSettings: SelectionSettingsModel;
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Constructor for creating the ListBox component.
|
|
405
|
+
*
|
|
406
|
+
* @param {ListBoxModel} options - Specifies ListBox model
|
|
407
|
+
* @param {string | HTMLElement} element - Specifies the element.
|
|
408
|
+
*/
|
|
409
|
+
constructor(options?: ListBoxModel, element?: string | HTMLElement) {
|
|
410
|
+
super(options, element);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Build and render the component.
|
|
415
|
+
*
|
|
416
|
+
* @private
|
|
417
|
+
* @returns {void}
|
|
418
|
+
*/
|
|
419
|
+
public render(): void {
|
|
420
|
+
this.inputString = '';
|
|
421
|
+
this.initLoad = true;
|
|
422
|
+
this.isCustomFiltering = false;
|
|
423
|
+
this.initialSelectedOptions = this.value;
|
|
424
|
+
super.render();
|
|
425
|
+
this.setEnabled();
|
|
426
|
+
this.renderComplete();
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
private initWrapper(): void {
|
|
430
|
+
const hiddenSelect: HTMLElement = this.createElement('select', { className: 'e-hidden-select', attrs: { 'multiple': '' } });
|
|
431
|
+
hiddenSelect.style.visibility = 'hidden';
|
|
432
|
+
this.list.classList.add('e-listbox-wrapper');
|
|
433
|
+
if (this.itemTemplate) {
|
|
434
|
+
this.list.classList.add('e-list-template');
|
|
435
|
+
}
|
|
436
|
+
this.list.classList.add('e-wrapper');
|
|
437
|
+
this.list.classList.add('e-lib');
|
|
438
|
+
if (this.element.tagName === 'EJS-LISTBOX') {
|
|
439
|
+
this.element.setAttribute('tabindex', '0');
|
|
440
|
+
if (this.initLoad) {
|
|
441
|
+
this.element.appendChild(this.list);
|
|
442
|
+
}
|
|
443
|
+
} else {
|
|
444
|
+
if (this.initLoad) {
|
|
445
|
+
this.element.parentElement.insertBefore(this.list, this.element);
|
|
446
|
+
}
|
|
447
|
+
this.list.insertBefore(this.element, this.list.firstChild);
|
|
448
|
+
this.element.style.display = 'none';
|
|
449
|
+
}
|
|
450
|
+
this.list.insertBefore(hiddenSelect, this.list.firstChild);
|
|
451
|
+
if (this.list.getElementsByClassName('e-list-item')[0]) {
|
|
452
|
+
this.list.getElementsByClassName('e-list-item')[0].classList.remove(dropDownBaseClasses.focus);
|
|
453
|
+
}
|
|
454
|
+
if (this.itemTemplate) { this.renderReactTemplates(); }
|
|
455
|
+
removeClass([this.list], [dropDownBaseClasses.content, dropDownBaseClasses.root]);
|
|
456
|
+
this.validationAttribute(this.element as HTMLInputElement, hiddenSelect as HTMLSelectElement);
|
|
457
|
+
this.list.setAttribute('role', 'listbox');
|
|
458
|
+
attributes(this.list, { 'role': 'listbox', 'aria-label': 'listbox', 'aria-multiselectable': this.selectionSettings.mode === 'Multiple' ? 'true' : 'false' });
|
|
459
|
+
this.updateSelectionSettings();
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
private updateSelectionSettings(): void {
|
|
463
|
+
if (this.selectionSettings.showCheckbox && this.selectionSettings.showSelectAll && this.liCollections.length) {
|
|
464
|
+
const l10nSelect: L10n = new L10n(
|
|
465
|
+
this.getModuleName(), { selectAllText: 'Select All', unSelectAllText: 'Unselect All' }, this.locale);
|
|
466
|
+
this.showSelectAll = true;
|
|
467
|
+
this.selectAllText = l10nSelect.getConstant('selectAllText');
|
|
468
|
+
this.unSelectAllText = l10nSelect.getConstant('unSelectAllText');
|
|
469
|
+
this.popupWrapper = this.list;
|
|
470
|
+
this.checkBoxSelectionModule.checkAllParent = null;
|
|
471
|
+
this.notify('selectAll', {});
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
private initDraggable(): void {
|
|
476
|
+
if (this.ulElement) {
|
|
477
|
+
this.ulElement.id = this.element.id + '_parent';
|
|
478
|
+
}
|
|
479
|
+
if (this.allowDragAndDrop) {
|
|
480
|
+
new Sortable(this.ulElement, {
|
|
481
|
+
scope: this.scope,
|
|
482
|
+
itemClass: 'e-list-item',
|
|
483
|
+
dragStart: this.triggerDragStart.bind(this),
|
|
484
|
+
drag: this.triggerDrag.bind(this),
|
|
485
|
+
beforeDrop: this.beforeDragEnd.bind(this),
|
|
486
|
+
drop: this.dragEnd.bind(this),
|
|
487
|
+
placeHolder: () => { return this.createElement('span', { className: 'e-placeholder' }); },
|
|
488
|
+
helper: (e: { sender: Element }) => {
|
|
489
|
+
const wrapper: HTMLElement = this.list.cloneNode() as HTMLElement;
|
|
490
|
+
const ele: HTMLElement = e.sender.cloneNode(true) as HTMLElement;
|
|
491
|
+
wrapper.appendChild(ele);
|
|
492
|
+
const refEle: HTMLElement = this.getItems()[0] as HTMLElement;
|
|
493
|
+
wrapper.style.width = refEle.offsetWidth + 'px';
|
|
494
|
+
wrapper.style.height = refEle.offsetHeight + 'px';
|
|
495
|
+
if ((this.value && this.value.length) > 1 && this.isSelected(ele)) {
|
|
496
|
+
ele.appendChild(this.createElement('span', {
|
|
497
|
+
className: 'e-list-badge', innerHTML: this.value.length + ''
|
|
498
|
+
}));
|
|
499
|
+
}
|
|
500
|
+
wrapper.style.zIndex = getZindexPartial(this.element) + '';
|
|
501
|
+
return wrapper;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
protected updateActionCompleteData(li: HTMLElement, item: { [key: string]: Object }, index: number): void {
|
|
509
|
+
(this.jsonData as { [key: string]: Object }[]).splice(index, 0, item);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
private initToolbar(): void {
|
|
513
|
+
const pos: string = this.toolbarSettings.position;
|
|
514
|
+
const prevScope: string = this.element.getAttribute('data-value');
|
|
515
|
+
if (this.toolbarSettings.items.length) {
|
|
516
|
+
const toolElem: Element = this.createElement('div', { className: 'e-listbox-tool', attrs: { 'role': 'toolbar' } });
|
|
517
|
+
const wrapper: Element = this.createElement('div', {
|
|
518
|
+
className: 'e-listboxtool-wrapper e-lib e-' + pos.toLowerCase()
|
|
519
|
+
});
|
|
520
|
+
this.list.parentElement.insertBefore(wrapper, this.list);
|
|
521
|
+
wrapper.appendChild(pos === 'Right' ? this.list : toolElem);
|
|
522
|
+
wrapper.appendChild(pos === 'Right' ? toolElem : this.list);
|
|
523
|
+
this.createButtons(toolElem);
|
|
524
|
+
if (!this.element.id) {
|
|
525
|
+
this.element.id = getUniqueID('e-' + this.getModuleName());
|
|
526
|
+
}
|
|
527
|
+
if (this.scope) {
|
|
528
|
+
document.querySelector(this.scope).setAttribute('data-value', this.element.id);
|
|
529
|
+
} else {
|
|
530
|
+
this.updateToolBarState();
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
const scope: string = this.element.getAttribute('data-value');
|
|
534
|
+
if (prevScope && scope && (prevScope !== scope)) {
|
|
535
|
+
this.tBListBox = getComponent(document.getElementById(prevScope), this.getModuleName());
|
|
536
|
+
this.tBListBox.updateToolBarState();
|
|
537
|
+
} else if (scope) {
|
|
538
|
+
this.tBListBox = getComponent(document.getElementById(scope), this.getModuleName());
|
|
539
|
+
this.tBListBox.updateToolBarState();
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
private createButtons(toolElem: Element): void {
|
|
544
|
+
let btn: Button;
|
|
545
|
+
let ele: HTMLButtonElement;
|
|
546
|
+
let title: string;
|
|
547
|
+
const l10n: L10n = new L10n(
|
|
548
|
+
this.getModuleName(),
|
|
549
|
+
{
|
|
550
|
+
moveUp: 'Move Up', moveDown: 'Move Down', moveTo: 'Move To',
|
|
551
|
+
moveFrom: 'Move From', moveAllTo: 'Move All To', moveAllFrom: 'Move All From'
|
|
552
|
+
},
|
|
553
|
+
this.locale
|
|
554
|
+
);
|
|
555
|
+
this.toolbarSettings.items.forEach((value: string) => {
|
|
556
|
+
title = l10n.getConstant(value);
|
|
557
|
+
ele = this.createElement('button', {
|
|
558
|
+
attrs: {
|
|
559
|
+
'type': 'button',
|
|
560
|
+
'data-value': value,
|
|
561
|
+
'title': title,
|
|
562
|
+
'aria-label': title
|
|
563
|
+
}
|
|
564
|
+
}) as HTMLButtonElement;
|
|
565
|
+
toolElem.appendChild(ele);
|
|
566
|
+
btn = new Button({ iconCss: 'e-icons e-' + value.toLowerCase() }, ele);
|
|
567
|
+
btn.createElement = this.createElement;
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
protected validationAttribute(input: HTMLInputElement, hiddenSelect: HTMLSelectElement): void {
|
|
572
|
+
super.validationAttribute(input, hiddenSelect);
|
|
573
|
+
hiddenSelect.required = input.required;
|
|
574
|
+
input.required = false;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
private setHeight(): void {
|
|
578
|
+
const ele: HTMLElement = this.toolbarSettings.items.length ? this.list.parentElement : this.list;
|
|
579
|
+
ele.style.height = formatUnit(this.height);
|
|
580
|
+
if (this.allowFiltering && this.height.toString().indexOf('%') < 0) {
|
|
581
|
+
addClass([this.list], 'e-filter-list');
|
|
582
|
+
} else {
|
|
583
|
+
removeClass([this.list], 'e-filter-list');
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
private setCssClass(): void {
|
|
588
|
+
const wrap: Element = this.toolbarSettings.items.length ? this.list.parentElement : this.list;
|
|
589
|
+
if (this.cssClass) {
|
|
590
|
+
addClass([wrap], this.cssClass.replace(/\s+/g, ' ').trim().split(' '));
|
|
591
|
+
}
|
|
592
|
+
if (this.enableRtl) {
|
|
593
|
+
addClass([this.list], 'e-rtl');
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
private setEnable(): void {
|
|
598
|
+
const ele: Element = this.toolbarSettings.items.length ? this.list.parentElement : this.list;
|
|
599
|
+
if (this.enabled) {
|
|
600
|
+
removeClass([ele], cssClass.disabled);
|
|
601
|
+
} else {
|
|
602
|
+
addClass([ele], cssClass.disabled);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
public showSpinner(): void {
|
|
607
|
+
if (!this.spinner) {
|
|
608
|
+
this.spinner = this.createElement('div', { className: 'e-listbox-wrapper' });
|
|
609
|
+
}
|
|
610
|
+
this.spinner.style.height = formatUnit(this.height);
|
|
611
|
+
this.element.parentElement.insertBefore(this.spinner, this.element.nextSibling);
|
|
612
|
+
createSpinner({ target: this.spinner }, this.createElement);
|
|
613
|
+
showSpinner(this.spinner);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
public hideSpinner(): void {
|
|
617
|
+
if (this.spinner.querySelector('.e-spinner-pane')) {
|
|
618
|
+
hideSpinner(this.spinner);
|
|
619
|
+
}
|
|
620
|
+
if (this.spinner.parentElement) {
|
|
621
|
+
detach(this.spinner);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
private onInput(): void {
|
|
626
|
+
this.isDataSourceUpdate = false;
|
|
627
|
+
if (this.keyDownStatus) {
|
|
628
|
+
this.isValidKey = true;
|
|
629
|
+
} else {
|
|
630
|
+
this.isValidKey = false;
|
|
631
|
+
}
|
|
632
|
+
this.keyDownStatus = false;
|
|
633
|
+
this.refreshClearIcon();
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
private clearText(): void {
|
|
637
|
+
this.filterInput.value = '';
|
|
638
|
+
this.refreshClearIcon();
|
|
639
|
+
const event: KeyboardEvent = document.createEvent('KeyboardEvent');
|
|
640
|
+
this.isValidKey = true;
|
|
641
|
+
this.KeyUp(event);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
private refreshClearIcon(): void {
|
|
645
|
+
if (this.filterInput.parentElement.querySelector('.' + listBoxClasses.clearIcon)) {
|
|
646
|
+
const clearElement: HTMLElement = <HTMLElement>this.filterInput.parentElement.querySelector('.' + listBoxClasses.clearIcon);
|
|
647
|
+
clearElement.style.visibility = this.filterInput.value === '' ? 'hidden' : 'visible';
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
protected onActionComplete(
|
|
652
|
+
ulElement: HTMLElement,
|
|
653
|
+
list: obj[] | boolean[] | string[] | number[],
|
|
654
|
+
e?: Object): void {
|
|
655
|
+
let searchEle: Element;
|
|
656
|
+
if (this.allowFiltering && this.list.getElementsByClassName('e-filter-parent')[0]) {
|
|
657
|
+
searchEle = this.list.getElementsByClassName('e-filter-parent')[0].cloneNode(true) as Element;
|
|
658
|
+
}
|
|
659
|
+
if (list.length === 0) {
|
|
660
|
+
const noRecElem: Element = ulElement.childNodes[0] as Element;
|
|
661
|
+
if (noRecElem) {
|
|
662
|
+
ulElement.removeChild(noRecElem);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
super.onActionComplete(ulElement, list, e);
|
|
666
|
+
if (this.allowFiltering && !isNullOrUndefined(searchEle)) {
|
|
667
|
+
this.list.insertBefore(searchEle, this.list.firstElementChild);
|
|
668
|
+
this.filterParent = this.list.getElementsByClassName('e-filter-parent')[0] as HTMLElement;
|
|
669
|
+
this.filterWireEvents(searchEle);
|
|
670
|
+
}
|
|
671
|
+
this.initWrapper();
|
|
672
|
+
this.setSelection();
|
|
673
|
+
this.initDraggable();
|
|
674
|
+
this.mainList = this.ulElement;
|
|
675
|
+
if (this.initLoad) {
|
|
676
|
+
this.jsonData = []; extend(this.jsonData, list, []);
|
|
677
|
+
this.initToolbarAndStyles();
|
|
678
|
+
this.wireEvents();
|
|
679
|
+
if (this.showCheckbox) {
|
|
680
|
+
this.setCheckboxPosition();
|
|
681
|
+
}
|
|
682
|
+
if (this.allowFiltering) {
|
|
683
|
+
this.setFiltering();
|
|
684
|
+
}
|
|
685
|
+
} else {
|
|
686
|
+
if (this.isDataSourceUpdate) {
|
|
687
|
+
this.jsonData = []; extend(this.jsonData, list, []);
|
|
688
|
+
this.isDataSourceUpdate = false;
|
|
689
|
+
}
|
|
690
|
+
if (this.allowFiltering) {
|
|
691
|
+
const filterElem: HTMLInputElement = (this.list.getElementsByClassName('e-input-filter')[0] as HTMLInputElement);
|
|
692
|
+
const txtLength: number = this.filterInput.value.length;
|
|
693
|
+
filterElem.selectionStart = txtLength;
|
|
694
|
+
filterElem.selectionEnd = txtLength;
|
|
695
|
+
filterElem.focus();
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
if (this.toolbarSettings.items.length && this.scope && this.scope.indexOf('#') > -1 && !isNullOrUndefined(e)) {
|
|
699
|
+
const scope: string = this.scope.replace('#', '');
|
|
700
|
+
const scopedLB: ListBox = getComponent(document.getElementById(scope), this.getModuleName());
|
|
701
|
+
scopedLB.initToolbar();
|
|
702
|
+
}
|
|
703
|
+
this.initLoad = false;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
private initToolbarAndStyles(): void {
|
|
707
|
+
this.initToolbar();
|
|
708
|
+
this.setCssClass();
|
|
709
|
+
this.setEnable();
|
|
710
|
+
this.setHeight();
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
private triggerDragStart(args: DragEventArgs ): void {
|
|
714
|
+
let badge: Element;
|
|
715
|
+
args = extend(this.getDragArgs(args), { dragSelected: true }) as DragEventArgs;
|
|
716
|
+
if (Browser.isIos) {
|
|
717
|
+
this.list.style.overflow = 'hidden';
|
|
718
|
+
}
|
|
719
|
+
this.trigger('dragStart', args, (dragEventArgs: DragEventArgs) => {
|
|
720
|
+
this.allowDragAll = dragEventArgs.dragSelected;
|
|
721
|
+
if (!this.allowDragAll) {
|
|
722
|
+
badge = this.ulElement.getElementsByClassName('e-list-badge')[0];
|
|
723
|
+
if (badge) { detach(badge); }
|
|
724
|
+
}
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
private triggerDrag(args: DragEventArgs): void {
|
|
729
|
+
let scrollParent: HTMLElement; let boundRect: DOMRect; const scrollMoved: number = 36;
|
|
730
|
+
let scrollHeight: number = 10;
|
|
731
|
+
if (this.itemTemplate && args.target) {
|
|
732
|
+
if (args.target && args.target.closest('.e-list-item')) {
|
|
733
|
+
scrollHeight = args.target.closest('.e-list-item').scrollHeight;
|
|
734
|
+
} else {
|
|
735
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
736
|
+
const listItem: HTMLElement = (args as any).element.querySelector('.e-list-item');
|
|
737
|
+
if (listItem) {
|
|
738
|
+
scrollHeight = listItem.scrollHeight;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
743
|
+
const event: any = (args as any).event; let wrapper: HTMLElement;
|
|
744
|
+
if (args.target && (args.target.classList.contains('e-listbox-wrapper') || args.target.classList.contains('e-list-item')
|
|
745
|
+
|| args.target.classList.contains('e-filter-parent') || args.target.classList.contains('e-input-group')
|
|
746
|
+
|| args.target.closest('.e-list-item'))) {
|
|
747
|
+
if (args.target.classList.contains('e-list-item') || args.target.classList.contains('e-filter-parent')
|
|
748
|
+
|| args.target.classList.contains('e-input-group')
|
|
749
|
+
|| args.target.closest('.e-list-item')) {
|
|
750
|
+
wrapper = args.target.closest('.e-listbox-wrapper') as HTMLElement;
|
|
751
|
+
} else {
|
|
752
|
+
wrapper = args.target as HTMLElement;
|
|
753
|
+
}
|
|
754
|
+
if (this.allowFiltering) {
|
|
755
|
+
scrollParent = wrapper.querySelector('.e-list-parent');
|
|
756
|
+
} else {
|
|
757
|
+
scrollParent = wrapper;
|
|
758
|
+
}
|
|
759
|
+
boundRect = scrollParent.getBoundingClientRect() as DOMRect;
|
|
760
|
+
if ((boundRect.y + scrollParent.offsetHeight) - (event.clientY + scrollMoved) < 1) {
|
|
761
|
+
scrollParent.scrollTop = scrollParent.scrollTop + scrollHeight;
|
|
762
|
+
}
|
|
763
|
+
else if ((event.clientY - scrollMoved) - boundRect.y < 1) {
|
|
764
|
+
scrollParent.scrollTop = scrollParent.scrollTop - scrollHeight;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
if (args.target === null) {
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
770
|
+
this.trigger('drag', this.getDragArgs(args as DragEventArgs));
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
private beforeDragEnd(args: DropEventArgs): void {
|
|
774
|
+
let items: object[] = [];
|
|
775
|
+
this.dragValue = this.getFormattedValue(args.droppedElement.getAttribute('data-value')) as string;
|
|
776
|
+
if ((this.value as string[]).indexOf(this.dragValue) > -1) {
|
|
777
|
+
args.items = this.getDataByValues(this.value);
|
|
778
|
+
} else {
|
|
779
|
+
args.items = this.getDataByValues([this.dragValue]);
|
|
780
|
+
}
|
|
781
|
+
extend(items, args.items);
|
|
782
|
+
this.trigger('beforeDrop', args);
|
|
783
|
+
if (args.items !== items) {
|
|
784
|
+
this.customDraggedItem = args.items;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
private dragEnd(args: DropEventArgs): void {
|
|
789
|
+
let listData: dataType[]; let liColl: HTMLElement[]; let jsonData: dataType[]; let droppedData: dataType;
|
|
790
|
+
let selectedOptions: (string | boolean | number)[]; let sortedData: dataType[];
|
|
791
|
+
const dropValue: string | number | boolean = this.getFormattedValue(args.droppedElement.getAttribute('data-value'));
|
|
792
|
+
const listObj: ListBox = this.getComponent(args.droppedElement);
|
|
793
|
+
const getArgs: Object = this.getDragArgs({ target: args.droppedElement } as DragEventArgs , true);
|
|
794
|
+
const sourceArgs: Object = { previousData: this.dataSource }; const destArgs: Object = { previousData: listObj.dataSource };
|
|
795
|
+
let dragArgs: Object = extend({}, getArgs, { target: args.target, source: { previousData: this.dataSource },
|
|
796
|
+
previousIndex: args.previousIndex, currentIndex: args.currentIndex });
|
|
797
|
+
if (listObj !== this) {
|
|
798
|
+
const sourceArgs1: Object = extend( sourceArgs, {currentData: this.listData});
|
|
799
|
+
dragArgs = extend(dragArgs, { source: sourceArgs1, destination: destArgs} );
|
|
800
|
+
}
|
|
801
|
+
if (Browser.isIos) {
|
|
802
|
+
this.list.style.overflow = '';
|
|
803
|
+
}
|
|
804
|
+
const targetListObj: ListBox = this.getComponent(args.target);
|
|
805
|
+
if (targetListObj && targetListObj.listData.length === 0) {
|
|
806
|
+
const noRecElem: Element = targetListObj.ulElement.childNodes[0] as Element;
|
|
807
|
+
if (noRecElem) {
|
|
808
|
+
targetListObj.ulElement.removeChild(noRecElem);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
if (listObj === this) {
|
|
812
|
+
const ul: Element = this.ulElement;
|
|
813
|
+
listData = [].slice.call(this.listData); liColl = [].slice.call(this.liCollections);
|
|
814
|
+
jsonData = [].slice.call(this.jsonData); sortedData = [].slice.call(this.sortedData);
|
|
815
|
+
const toSortIdx: number = args.currentIndex;
|
|
816
|
+
let toIdx: number = args.currentIndex = this.getCurIdx(this, args.currentIndex);
|
|
817
|
+
const rIdx: number = listData.indexOf(this.getDataByValue(dropValue));
|
|
818
|
+
const jsonIdx: number = jsonData.indexOf(this.getDataByValue(dropValue));
|
|
819
|
+
const sIdx: number = sortedData.indexOf(this.getDataByValue(dropValue));
|
|
820
|
+
listData.splice(toIdx, 0, listData.splice(rIdx, 1)[0] as obj);
|
|
821
|
+
sortedData.splice(toSortIdx, 0, sortedData.splice(sIdx, 1)[0] as obj);
|
|
822
|
+
jsonData.splice(toIdx, 0, jsonData.splice(jsonIdx, 1)[0] as obj);
|
|
823
|
+
liColl.splice(toIdx, 0, liColl.splice(rIdx, 1)[0] as HTMLElement);
|
|
824
|
+
if (this.allowDragAll) {
|
|
825
|
+
selectedOptions = this.value && Array.prototype.indexOf.call(this.value, dropValue) > -1 ? this.value : [dropValue];
|
|
826
|
+
if (!isNullOrUndefined(this.customDraggedItem)) {
|
|
827
|
+
selectedOptions = [];
|
|
828
|
+
this.customDraggedItem.forEach((item: object) => {
|
|
829
|
+
selectedOptions.push(getValue(this.fields.value, item));
|
|
830
|
+
})
|
|
831
|
+
}
|
|
832
|
+
selectedOptions.forEach((value: string) => {
|
|
833
|
+
if (value !== dropValue) {
|
|
834
|
+
const idx: number = listData.indexOf(this.getDataByValue(value));
|
|
835
|
+
const jsonIdx: number = jsonData.indexOf(this.getDataByValue(value));
|
|
836
|
+
const sIdx: number = sortedData.indexOf(this.getDataByValue(value));
|
|
837
|
+
if (idx > toIdx) {
|
|
838
|
+
toIdx++;
|
|
839
|
+
}
|
|
840
|
+
jsonData.splice(toIdx, 0, jsonData.splice(jsonIdx, 1)[0] as obj);
|
|
841
|
+
listData.splice(toIdx, 0, listData.splice(idx, 1)[0] as obj);
|
|
842
|
+
sortedData.splice(toSortIdx, 0, sortedData.splice(sIdx, 1)[0] as obj);
|
|
843
|
+
liColl.splice(toIdx, 0, liColl.splice(idx, 1)[0] as HTMLElement);
|
|
844
|
+
ul.insertBefore(this.getItems()[this.getIndexByValue(value)], ul.getElementsByClassName('e-placeholder')[0]);
|
|
845
|
+
}
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
(this.listData as dataType[]) = listData; (this.jsonData as dataType[]) = jsonData;
|
|
849
|
+
(this.sortedData as dataType[]) = sortedData; this.liCollections = liColl;
|
|
850
|
+
} else {
|
|
851
|
+
let li: Element; const fLiColl: HTMLElement[] = [].slice.call(this.liCollections);
|
|
852
|
+
let currIdx: number = args.currentIndex = this.getCurIdx(listObj, args.currentIndex); const ul: Element = listObj.ulElement;
|
|
853
|
+
listData = [].slice.call(listObj.listData); liColl = [].slice.call(listObj.liCollections);
|
|
854
|
+
jsonData = [].slice.call(listObj.jsonData); sortedData = [].slice.call(listObj.sortedData);
|
|
855
|
+
selectedOptions = (this.value && Array.prototype.indexOf.call(this.value, dropValue) > -1 && this.allowDragAll)
|
|
856
|
+
? this.value : [dropValue];
|
|
857
|
+
if (!isNullOrUndefined(this.customDraggedItem)) {
|
|
858
|
+
selectedOptions = [];
|
|
859
|
+
this.customDraggedItem.forEach((item: object) => {
|
|
860
|
+
selectedOptions.push(getValue(this.fields.value, item));
|
|
861
|
+
})
|
|
862
|
+
}
|
|
863
|
+
const fListData: dataType[] = [].slice.call(this.listData); const fSortData: dataType[] = [].slice.call(this.sortedData);
|
|
864
|
+
selectedOptions.forEach((value: string, index: number) => {
|
|
865
|
+
droppedData = this.getDataByValue(value);
|
|
866
|
+
const srcIdx: number = (this.listData as dataType[]).indexOf(droppedData);
|
|
867
|
+
const jsonSrcIdx: number = (this.jsonData as dataType[]).indexOf(droppedData);
|
|
868
|
+
const sortIdx: number = (this.sortedData as dataType[]).indexOf(droppedData);
|
|
869
|
+
fListData.splice(srcIdx, 1); this.jsonData.splice(jsonSrcIdx, 1);
|
|
870
|
+
fSortData.splice(sortIdx, 1); (this.listData as dataType[]) = fListData; (this.sortedData as dataType[]) = fSortData;
|
|
871
|
+
const destIdx: number = value === dropValue ? args.currentIndex : currIdx;
|
|
872
|
+
listData.splice(destIdx, 0, droppedData); jsonData.splice(destIdx, 0, droppedData);
|
|
873
|
+
sortedData.splice(destIdx, 0, droppedData);
|
|
874
|
+
liColl.splice(destIdx, 0, fLiColl.splice(srcIdx, 1)[0]);
|
|
875
|
+
if (!value) {
|
|
876
|
+
const liCollElem: Element[] = this.getItems();
|
|
877
|
+
for (let i: number = 0; i < liCollElem.length; i++ ) {
|
|
878
|
+
if (liCollElem[i as number].getAttribute('data-value') === null && liCollElem[i as number].classList.contains('e-list-item')) {
|
|
879
|
+
li = liCollElem[i as number];
|
|
880
|
+
break;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
} else {
|
|
884
|
+
li = this.getItems()[this.getIndexByValue(value)];
|
|
885
|
+
}
|
|
886
|
+
if (!li) { li = args.helper; }
|
|
887
|
+
this.removeSelected(this, value === dropValue ? [args.droppedElement] : [li]);
|
|
888
|
+
ul.insertBefore(li, ul.getElementsByClassName('e-placeholder')[0]);
|
|
889
|
+
currIdx++;
|
|
890
|
+
});
|
|
891
|
+
if (this.fields.groupBy) {
|
|
892
|
+
const sourceElem: HTMLElement = this.renderItems(this.listData as obj[], this.fields);
|
|
893
|
+
this.updateListItems(sourceElem, this.ulElement); this.setSelection();
|
|
894
|
+
}
|
|
895
|
+
if (listObj.sortOrder !== 'None' || this.selectionSettings.showCheckbox
|
|
896
|
+
!== listObj.selectionSettings.showCheckbox || listObj.fields.groupBy || listObj.itemTemplate || this.itemTemplate) {
|
|
897
|
+
const sortable: { placeHolderElement: Element } = getComponent(ul as HTMLElement, 'sortable');
|
|
898
|
+
const sourceElem: HTMLElement = listObj.renderItems(listData as obj[], listObj.fields);
|
|
899
|
+
listObj.updateListItems(sourceElem, ul as HTMLElement); this.setSelection();
|
|
900
|
+
if (sortable.placeHolderElement) {
|
|
901
|
+
ul.appendChild(sortable.placeHolderElement);
|
|
902
|
+
}
|
|
903
|
+
ul.appendChild(args.helper); listObj.setSelection();
|
|
904
|
+
}
|
|
905
|
+
this.liCollections = fLiColl; listObj.liCollections = liColl;
|
|
906
|
+
(listObj.jsonData as dataType[]) = extend([], [], jsonData, false) as dataType[];
|
|
907
|
+
(listObj.listData as dataType[]) = extend([], [], listData, false) as dataType[];
|
|
908
|
+
(listObj.sortedData as dataType[]) = extend([], [], sortedData, false) as dataType[];
|
|
909
|
+
if (this.listData.length === 0) {
|
|
910
|
+
this.l10nUpdate();
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
if (this === listObj) {
|
|
914
|
+
const sourceArgs1: Object = extend( sourceArgs, {currentData: listData});
|
|
915
|
+
dragArgs = extend(dragArgs, {source: sourceArgs1});
|
|
916
|
+
} else {
|
|
917
|
+
const dragArgs1: Object = extend(destArgs, {currentData: listData});
|
|
918
|
+
dragArgs = extend(dragArgs, { destination: dragArgs1 });
|
|
919
|
+
}
|
|
920
|
+
if (!isNullOrUndefined(this.customDraggedItem)) {
|
|
921
|
+
(dragArgs as DragEventArgs).items = this.customDraggedItem;
|
|
922
|
+
}
|
|
923
|
+
this.trigger('drop', dragArgs);
|
|
924
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
925
|
+
const liCollElem: NodeListOf<Element> = (dragArgs as any).elements;
|
|
926
|
+
if (liCollElem.length) {
|
|
927
|
+
for (let i: number = 0; i < liCollElem.length; i++) {
|
|
928
|
+
liCollElem[i as number].classList.remove('e-grabbed');
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
private updateListItems(sourceElem: HTMLElement, destElem: HTMLElement): void {
|
|
934
|
+
const i: number = 0;
|
|
935
|
+
destElem.innerHTML = '';
|
|
936
|
+
while (i < sourceElem.childNodes.length) {
|
|
937
|
+
destElem.appendChild(sourceElem.childNodes[i as number]);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
private removeSelected(listObj: ListBox, elems: Element[]): void {
|
|
942
|
+
if (listObj.selectionSettings.showCheckbox) {
|
|
943
|
+
elems.forEach((ele: Element) => { ele.getElementsByClassName('e-frame')[0].classList.remove('e-check'); });
|
|
944
|
+
} else {
|
|
945
|
+
removeClass(elems, cssClass.selected);
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
private getCurIdx(listObj: ListBox, idx: number): number {
|
|
950
|
+
if (listObj.fields.groupBy) {
|
|
951
|
+
idx -= [].slice.call(listObj.ulElement.children).slice(0, idx)
|
|
952
|
+
.filter((ele: Element) => ele.classList.contains(cssClass.group)).length;
|
|
953
|
+
}
|
|
954
|
+
return idx;
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
private getComponent(li: Element): ListBox {
|
|
958
|
+
let listObj: ListBox;
|
|
959
|
+
const ele: HTMLElement = (this.element.tagName === 'EJS-LISTBOX' ? closest(li, '.e-listbox')
|
|
960
|
+
: closest(li, '.e-listbox-wrapper') && closest(li, '.e-listbox-wrapper').querySelector('.e-listbox')) as HTMLElement;
|
|
961
|
+
if (ele) {
|
|
962
|
+
listObj = getComponent(ele, this.getModuleName());
|
|
963
|
+
}
|
|
964
|
+
return listObj;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
/**
|
|
968
|
+
* Sets the enabled state to DropDownBase.
|
|
969
|
+
*
|
|
970
|
+
* @returns {void}
|
|
971
|
+
*/
|
|
972
|
+
protected setEnabled(): void {
|
|
973
|
+
this.element.setAttribute('aria-disabled', (this.enabled) ? 'false' : 'true');
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
protected listOption(
|
|
977
|
+
dataSource: obj[] | string[] | number[] | boolean[],
|
|
978
|
+
fields: FieldSettingsModel): FieldSettingsModel {
|
|
979
|
+
this.listCurrentOptions = super.listOption(dataSource, fields);
|
|
980
|
+
this.listCurrentOptions = extend({}, this.listCurrentOptions, { itemCreated: this.triggerBeforeItemRender.bind(this) }, true);
|
|
981
|
+
this.notify('listoption', { module: 'CheckBoxSelection' });
|
|
982
|
+
return this.listCurrentOptions;
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
private triggerBeforeItemRender(e: { item: Element, curData: obj }): void {
|
|
986
|
+
e.item.setAttribute('tabindex', '-1');
|
|
987
|
+
this.trigger('beforeItemRender', { element: e.item, item: e.curData });
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
public requiredModules(): ModuleDeclaration[] {
|
|
991
|
+
const modules: ModuleDeclaration[] = [];
|
|
992
|
+
if (this.selectionSettings.showCheckbox) {
|
|
993
|
+
modules.push({
|
|
994
|
+
member: 'CheckBoxSelection',
|
|
995
|
+
args: [this]
|
|
996
|
+
});
|
|
997
|
+
}
|
|
998
|
+
return modules;
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
/**
|
|
1002
|
+
* This method is used to enable or disable the items in the ListBox based on the items and enable argument.
|
|
1003
|
+
*
|
|
1004
|
+
* @param {string[]} items - Text items that needs to be enabled/disabled.
|
|
1005
|
+
* @param {boolean} enable - Set `true`/`false` to enable/disable the list items.
|
|
1006
|
+
* @param {boolean} isValue - Set `true` if `items` parameter is a array of unique values.
|
|
1007
|
+
* @returns {void}
|
|
1008
|
+
*/
|
|
1009
|
+
public enableItems(items: string[], enable: boolean = true, isValue?: boolean): void {
|
|
1010
|
+
let li: HTMLElement;
|
|
1011
|
+
items.forEach((item: string) => {
|
|
1012
|
+
const text: string = item;
|
|
1013
|
+
li = this.findListElement(this.list, 'li', 'data-value', isValue ? text : this.getValueByText(text));
|
|
1014
|
+
if (!li) { return; }
|
|
1015
|
+
if (enable) {
|
|
1016
|
+
removeClass([li], cssClass.disabled);
|
|
1017
|
+
li.removeAttribute('aria-disabled');
|
|
1018
|
+
} else {
|
|
1019
|
+
addClass([li], cssClass.disabled);
|
|
1020
|
+
li.setAttribute('aria-disabled', 'true');
|
|
1021
|
+
}
|
|
1022
|
+
});
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
/**
|
|
1026
|
+
* Based on the state parameter, specified list item will be selected/deselected.
|
|
1027
|
+
*
|
|
1028
|
+
* @param {string[]} items - Array of text value of the item.
|
|
1029
|
+
* @param {boolean} state - Set `true`/`false` to select/un select the list items.
|
|
1030
|
+
* @param {boolean} isValue - Set `true` if `items` parameter is a array of unique values.
|
|
1031
|
+
* @returns {void}
|
|
1032
|
+
*/
|
|
1033
|
+
public selectItems(items: string[], state: boolean = true, isValue?: boolean): void {
|
|
1034
|
+
if (state && !this.selectionSettings.showCheckbox && this.selectionSettings.mode === 'Single') {
|
|
1035
|
+
this.getSelectedItems().forEach((li: Element) => {
|
|
1036
|
+
li.classList.remove('e-active');
|
|
1037
|
+
li.removeAttribute('aria-selected');
|
|
1038
|
+
removeClass([li], cssClass.selected);
|
|
1039
|
+
});
|
|
1040
|
+
}
|
|
1041
|
+
this.setSelection(items, state, !isValue);
|
|
1042
|
+
this.updateSelectedOptions();
|
|
1043
|
+
let selElems: Element[] = [];
|
|
1044
|
+
for (let i: number = 0; i < items.length; i++) {
|
|
1045
|
+
const liColl: NodeListOf<Element> = this.list.querySelectorAll('[aria-selected="true"]');
|
|
1046
|
+
for (let j: number = 0; j < liColl.length; j++) {
|
|
1047
|
+
if (items[i as number] === this.getFormattedValue(liColl[j as number].getAttribute('data-value')) as string) {
|
|
1048
|
+
selElems.push(liColl[j as number])
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
this.triggerChange(selElems, null);
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
/**
|
|
1056
|
+
* Based on the state parameter, entire list item will be selected/deselected.
|
|
1057
|
+
*
|
|
1058
|
+
* @param {boolean} state - Set `true`/`false` to select/un select the entire list items.
|
|
1059
|
+
* @returns {void}
|
|
1060
|
+
*/
|
|
1061
|
+
public selectAll(state: boolean = true): void {
|
|
1062
|
+
this.selectAllItems(state);
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
/**
|
|
1066
|
+
* Adds a new item to the list. By default, new item appends to the list as the last item,
|
|
1067
|
+
* but you can insert based on the index parameter.
|
|
1068
|
+
*
|
|
1069
|
+
* @param { Object[] } items - Specifies an array of JSON data or a JSON data.
|
|
1070
|
+
* @param { number } itemIndex - Specifies the index to place the newly added item in the list.
|
|
1071
|
+
* @returns {void}.
|
|
1072
|
+
*/
|
|
1073
|
+
public addItems(items: obj[] | obj, itemIndex?: number): void {
|
|
1074
|
+
super.addItem(items, itemIndex);
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* Removes a item from the list. By default, removed the last item in the list,
|
|
1078
|
+
* but you can remove based on the index parameter.
|
|
1079
|
+
*
|
|
1080
|
+
* @param { Object[] } items - Specifies an array of JSON data or a JSON data.
|
|
1081
|
+
* @param { number } itemIndex - Specifies the index to remove the item from the list.
|
|
1082
|
+
* @returns {void}.
|
|
1083
|
+
*/
|
|
1084
|
+
public removeItems(items?: obj[] | obj, itemIndex?: number): void {
|
|
1085
|
+
this.removeItem(items, itemIndex);
|
|
1086
|
+
}
|
|
1087
|
+
/**
|
|
1088
|
+
* Removes a item from the list. By default, removed the last item in the list,
|
|
1089
|
+
* but you can remove based on the index parameter.
|
|
1090
|
+
*
|
|
1091
|
+
* @param { Object[] } items - Specifies an array of JSON data or a JSON data.
|
|
1092
|
+
* @param { number } itemIndex - Specifies the index to remove the item from the list.
|
|
1093
|
+
* @returns {void}.
|
|
1094
|
+
*/
|
|
1095
|
+
public removeItem(
|
|
1096
|
+
items?: { [key: string]: Object }[] | { [key: string]: Object } | string | boolean | number | string[] | boolean[] | number[],
|
|
1097
|
+
itemIndex?: number): void {
|
|
1098
|
+
const liCollections: HTMLElement[] = [];
|
|
1099
|
+
const liElement: HTMLElement[] | NodeListOf<HTMLLIElement> = this.list.querySelectorAll('.' + dropDownBaseClasses.li);
|
|
1100
|
+
if (items) {
|
|
1101
|
+
items = (items instanceof Array ? items : [items]) as { [key: string]: Object }[] | string[] | boolean[] | number[];
|
|
1102
|
+
const fields: FieldSettingsModel = this.fields; let dataValue: string; let objValue: string;
|
|
1103
|
+
const dupData: {[key: string]: Object }[] = []; let itemIdx: number;
|
|
1104
|
+
extend(dupData, [], this.jsonData as { [key: string]: Object }[]);
|
|
1105
|
+
const removeIdxes: number [] = []; const removeLiIdxes: number [] = [];
|
|
1106
|
+
for (let j: number = 0; j < items.length; j++) {
|
|
1107
|
+
if (items[j as number] instanceof Object) {
|
|
1108
|
+
dataValue = getValue(fields.value, items[j as number]);
|
|
1109
|
+
} else {
|
|
1110
|
+
dataValue = items[j as number].toString();
|
|
1111
|
+
}
|
|
1112
|
+
for (let i: number = 0, len: number = dupData.length; i < len; i++) {
|
|
1113
|
+
if (dupData[i as number] instanceof Object) {
|
|
1114
|
+
objValue = getValue(fields.value, dupData[i as number]);
|
|
1115
|
+
} else {
|
|
1116
|
+
objValue = dupData[i as number].toString();
|
|
1117
|
+
}
|
|
1118
|
+
if (objValue === dataValue) {
|
|
1119
|
+
itemIdx = this.getIndexByValue(dataValue);
|
|
1120
|
+
const idx: number = itemIdx === i ? itemIdx : i;
|
|
1121
|
+
liCollections.push(liElement[idx as number]);
|
|
1122
|
+
removeIdxes.push(idx);
|
|
1123
|
+
removeLiIdxes.push(idx);
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
for (let k: number = removeIdxes.length - 1; k >= 0; k--) {
|
|
1128
|
+
(this.listData as { [key: string]: Object }[]).splice(removeIdxes[k as number], 1);
|
|
1129
|
+
}
|
|
1130
|
+
for (let k: number = removeIdxes.length - 1; k >= 0; k--) {
|
|
1131
|
+
(this.jsonData as { [key: string]: Object }[]).splice(removeIdxes[k as number], 1);
|
|
1132
|
+
}
|
|
1133
|
+
for (let k: number = removeLiIdxes.length - 1; k >= 0; k--) {
|
|
1134
|
+
this.updateLiCollection(removeLiIdxes[k as number]);
|
|
1135
|
+
}
|
|
1136
|
+
} else {
|
|
1137
|
+
itemIndex = itemIndex ? itemIndex : 0;
|
|
1138
|
+
liCollections.push(liElement[itemIndex as number]);
|
|
1139
|
+
(this.listData as { [key: string]: Object }[]).splice(itemIndex, 1);
|
|
1140
|
+
(this.jsonData as { [key: string]: Object }[]).splice(itemIndex, 1);
|
|
1141
|
+
this.updateLiCollection(itemIndex);
|
|
1142
|
+
}
|
|
1143
|
+
for (let i: number = 0; i < liCollections.length; i++) {
|
|
1144
|
+
this.ulElement.removeChild(liCollections[i as number]);
|
|
1145
|
+
}
|
|
1146
|
+
if (this.listData.length === 0) {
|
|
1147
|
+
this.l10nUpdate();
|
|
1148
|
+
}
|
|
1149
|
+
this.value = [];
|
|
1150
|
+
this.updateToolBarState();
|
|
1151
|
+
}
|
|
1152
|
+
/**
|
|
1153
|
+
* Gets the array of data Object that matches the given array of values.
|
|
1154
|
+
*
|
|
1155
|
+
* @param { string[] | number[] | boolean[] } value - Specifies the array value of the list item.
|
|
1156
|
+
* @returns {object[]}.
|
|
1157
|
+
*/
|
|
1158
|
+
public getDataByValues(value: string[] | number[] | boolean[] ): { [key: string]: Object }[] {
|
|
1159
|
+
const data: string | number | boolean | { [key: string]: Object }[] = [];
|
|
1160
|
+
for (let i: number = 0; i < value.length; i++) {
|
|
1161
|
+
data.push(this.getDataByValue(value[i as number]) as { [key: string]: Object });
|
|
1162
|
+
}
|
|
1163
|
+
return data;
|
|
1164
|
+
}
|
|
1165
|
+
/**
|
|
1166
|
+
* Moves the given value(s) / selected value(s) upwards.
|
|
1167
|
+
*
|
|
1168
|
+
* @param { string[] | number[] | boolean[] } value - Specifies the value(s).
|
|
1169
|
+
* @returns {void}
|
|
1170
|
+
*/
|
|
1171
|
+
public moveUp(value?: string[] | number[] | boolean[]): void {
|
|
1172
|
+
const elem: Element[] = (value) ? this.getElemByValue(value) : this.getSelectedItems();
|
|
1173
|
+
this.moveUpDown(true, false, elem);
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Moves the given value(s) / selected value(s) downwards.
|
|
1177
|
+
*
|
|
1178
|
+
* @param { string[] | number[] | boolean[] } value - Specifies the value(s).
|
|
1179
|
+
* @returns {void}
|
|
1180
|
+
*/
|
|
1181
|
+
public moveDown(value?: string[] | number[] | boolean[]): void {
|
|
1182
|
+
const elem: Element[] = (value) ? this.getElemByValue(value) : this.getSelectedItems();
|
|
1183
|
+
this.moveUpDown(false, false, elem);
|
|
1184
|
+
}
|
|
1185
|
+
/**
|
|
1186
|
+
* Moves the given value(s) / selected value(s) in Top of the list.
|
|
1187
|
+
*
|
|
1188
|
+
* @param { string[] | number[] | boolean[] } value - Specifies the value(s).
|
|
1189
|
+
* @returns {void}
|
|
1190
|
+
*/
|
|
1191
|
+
public moveTop(value?: string[] | number[] | boolean[]): void {
|
|
1192
|
+
const elem: Element[] = (value) ? this.getElemByValue(value) : this.getSelectedItems();
|
|
1193
|
+
this.moveUpDown(null, false, elem, true);
|
|
1194
|
+
}
|
|
1195
|
+
/**
|
|
1196
|
+
* Moves the given value(s) / selected value(s) in bottom of the list.
|
|
1197
|
+
*
|
|
1198
|
+
* @param { string[] | number[] | boolean[] } value - Specifies the value(s).
|
|
1199
|
+
* @returns {void}
|
|
1200
|
+
*/
|
|
1201
|
+
public moveBottom(value?: string[] | number[] | boolean[]): void {
|
|
1202
|
+
const elem: Element[] = (value) ? this.getElemByValue(value) : this.getSelectedItems();
|
|
1203
|
+
this.moveUpDown(true, false, elem, false, true);
|
|
1204
|
+
}
|
|
1205
|
+
/**
|
|
1206
|
+
* Moves the given value(s) / selected value(s) to the given / default scoped ListBox.
|
|
1207
|
+
*
|
|
1208
|
+
* @param { string[] | number[] | boolean[] } value - Specifies the value or array value of the list item.
|
|
1209
|
+
* @param {number} index - Specifies the index.
|
|
1210
|
+
* @param {string} targetId - Specifies the target id.
|
|
1211
|
+
* @returns {void}
|
|
1212
|
+
*/
|
|
1213
|
+
public moveTo(value?: string[] | number[] | boolean[], index?: number, targetId?: string): void {
|
|
1214
|
+
const elem: Element[] = (value) ? this.getElemByValue(value) : this.getSelectedItems();
|
|
1215
|
+
const tlistbox: ListBox = (targetId) ? getComponent(targetId, ListBox) : this.getScopedListBox();
|
|
1216
|
+
this.moveData(this, tlistbox, false, elem, index);
|
|
1217
|
+
}
|
|
1218
|
+
/**
|
|
1219
|
+
* Moves all the values from one ListBox to the scoped ListBox.
|
|
1220
|
+
*
|
|
1221
|
+
* @param { string } targetId - Specifies the scoped ListBox ID.
|
|
1222
|
+
* @param { string } index - Specifies the index to where the items moved.
|
|
1223
|
+
* @returns {void}
|
|
1224
|
+
*/
|
|
1225
|
+
public moveAllTo(targetId?: string, index?: number): void {
|
|
1226
|
+
if (this.listData.length > 0) {
|
|
1227
|
+
const tlistbox: ListBox = (targetId) ? getComponent(targetId, ListBox) : this.getScopedListBox();
|
|
1228
|
+
this.moveAllData(this, tlistbox, false, index);
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
/* eslint-disable */
|
|
1232
|
+
/**
|
|
1233
|
+
* Gets the updated dataSource in ListBox.
|
|
1234
|
+
*
|
|
1235
|
+
* @returns {{ [key: string]: Object }[] | string[] | boolean[] | number[]} - Updated DataSource.
|
|
1236
|
+
*/
|
|
1237
|
+
/* eslint-enable */
|
|
1238
|
+
public getDataList(): { [key: string]: Object }[] | string[] | boolean[] | number[] {
|
|
1239
|
+
return this.jsonData;
|
|
1240
|
+
}
|
|
1241
|
+
/* eslint-disable */
|
|
1242
|
+
/**
|
|
1243
|
+
* Returns the sorted Data in ListBox.
|
|
1244
|
+
*
|
|
1245
|
+
* @returns {{ [key: string]: Object }[] | string[] | boolean[] | number[]} - Sorted data
|
|
1246
|
+
*/
|
|
1247
|
+
/* eslint-enable */
|
|
1248
|
+
public getSortedList(): { [key: string]: Object }[] | string[] | boolean[] | number[] {
|
|
1249
|
+
let sortData: dataType[]; let tempData: { [key: string]: Object }[] | string[] | boolean[] | number[];
|
|
1250
|
+
sortData = tempData = this.sortedData;
|
|
1251
|
+
if (this.fields.groupBy) {
|
|
1252
|
+
sortData = [];
|
|
1253
|
+
for (let i: number = 0; i < tempData.length; i++) {
|
|
1254
|
+
if ((tempData[i as number] as { [key: string]: Object }).isHeader) {
|
|
1255
|
+
continue;
|
|
1256
|
+
}
|
|
1257
|
+
sortData.push(tempData[i as number]);
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
return sortData as { [key: string]: Object }[] | string[] | boolean[] | number[];
|
|
1261
|
+
}
|
|
1262
|
+
private getElemByValue(value: string[] | number[] | boolean[]): Element[] {
|
|
1263
|
+
const elem: Element[] = [];
|
|
1264
|
+
for (let i: number = 0; i < value.length; i++) {
|
|
1265
|
+
elem.push(this.ulElement.querySelector('[data-value ="' + value[i as number] + '"]'));
|
|
1266
|
+
}
|
|
1267
|
+
return elem;
|
|
1268
|
+
}
|
|
1269
|
+
private updateLiCollection(index: number): void {
|
|
1270
|
+
const tempLi: HTMLElement[] = [].slice.call(this.liCollections);
|
|
1271
|
+
tempLi.splice(index, 1);
|
|
1272
|
+
this.liCollections = tempLi;
|
|
1273
|
+
}
|
|
1274
|
+
private selectAllItems(state: boolean, event?: MouseEvent): void {
|
|
1275
|
+
[].slice.call(this.getItems()).forEach((li: Element) => {
|
|
1276
|
+
if (!li.classList.contains(cssClass.disabled)) {
|
|
1277
|
+
if (this.selectionSettings.showCheckbox) {
|
|
1278
|
+
const ele: Element = li.getElementsByClassName('e-check')[0];
|
|
1279
|
+
if ((!ele && state) || (ele && !state)) {
|
|
1280
|
+
this.notify('updatelist', { li: li, module: 'listbox' });
|
|
1281
|
+
if (this.maximumSelectionLength >= this.list.querySelectorAll('.e-list-item span.e-check').length) {
|
|
1282
|
+
this.checkMaxSelection();
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
} else {
|
|
1286
|
+
if (state) {
|
|
1287
|
+
li.classList.add(cssClass.selected);
|
|
1288
|
+
} else {
|
|
1289
|
+
li.classList.remove(cssClass.selected);
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
});
|
|
1294
|
+
this.updateSelectedOptions();
|
|
1295
|
+
if (this.allowFiltering && this.selectionSettings.showCheckbox) {
|
|
1296
|
+
const liEle: HTMLCollectionOf<HTMLLIElement> = this.list.getElementsByTagName('li') as HTMLCollectionOf<HTMLLIElement>;
|
|
1297
|
+
let index: number = 0;
|
|
1298
|
+
if (state) {
|
|
1299
|
+
for (index = 0; index < liEle.length; index++) {
|
|
1300
|
+
const dataValue1: string = this.getFormattedValue(liEle[index as number].getAttribute('data-value')) as string;
|
|
1301
|
+
if (!(this.value as string[]).some((e: string) => e === dataValue1)) {
|
|
1302
|
+
(this.value as string[]).push(this.getFormattedValue(liEle[index as number].getAttribute('data-value')) as string);
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
} else {
|
|
1306
|
+
for (index = 0; index < liEle.length; index++) {
|
|
1307
|
+
const dataValue2: string = this.getFormattedValue(liEle[index as number].getAttribute('data-value')) as string;
|
|
1308
|
+
this.value = (this.value as string[]).filter((e: string) => e !== dataValue2);
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
if (document.querySelectorAll('ul').length < 2) {
|
|
1312
|
+
this.updateMainList();
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
this.triggerChange(this.getSelectedItems(), event);
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
private updateMainList(): void {
|
|
1319
|
+
const mainList: NodeListOf<Element> = this.mainList.querySelectorAll('.e-list-item');
|
|
1320
|
+
const ulList: NodeListOf<Element> = this.ulElement.querySelectorAll('.e-list-item');
|
|
1321
|
+
const mainCount: number = mainList.length; const ulEleCount: number = ulList.length;
|
|
1322
|
+
if (this.selectionSettings.showCheckbox || (document.querySelectorAll('ul').length > 1 || mainCount !== ulEleCount)) {
|
|
1323
|
+
let listindex: number = 0;
|
|
1324
|
+
let valueindex: number = 0;
|
|
1325
|
+
let count: number = 0;
|
|
1326
|
+
for (listindex; listindex < mainCount; ) {
|
|
1327
|
+
if (this.value) {
|
|
1328
|
+
for (valueindex; valueindex < this.value.length; valueindex++) {
|
|
1329
|
+
if (mainList[listindex as number].getAttribute('data-value') === this.value[valueindex as number]) {
|
|
1330
|
+
count++;
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
if (!count && this.selectionSettings.showCheckbox) {
|
|
1335
|
+
mainList[listindex as number].getElementsByClassName('e-frame')[0].classList.remove('e-check');
|
|
1336
|
+
}
|
|
1337
|
+
if (document.querySelectorAll('ul').length > 1 && count && mainCount !== ulEleCount) {
|
|
1338
|
+
this.mainList.removeChild(this.mainList.getElementsByTagName('li')[listindex as number]);
|
|
1339
|
+
listindex = 0;
|
|
1340
|
+
} else {
|
|
1341
|
+
listindex++;
|
|
1342
|
+
}
|
|
1343
|
+
count = 0;
|
|
1344
|
+
valueindex = 0;
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
private wireEvents(): void {
|
|
1350
|
+
const form: Element = closest(this.element, 'form');
|
|
1351
|
+
const wrapper: Element = this.element.tagName === 'EJS-LISTBOX' ? this.element : this.list;
|
|
1352
|
+
EventHandler.add(this.list, 'click', this.clickHandler, this);
|
|
1353
|
+
EventHandler.add(wrapper, 'keydown', this.keyDownHandler, this);
|
|
1354
|
+
EventHandler.add(wrapper, 'focusout', this.focusOutHandler, this);
|
|
1355
|
+
this.wireToolbarEvent();
|
|
1356
|
+
if (this.selectionSettings.showCheckbox) {
|
|
1357
|
+
EventHandler.remove(document, 'mousedown', this.checkBoxSelectionModule.onDocumentClick);
|
|
1358
|
+
}
|
|
1359
|
+
if (this.fields.groupBy || this.element.querySelector('select>optgroup')) {
|
|
1360
|
+
EventHandler.remove(this.list, 'scroll', this.setFloatingHeader);
|
|
1361
|
+
}
|
|
1362
|
+
if (form) {
|
|
1363
|
+
EventHandler.add(form, 'reset', this.formResetHandler, this);
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
private wireToolbarEvent(): void {
|
|
1368
|
+
if (this.toolbarSettings.items.length) {
|
|
1369
|
+
EventHandler.add(this.getToolElem(), 'click', this.toolbarClickHandler, this);
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
private unwireEvents(): void {
|
|
1374
|
+
const form: Element = closest(this.element, 'form');
|
|
1375
|
+
const wrapper: Element = this.element.tagName === 'EJS-LISTBOX' ? this.element : this.list;
|
|
1376
|
+
EventHandler.remove(this.list, 'click', this.clickHandler);
|
|
1377
|
+
EventHandler.remove(wrapper, 'keydown', this.keyDownHandler);
|
|
1378
|
+
EventHandler.remove(wrapper, 'focusout', this.focusOutHandler);
|
|
1379
|
+
if (this.allowFiltering && this.clearFilterIconElem) {
|
|
1380
|
+
EventHandler.remove(this.clearFilterIconElem, 'click', this.clearText);
|
|
1381
|
+
}
|
|
1382
|
+
if (this.toolbarSettings.items.length) {
|
|
1383
|
+
EventHandler.remove(this.getToolElem(), 'click', this.toolbarClickHandler);
|
|
1384
|
+
}
|
|
1385
|
+
if (form) {
|
|
1386
|
+
EventHandler.remove(form, 'reset', this.formResetHandler);
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
private clickHandler(e: MouseEvent): void {
|
|
1391
|
+
this.selectHandler(e);
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
private checkSelectAll(): void {
|
|
1395
|
+
let searchCount: number = 0;
|
|
1396
|
+
const liItems: NodeListOf<Element> = this.list.querySelectorAll('li.' + dropDownBaseClasses.li);
|
|
1397
|
+
for (let i: number = 0; i < liItems.length; i++) {
|
|
1398
|
+
if (!liItems[i as number].classList.contains('e-disabled')) {
|
|
1399
|
+
searchCount++;
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
const len: number = this.getSelectedItems().length;
|
|
1403
|
+
if (this.showSelectAll && searchCount) {
|
|
1404
|
+
this.notify('checkSelectAll', { module: 'CheckBoxSelection',
|
|
1405
|
+
value: (searchCount === len) ? 'check' : (len === 0) ? 'uncheck' : 'indeterminate'});
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
protected getQuery(query: Query): Query {
|
|
1410
|
+
let filterQuery: Query = query ? query.clone() : this.query ? this.query.clone() : new Query();
|
|
1411
|
+
if (this.allowFiltering) {
|
|
1412
|
+
const filterType: string = this.inputString === '' ? 'contains' : this.filterType;
|
|
1413
|
+
let dataType: string = <string>this.typeOfData(this.dataSource as { [key: string]: Object; }[]).typeof;
|
|
1414
|
+
if (dataType === null) {
|
|
1415
|
+
dataType = <string>this.typeOfData(this.jsonData as { [key: string]: Object; }[]).typeof;
|
|
1416
|
+
}
|
|
1417
|
+
if (!(this.dataSource instanceof DataManager) && dataType === 'string' || dataType === 'number') {
|
|
1418
|
+
filterQuery.where('', filterType, this.inputString, this.ignoreCase, this.ignoreAccent);
|
|
1419
|
+
} else {
|
|
1420
|
+
const fields: string = (this.fields.text) ? this.fields.text : '';
|
|
1421
|
+
filterQuery.where(fields, filterType, this.inputString, this.ignoreCase, this.ignoreAccent);
|
|
1422
|
+
}
|
|
1423
|
+
} else {
|
|
1424
|
+
filterQuery = query ? query : this.query ? this.query : new Query();
|
|
1425
|
+
}
|
|
1426
|
+
return filterQuery;
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
private setFiltering(): InputObject | void {
|
|
1430
|
+
let filterInputObj: InputObject;
|
|
1431
|
+
if (this.initLoad || isNullOrUndefined(this.filterParent)) {
|
|
1432
|
+
this.filterParent = this.createElement('span', {
|
|
1433
|
+
className: listBoxClasses.filterParent
|
|
1434
|
+
});
|
|
1435
|
+
this.filterInput = <HTMLInputElement>this.createElement('input', {
|
|
1436
|
+
attrs: { type: 'text' },
|
|
1437
|
+
className: listBoxClasses.filterInput
|
|
1438
|
+
});
|
|
1439
|
+
this.element.parentNode.insertBefore(this.filterInput, this.element);
|
|
1440
|
+
filterInputObj = Input.createInput(
|
|
1441
|
+
{
|
|
1442
|
+
element: this.filterInput,
|
|
1443
|
+
buttons: [listBoxClasses.filterBarClearIcon],
|
|
1444
|
+
properties: { placeholder: this.filterBarPlaceholder }
|
|
1445
|
+
},
|
|
1446
|
+
this.createElement
|
|
1447
|
+
);
|
|
1448
|
+
append([filterInputObj.container], this.filterParent);
|
|
1449
|
+
prepend([this.filterParent], this.list);
|
|
1450
|
+
attributes(this.filterInput, {
|
|
1451
|
+
'aria-disabled': 'false',
|
|
1452
|
+
'aria-label': 'search list item',
|
|
1453
|
+
'autocomplete': 'off',
|
|
1454
|
+
'autocorrect': 'off',
|
|
1455
|
+
'autocapitalize': 'off',
|
|
1456
|
+
'spellcheck': 'false'
|
|
1457
|
+
});
|
|
1458
|
+
if (this.height.toString().indexOf('%') < 0) {
|
|
1459
|
+
addClass([this.list], 'e-filter-list');
|
|
1460
|
+
}
|
|
1461
|
+
this.inputString = this.filterInput.value;
|
|
1462
|
+
this.filterWireEvents();
|
|
1463
|
+
return filterInputObj;
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
private filterWireEvents(filterElem?: Element): void {
|
|
1468
|
+
if (filterElem) {
|
|
1469
|
+
this.filterInput = filterElem.querySelector('.e-input-filter');
|
|
1470
|
+
}
|
|
1471
|
+
this.clearFilterIconElem = this.filterInput.parentElement.querySelector('.' + listBoxClasses.clearIcon);
|
|
1472
|
+
if (this.clearFilterIconElem) {
|
|
1473
|
+
EventHandler.add(this.clearFilterIconElem, 'click', this.clearText, this);
|
|
1474
|
+
if (!filterElem) {
|
|
1475
|
+
(this.clearFilterIconElem as HTMLElement).style.visibility = 'hidden';
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
EventHandler.add(this.filterInput, 'input', this.onInput, this);
|
|
1479
|
+
EventHandler.add(this.filterInput, 'keyup', this.KeyUp, this);
|
|
1480
|
+
EventHandler.add(this.filterInput, 'keydown', this.onKeyDown, this);
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
private selectHandler(e: MouseEvent | { target: EventTarget, ctrlKey?: boolean, shiftKey?: boolean,
|
|
1484
|
+
metaKey?: boolean}, isKey?: boolean): void {
|
|
1485
|
+
let isSelect: boolean = true;
|
|
1486
|
+
let currSelIdx: number;
|
|
1487
|
+
const li: Element = closest(e.target as Element, '.' + 'e-list-item');
|
|
1488
|
+
let selectedLi: Element[] = [li];
|
|
1489
|
+
if (li && li.parentElement) {
|
|
1490
|
+
currSelIdx = [].slice.call(li.parentElement.children).indexOf(li);
|
|
1491
|
+
if (!this.selectionSettings.showCheckbox) {
|
|
1492
|
+
if ((e.ctrlKey || e.metaKey || Browser.isDevice) && this.isSelected(li)) {
|
|
1493
|
+
li.classList.remove(cssClass.selected);
|
|
1494
|
+
li.removeAttribute('aria-selected');
|
|
1495
|
+
isSelect = false;
|
|
1496
|
+
} else if (!(this.selectionSettings.mode === 'Multiple' && (e.ctrlKey || e.metaKey || Browser.isDevice))) {
|
|
1497
|
+
this.getSelectedItems().forEach((ele: Element) => {
|
|
1498
|
+
ele.removeAttribute('aria-selected');
|
|
1499
|
+
});
|
|
1500
|
+
removeClass(this.getSelectedItems(), cssClass.selected);
|
|
1501
|
+
}
|
|
1502
|
+
} else {
|
|
1503
|
+
isSelect = !li.getElementsByClassName('e-frame')[0].classList.contains('e-check');
|
|
1504
|
+
}
|
|
1505
|
+
if (e.shiftKey && !this.selectionSettings.showCheckbox && this.selectionSettings.mode !== 'Single') {
|
|
1506
|
+
selectedLi = [].slice.call(li.parentElement.children)
|
|
1507
|
+
.slice(Math.min(currSelIdx, this.prevSelIdx), Math.max(currSelIdx, this.prevSelIdx) + 1)
|
|
1508
|
+
.filter((ele: Element) => { return ele.classList.contains('e-list-item'); });
|
|
1509
|
+
} else {
|
|
1510
|
+
this.prevSelIdx = [].slice.call(li.parentElement.children).indexOf(li);
|
|
1511
|
+
}
|
|
1512
|
+
if (isSelect) {
|
|
1513
|
+
if (!this.selectionSettings.showCheckbox) {
|
|
1514
|
+
addClass(selectedLi, cssClass.selected);
|
|
1515
|
+
}
|
|
1516
|
+
selectedLi.forEach((ele: Element) => {
|
|
1517
|
+
ele.setAttribute('aria-selected', 'true');
|
|
1518
|
+
});
|
|
1519
|
+
this.list.setAttribute('aria-activedescendant', li.id);
|
|
1520
|
+
} else {
|
|
1521
|
+
selectedLi.forEach((ele: Element) => {
|
|
1522
|
+
ele.setAttribute('aria-selected', 'false');
|
|
1523
|
+
});
|
|
1524
|
+
}
|
|
1525
|
+
if (!isKey && (this.maximumSelectionLength > (this.value && this.value.length) || !isSelect) &&
|
|
1526
|
+
(this.maximumSelectionLength >= (this.value && this.value.length) || !isSelect) &&
|
|
1527
|
+
!(this.maximumSelectionLength < (this.value && this.value.length))) {
|
|
1528
|
+
this.notify('updatelist', { li: li, e: e, module: 'listbox' });
|
|
1529
|
+
}
|
|
1530
|
+
if (this.allowFiltering && !isKey) {
|
|
1531
|
+
const liDataValue: string = this.getFormattedValue(li.getAttribute('data-value')) as string;
|
|
1532
|
+
if (!isSelect) {
|
|
1533
|
+
this.value = (this.value as string[]).filter((value1: string) =>
|
|
1534
|
+
value1 !== liDataValue);
|
|
1535
|
+
} else {
|
|
1536
|
+
const values: string[] = [];
|
|
1537
|
+
extend(values, this.value); values.push(liDataValue);
|
|
1538
|
+
this.value = values;
|
|
1539
|
+
}
|
|
1540
|
+
if (document.querySelectorAll('ul').length < 2) {
|
|
1541
|
+
this.updateMainList();
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
this.updateSelectedOptions();
|
|
1545
|
+
this.triggerChange(this.getSelectedItems(), e as MouseEvent);
|
|
1546
|
+
if (this.list) {
|
|
1547
|
+
this.checkMaxSelection();
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1552
|
+
private triggerChange(selectedLis: Element[], event: MouseEvent): void {
|
|
1553
|
+
this.trigger('change', { elements: selectedLis, items: this.getDataByElements(selectedLis), value: this.value, event: event });
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
private getDataByElems(elems: Element[]): Object[] {
|
|
1557
|
+
const data: Object[] = [];
|
|
1558
|
+
for (let i: number = 0, len: number = elems.length; i < len; i++) {
|
|
1559
|
+
data.push(this.getDataByValue(this.getFormattedValue(elems[i as number].getAttribute('data-value'))));
|
|
1560
|
+
}
|
|
1561
|
+
return data;
|
|
1562
|
+
}
|
|
1563
|
+
private getDataByElements(elems: Element[]): Object[] {
|
|
1564
|
+
|
|
1565
|
+
const data: Object[] = []; let value: string | number | boolean; let sIdx: number = 0;
|
|
1566
|
+
if (!isNullOrUndefined(this.listData)) {
|
|
1567
|
+
const type: string = this.typeOfData(this.listData).typeof as string;
|
|
1568
|
+
if (type === 'string' || type === 'number' || type === 'boolean') {
|
|
1569
|
+
for (const item of this.listData) {
|
|
1570
|
+
for (let i: number = sIdx, len: number = elems.length; i < len; i++) {
|
|
1571
|
+
value = this.getFormattedValue((elems[i as number] as Element).getAttribute('data-value'));
|
|
1572
|
+
if (!isNullOrUndefined(item) && item === value as Object) {
|
|
1573
|
+
sIdx = i; data.push(item); break;
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
if (elems.length === data.length) {
|
|
1577
|
+
break;
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
} else {
|
|
1581
|
+
for (const item of this.listData) {
|
|
1582
|
+
for (let i: number = sIdx, len: number = elems.length; i < len; i++) {
|
|
1583
|
+
value = this.getFormattedValue((elems[i as number] as Element).getAttribute('data-value'));
|
|
1584
|
+
if (!isNullOrUndefined(item) && getValue((this.fields.value ? this.fields.value : 'value'), item) === value) {
|
|
1585
|
+
sIdx = i; data.push(item); break;
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
if (elems.length === data.length) {
|
|
1589
|
+
break;
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
return data;
|
|
1594
|
+
}
|
|
1595
|
+
return null;
|
|
1596
|
+
}
|
|
1597
|
+
private checkMaxSelection(): InputObject | void {
|
|
1598
|
+
const limit: number = this.list.querySelectorAll('.e-list-item span.e-check').length;
|
|
1599
|
+
if (this.selectionSettings.showCheckbox) {
|
|
1600
|
+
let index: number = 0;
|
|
1601
|
+
const liCollElem: HTMLCollectionOf<HTMLLIElement> = this.list.getElementsByClassName('e-list-item') as HTMLCollectionOf<HTMLLIElement>;
|
|
1602
|
+
for (index; index < liCollElem.length; index++) {
|
|
1603
|
+
if (!liCollElem[index as number].querySelector('.e-frame.e-check')) {
|
|
1604
|
+
if (limit === this.maximumSelectionLength) {
|
|
1605
|
+
liCollElem[index as number].classList.add('e-disable');
|
|
1606
|
+
} else if (liCollElem[index as number].classList.contains('e-disable')) {
|
|
1607
|
+
liCollElem[index as number].classList.remove('e-disable');
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
private toolbarClickHandler(e: MouseEvent): void {
|
|
1615
|
+
const btn: Element = closest(e.target as Element, 'button');
|
|
1616
|
+
if (btn) {
|
|
1617
|
+
this.toolbarAction = btn.getAttribute('data-value');
|
|
1618
|
+
if ((btn as HTMLButtonElement).disabled) {
|
|
1619
|
+
return;
|
|
1620
|
+
}
|
|
1621
|
+
switch (this.toolbarAction) {
|
|
1622
|
+
case 'moveUp':
|
|
1623
|
+
this.moveUpDown(true);
|
|
1624
|
+
break;
|
|
1625
|
+
case 'moveDown':
|
|
1626
|
+
this.moveUpDown();
|
|
1627
|
+
break;
|
|
1628
|
+
case 'moveTo':
|
|
1629
|
+
this.moveItemTo();
|
|
1630
|
+
break;
|
|
1631
|
+
case 'moveFrom':
|
|
1632
|
+
this.moveItemFrom();
|
|
1633
|
+
break;
|
|
1634
|
+
case 'moveAllTo':
|
|
1635
|
+
this.moveAllItemTo();
|
|
1636
|
+
break;
|
|
1637
|
+
case 'moveAllFrom':
|
|
1638
|
+
this.moveAllItemFrom();
|
|
1639
|
+
break;
|
|
1640
|
+
default:
|
|
1641
|
+
this.trigger('actionBegin', { cancel: false, items: this.getDataByElems(this.getSelectedItems()),
|
|
1642
|
+
eventName: this.toolbarAction });
|
|
1643
|
+
break;
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
private moveUpDown(isUp?: boolean, isKey?: boolean, value?: Element[], isTop?: boolean, isBottom?: boolean): void {
|
|
1649
|
+
let elems: Element[] = this.getSelectedItems();
|
|
1650
|
+
if (value) {
|
|
1651
|
+
elems = value;
|
|
1652
|
+
}
|
|
1653
|
+
if (((isUp && this.isSelected(this.ulElement.firstElementChild))
|
|
1654
|
+
|| (!isUp && this.isSelected(this.ulElement.lastElementChild))) && !value ) {
|
|
1655
|
+
return;
|
|
1656
|
+
}
|
|
1657
|
+
const tempItems: Object[] = this.getDataByElems(elems);
|
|
1658
|
+
const localDataArgs: { [key: string]: Object } = { cancel: false, items: tempItems, eventName: this.toolbarAction };
|
|
1659
|
+
this.trigger('actionBegin', localDataArgs);
|
|
1660
|
+
if (localDataArgs.cancel) {
|
|
1661
|
+
return;
|
|
1662
|
+
}
|
|
1663
|
+
(isUp ? elems : elems.reverse()).forEach((ele: Element) => {
|
|
1664
|
+
const jsonToIdx: number = Array.prototype.indexOf.call(this.ulElement.querySelectorAll('.e-list-item'), ele);
|
|
1665
|
+
const idx: number = Array.prototype.indexOf.call(this.ulElement.children, ele);
|
|
1666
|
+
if (isTop) {
|
|
1667
|
+
moveTo(this.ulElement, this.ulElement, [idx], 0);
|
|
1668
|
+
this.changeData(idx, 0 , jsonToIdx, ele);
|
|
1669
|
+
}
|
|
1670
|
+
else if(isBottom) {
|
|
1671
|
+
moveTo(this.ulElement, this.ulElement, [idx], this.ulElement.querySelectorAll('.e-list-item').length);
|
|
1672
|
+
this.changeData(idx, this.ulElement.querySelectorAll('.e-list-item').length, jsonToIdx, ele);
|
|
1673
|
+
}
|
|
1674
|
+
else {
|
|
1675
|
+
moveTo(this.ulElement, this.ulElement, [idx], isUp ? idx - 1 : idx + 2);
|
|
1676
|
+
this.changeData(idx, isUp ? idx - 1 : idx + 1, isUp ? jsonToIdx - 1 : jsonToIdx + 1, ele);
|
|
1677
|
+
}
|
|
1678
|
+
});
|
|
1679
|
+
this.trigger('actionComplete', { items: tempItems, eventName: this.toolbarAction });
|
|
1680
|
+
(elems[0] as HTMLElement).focus();
|
|
1681
|
+
if (!isKey && this.toolbarSettings.items.length) {
|
|
1682
|
+
(this.getToolElem().querySelector('[data-value=' + (isUp ? 'moveUp' : 'moveDown') + ']') as HTMLElement).focus();
|
|
1683
|
+
}
|
|
1684
|
+
this.updateToolBarState();
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
private moveItemTo(): void {
|
|
1688
|
+
this.moveData(this, this.getScopedListBox());
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
private moveItemFrom(): void {
|
|
1692
|
+
this.moveData(this.getScopedListBox(), this);
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
/**
|
|
1696
|
+
* Called internally if any of the property value changed.
|
|
1697
|
+
*
|
|
1698
|
+
* @param {ListBox} fListBox - Specifies the from listbox.
|
|
1699
|
+
* @param {ListBox} tListBox - Specifies the to listbox.
|
|
1700
|
+
* @param {boolean} isKey - Specifies the key.
|
|
1701
|
+
* @param {Element[]} value - Specifies the value.
|
|
1702
|
+
* @param {number} index - Specifies the index.
|
|
1703
|
+
* @returns {void}
|
|
1704
|
+
* @private
|
|
1705
|
+
*/
|
|
1706
|
+
private moveData(fListBox: ListBox, tListBox: ListBox, isKey?: boolean, value?: Element[], index?: number): void {
|
|
1707
|
+
const idx: number[] = []; const dataIdx: number[] = []; const jsonIdx: number[] = []; const sortIdx: number[] = [];
|
|
1708
|
+
const listData: dataType[] = [].slice.call(fListBox.listData); const tListData: dataType[] = [].slice.call(tListBox.listData);
|
|
1709
|
+
const sortData: dataType[] = [].slice.call(fListBox.sortedData); let tSortData: dataType[] = [].slice.call(tListBox.sortedData);
|
|
1710
|
+
const fliCollections: HTMLElement[] = [].slice.call(fListBox.liCollections); const dataLiIdx: number[] = [];
|
|
1711
|
+
const tliCollections: HTMLElement[] = [].slice.call(tListBox.liCollections);
|
|
1712
|
+
const tempItems: dataType[] = [];
|
|
1713
|
+
const data: dataType[] = []; let elems: Element[] = fListBox.getSelectedItems();
|
|
1714
|
+
if (value) {
|
|
1715
|
+
elems = value;
|
|
1716
|
+
}
|
|
1717
|
+
const isRefresh: boolean | string | Function = tListBox.sortOrder !== 'None' || (tListBox.selectionSettings.showCheckbox !==
|
|
1718
|
+
fListBox.selectionSettings.showCheckbox) || tListBox.fields.groupBy || tListBox.itemTemplate || fListBox.itemTemplate;
|
|
1719
|
+
fListBox.value = [];
|
|
1720
|
+
if (elems.length) {
|
|
1721
|
+
this.removeSelected(fListBox, elems);
|
|
1722
|
+
elems.forEach((ele: Element) => {
|
|
1723
|
+
idx.push(Array.prototype.indexOf.call(fListBox.ulElement.children, ele)); // update sortable elem
|
|
1724
|
+
// To update lb view data
|
|
1725
|
+
dataLiIdx.push(Array.prototype.indexOf.call(fListBox.ulElement.querySelectorAll('.e-list-item'), ele));
|
|
1726
|
+
// To update lb listdata data
|
|
1727
|
+
dataIdx.push(Array.prototype.indexOf.call(fListBox.listData, fListBox.getDataByElems([ele])[0]));
|
|
1728
|
+
// To update lb sorted data
|
|
1729
|
+
sortIdx.push(Array.prototype.indexOf.call(fListBox.sortedData, fListBox.getDataByElems([ele])[0]));
|
|
1730
|
+
// To update lb original data
|
|
1731
|
+
jsonIdx.push(Array.prototype.indexOf.call(fListBox.jsonData, fListBox.getDataByElems([ele])[0]));
|
|
1732
|
+
});
|
|
1733
|
+
if (this.sortOrder !== 'None') {
|
|
1734
|
+
sortIdx.forEach((i: number) => {
|
|
1735
|
+
tempItems.push(fListBox.sortedData[i as number]);
|
|
1736
|
+
});
|
|
1737
|
+
} else {
|
|
1738
|
+
jsonIdx.forEach((i: number) => {
|
|
1739
|
+
tempItems.push(fListBox.jsonData[i as number]);
|
|
1740
|
+
});
|
|
1741
|
+
}
|
|
1742
|
+
const localDataArgs: { [key: string]: Object } = { cancel: false, items: tempItems, eventName: this.toolbarAction };
|
|
1743
|
+
fListBox.trigger('actionBegin', localDataArgs);
|
|
1744
|
+
if (localDataArgs.cancel) {
|
|
1745
|
+
return;
|
|
1746
|
+
}
|
|
1747
|
+
const rLiCollection: HTMLElement[] = [];
|
|
1748
|
+
dataLiIdx.sort((n1: number, n2: number) => n1 - n2).reverse().forEach((i: number) => {
|
|
1749
|
+
rLiCollection.push(fliCollections.splice(i, 1)[0]);
|
|
1750
|
+
});
|
|
1751
|
+
fListBox.liCollections = fliCollections;
|
|
1752
|
+
if (index) {
|
|
1753
|
+
const toColl: HTMLElement[] = tliCollections.splice(0, index);
|
|
1754
|
+
tListBox.liCollections = toColl.concat(rLiCollection.reverse()).concat(tliCollections);
|
|
1755
|
+
} else {
|
|
1756
|
+
tListBox.liCollections = tliCollections.concat(rLiCollection.reverse());
|
|
1757
|
+
}
|
|
1758
|
+
if (tListBox.listData.length === 0) {
|
|
1759
|
+
const noRecElem: Element = tListBox.ulElement.childNodes[0] as Element;
|
|
1760
|
+
if (noRecElem) {
|
|
1761
|
+
tListBox.ulElement.removeChild(noRecElem);
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
dataIdx.sort((n1: number, n2: number) => n2 - n1).forEach((i: number) => {
|
|
1765
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
1766
|
+
listData.splice(i, 1)[0];
|
|
1767
|
+
});
|
|
1768
|
+
sortIdx.sort((n1: number, n2: number) => n2 - n1).forEach((i: number) => {
|
|
1769
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
1770
|
+
sortData.splice(i, 1)[0];
|
|
1771
|
+
});
|
|
1772
|
+
jsonIdx.slice().reverse().forEach((i: number) => {
|
|
1773
|
+
data.push(fListBox.jsonData.splice(i, 1)[0]);
|
|
1774
|
+
});
|
|
1775
|
+
if (isRefresh) {
|
|
1776
|
+
if (fListBox.fields.groupBy) {
|
|
1777
|
+
const sourceElem: HTMLElement = fListBox.renderItems(listData as obj[], fListBox.fields);
|
|
1778
|
+
fListBox.updateListItems(sourceElem, fListBox.ulElement);
|
|
1779
|
+
} else {
|
|
1780
|
+
elems.forEach((ele: Element) => { detach(ele); });
|
|
1781
|
+
}
|
|
1782
|
+
} else {
|
|
1783
|
+
moveTo(fListBox.ulElement, tListBox.ulElement, idx, index);
|
|
1784
|
+
fListBox.trigger('actionComplete', { items: tempItems, eventName: this.toolbarAction });
|
|
1785
|
+
}
|
|
1786
|
+
if (tListBox.mainList.childElementCount !== tListBox.jsonData.length) {
|
|
1787
|
+
tListBox.mainList = tListBox.ulElement;
|
|
1788
|
+
}
|
|
1789
|
+
fListBox.updateMainList();
|
|
1790
|
+
const tJsonData: dataType[] = [].slice.call(tListBox.jsonData);
|
|
1791
|
+
tSortData = [].slice.call(tListBox.sortedData);
|
|
1792
|
+
this.selectNextList(elems, dataLiIdx, dataIdx, fListBox);
|
|
1793
|
+
if (isKey) { this.list.focus(); }
|
|
1794
|
+
(fListBox.listData as dataType[]) = listData;
|
|
1795
|
+
(fListBox.sortedData as dataType[]) = sortData;
|
|
1796
|
+
index = (index) ? index : tListData.length;
|
|
1797
|
+
for (let i: number = tempItems.length - 1; i >= 0; i--) {
|
|
1798
|
+
tListData.splice(index, 0, tempItems[i as number]);
|
|
1799
|
+
tJsonData.splice(index, 0, tempItems[i as number]);
|
|
1800
|
+
tSortData.splice(index, 0, tempItems[i as number]);
|
|
1801
|
+
}
|
|
1802
|
+
(tListBox.listData as dataType[]) = tListData;
|
|
1803
|
+
tListBox.jsonData = tJsonData as {[key: string]: object}[];
|
|
1804
|
+
tListBox.sortedData = tSortData as {[key: string]: object}[];
|
|
1805
|
+
if (isRefresh) {
|
|
1806
|
+
const sourceElem: HTMLElement = tListBox.renderItems(tListData as obj[], tListBox.fields);
|
|
1807
|
+
tListBox.updateListItems(sourceElem, tListBox.ulElement);
|
|
1808
|
+
tListBox.setSelection();
|
|
1809
|
+
fListBox.trigger('actionComplete', { items: tempItems, eventName: this.toolbarAction });
|
|
1810
|
+
}
|
|
1811
|
+
fListBox.updateSelectedOptions();
|
|
1812
|
+
if (fListBox.listData.length === 0) {
|
|
1813
|
+
fListBox.l10nUpdate();
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
if (fListBox.value.length === 1 && fListBox.getSelectedItems().length) {
|
|
1817
|
+
fListBox.value[0] = fListBox.getFormattedValue(fListBox.getSelectedItems()[0].getAttribute('data-value'));
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
|
|
1821
|
+
private selectNextList(elems: Element[], dataLiIdx: number[], dataIdx: number[], inst: ListBox): void {
|
|
1822
|
+
const childCnt: number = inst.ulElement.querySelectorAll('.e-list-item').length;
|
|
1823
|
+
let ele: Element; let liIdx: number;
|
|
1824
|
+
let validIdx: number = -1;
|
|
1825
|
+
if (elems.length === 1 && childCnt && !inst.selectionSettings.showCheckbox) {
|
|
1826
|
+
liIdx = childCnt <= dataLiIdx[0] ? childCnt - 1 : dataLiIdx[0];
|
|
1827
|
+
ele = inst.ulElement.querySelectorAll('.e-list-item')[liIdx as number];
|
|
1828
|
+
validIdx = inst.getValidIndex(ele, liIdx, childCnt === dataIdx[0] ? 38 : 40);
|
|
1829
|
+
if (validIdx > -1) {
|
|
1830
|
+
(inst.ulElement.querySelectorAll('.e-list-item')[validIdx as number].classList.add(cssClass.selected));
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
private moveAllItemTo(): void {
|
|
1836
|
+
this.moveAllData(this, this.getScopedListBox());
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
private moveAllItemFrom(): void {
|
|
1840
|
+
this.moveAllData(this.getScopedListBox(), this);
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1843
|
+
private moveAllData(fListBox: ListBox, tListBox: ListBox, isKey?: boolean, index?: number): void {
|
|
1844
|
+
type sortedType = dataType | { isHeader: boolean };
|
|
1845
|
+
let listData: dataType[] = [].slice.call(tListBox.listData);
|
|
1846
|
+
const jsonData: {[key: string]: object}[] = [].slice.call(tListBox.jsonData);
|
|
1847
|
+
const isRefresh: boolean | string | Function = tListBox.sortOrder !== 'None' || (tListBox.selectionSettings.showCheckbox !==
|
|
1848
|
+
fListBox.selectionSettings.showCheckbox) || tListBox.fields.groupBy || tListBox.itemTemplate || fListBox.itemTemplate;
|
|
1849
|
+
this.removeSelected(fListBox, fListBox.getSelectedItems());
|
|
1850
|
+
const tempItems: Object[] = [].slice.call(fListBox.listData);
|
|
1851
|
+
const localDataArgs: { [key: string]: Object } = { cancel: false, items: tempItems, eventName: this.toolbarAction };
|
|
1852
|
+
fListBox.trigger('actionBegin', localDataArgs);
|
|
1853
|
+
if (localDataArgs.cancel) {
|
|
1854
|
+
return;
|
|
1855
|
+
}
|
|
1856
|
+
if (tListBox.listData.length === 0) {
|
|
1857
|
+
const noRecElem: Element = tListBox.ulElement.childNodes[0] as Element;
|
|
1858
|
+
if (noRecElem) {
|
|
1859
|
+
tListBox.ulElement.removeChild(noRecElem);
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
if (isRefresh) {
|
|
1863
|
+
const noRecElem: Element = fListBox.ulElement.childNodes[0] as Element;
|
|
1864
|
+
if (noRecElem) {
|
|
1865
|
+
fListBox.ulElement.removeChild(noRecElem);
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
moveTo(
|
|
1869
|
+
fListBox.ulElement, tListBox.ulElement,
|
|
1870
|
+
// eslint-disable-next-line prefer-spread
|
|
1871
|
+
Array.apply(null, { length: fListBox.ulElement.childElementCount }).map(Number.call, Number), index);
|
|
1872
|
+
this.trigger('actionComplete', { items: tempItems, eventName: this.toolbarAction });
|
|
1873
|
+
if (isKey) { this.list.focus(); }
|
|
1874
|
+
index = (index) ? index : listData.length;
|
|
1875
|
+
for (let i: number = 0; i < fListBox.listData.length; i++) {
|
|
1876
|
+
listData.splice(index + i, 0, fListBox.listData[i as number]);
|
|
1877
|
+
}
|
|
1878
|
+
for (let i: number = 0; i < fListBox.jsonData.length; i++) {
|
|
1879
|
+
jsonData.splice(index + i, 0, fListBox.jsonData[i as number] as {[key: string]: object});
|
|
1880
|
+
}
|
|
1881
|
+
const fliCollections: HTMLElement[] = [].slice.call(fListBox.liCollections);
|
|
1882
|
+
const tliCollections: HTMLElement[] = [].slice.call(tListBox.liCollections);
|
|
1883
|
+
fListBox.liCollections = [];
|
|
1884
|
+
if (index) {
|
|
1885
|
+
const toColl: HTMLElement[] = tliCollections.splice(0, index);
|
|
1886
|
+
tListBox.liCollections = toColl.concat(fliCollections).concat(tliCollections);
|
|
1887
|
+
} else {
|
|
1888
|
+
tListBox.liCollections = tliCollections.concat(fliCollections);
|
|
1889
|
+
}
|
|
1890
|
+
fListBox.value = [];
|
|
1891
|
+
(listData as sortedType[]) = (listData as sortedType[])
|
|
1892
|
+
.filter((data: sortedType) => (data as { isHeader: boolean }).isHeader !== true);
|
|
1893
|
+
const sortedData: dataType[] = listData.filter(function(val: dataType): dataType {
|
|
1894
|
+
return (tListBox.jsonData as dataType[]).indexOf(val) === -1;
|
|
1895
|
+
});
|
|
1896
|
+
for (let i: number = 0; i < sortedData.length; i++) {
|
|
1897
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1898
|
+
tListBox.jsonData.splice(index + i, 0, sortedData[i as number] as any);
|
|
1899
|
+
}
|
|
1900
|
+
(tListBox.listData as dataType[]) = listData;
|
|
1901
|
+
if (fListBox.listData.length === fListBox.jsonData.length) {
|
|
1902
|
+
fListBox.listData = fListBox.sortedData = fListBox.jsonData = [];
|
|
1903
|
+
} else if (fListBox.allowFiltering) {
|
|
1904
|
+
for (let i: number = 0; i < fListBox.listData.length; i++) {
|
|
1905
|
+
for (let j: number = 0; j < fListBox.jsonData.length; j++) {
|
|
1906
|
+
if (fListBox.listData[i as number] === fListBox.jsonData[j as number]) {
|
|
1907
|
+
fListBox.jsonData.splice(j, 1);
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
fListBox.listData = fListBox.sortedData = [];
|
|
1912
|
+
}
|
|
1913
|
+
if (isRefresh) {
|
|
1914
|
+
const sourceElem: HTMLElement = tListBox.renderItems(listData as obj[], tListBox.fields);
|
|
1915
|
+
tListBox.updateListItems(sourceElem, tListBox.ulElement);
|
|
1916
|
+
this.trigger('actionComplete', { items: tempItems, eventName: this.toolbarAction });
|
|
1917
|
+
} else {
|
|
1918
|
+
(tListBox.sortedData as dataType[]) = listData;
|
|
1919
|
+
}
|
|
1920
|
+
fListBox.updateSelectedOptions();
|
|
1921
|
+
if (fListBox.listData.length === 0) {
|
|
1922
|
+
fListBox.l10nUpdate();
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
private changeData(fromIdx: number, toIdx: number, jsonToIdx: number, ele: Element): void {
|
|
1927
|
+
const listData: obj[] = [].slice.call(this.listData);
|
|
1928
|
+
const jsonData: obj[] = [].slice.call(this.jsonData);
|
|
1929
|
+
const sortData: obj[] = [].slice.call(this.sortedData);
|
|
1930
|
+
const jsonIdx: number = Array.prototype.indexOf.call(this.jsonData, this.getDataByElems([ele])[0]);
|
|
1931
|
+
const sortIdx: number = Array.prototype.indexOf.call(this.sortedData, this.getDataByElems([ele])[0]);
|
|
1932
|
+
const liColl: HTMLElement[] = [].slice.call(this.liCollections);
|
|
1933
|
+
listData.splice(toIdx, 0, listData.splice(fromIdx, 1)[0] as obj);
|
|
1934
|
+
jsonData.splice(jsonToIdx, 0, jsonData.splice(jsonIdx, 1)[0] as obj);
|
|
1935
|
+
sortData.splice(toIdx, 0, sortData.splice(sortIdx, 1)[0] as obj);
|
|
1936
|
+
liColl.splice(toIdx, 0, liColl.splice(fromIdx, 1)[0] as HTMLElement);
|
|
1937
|
+
this.listData = listData;
|
|
1938
|
+
this.jsonData = jsonData;
|
|
1939
|
+
this.liCollections = liColl;
|
|
1940
|
+
this.sortedData = sortData;
|
|
1941
|
+
}
|
|
1942
|
+
|
|
1943
|
+
private getSelectedItems(): Element[] {
|
|
1944
|
+
let ele: Element[] = [];
|
|
1945
|
+
if (this.selectionSettings.showCheckbox) {
|
|
1946
|
+
[].slice.call(this.ulElement.getElementsByClassName('e-check')).forEach((cbox: Element) => {
|
|
1947
|
+
ele.push(closest(cbox, '.' + 'e-list-item'));
|
|
1948
|
+
});
|
|
1949
|
+
} else {
|
|
1950
|
+
ele = [].slice.call(this.ulElement.getElementsByClassName(cssClass.selected));
|
|
1951
|
+
}
|
|
1952
|
+
return ele;
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
private getScopedListBox(): ListBox {
|
|
1956
|
+
let listObj: ListBox;
|
|
1957
|
+
if (this.scope) {
|
|
1958
|
+
[].slice.call(document.querySelectorAll(this.scope)).forEach((ele: Element) => {
|
|
1959
|
+
if (getComponent(ele as HTMLElement, this.getModuleName())) {
|
|
1960
|
+
listObj = getComponent(ele as HTMLElement, this.getModuleName());
|
|
1961
|
+
}
|
|
1962
|
+
});
|
|
1963
|
+
}
|
|
1964
|
+
return listObj;
|
|
1965
|
+
}
|
|
1966
|
+
|
|
1967
|
+
private getGrabbedItems(args: DragEventArgs): Element[] {
|
|
1968
|
+
let grabbItems : boolean = false;
|
|
1969
|
+
for (let i: number = 0; i < this.value.length; i++) {
|
|
1970
|
+
if (this.value[i as number] === this.getFormattedValue(args.target.getAttribute('data-value')) as string) {
|
|
1971
|
+
grabbItems = true;
|
|
1972
|
+
break;
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
if (grabbItems) {
|
|
1976
|
+
for (let i: number = 0; i < this.value.length; i++) {
|
|
1977
|
+
const liColl: NodeListOf<Element> = this.list.querySelectorAll('[aria-selected="true"]');
|
|
1978
|
+
for (let j: number = 0; j < liColl.length; j++) {
|
|
1979
|
+
if (this.value[i as number] === this.getFormattedValue(liColl[j as number].getAttribute('data-value')) as string) {
|
|
1980
|
+
liColl[j as number].classList.add('e-grabbed');
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
let elems: Element[];
|
|
1986
|
+
if (this.isAngular) {
|
|
1987
|
+
elems = Array.prototype.slice.call(this.element.getElementsByClassName('e-list-parent')[0].querySelectorAll('.e-grabbed'));
|
|
1988
|
+
} else {
|
|
1989
|
+
elems = Array.prototype.slice.call(this.element.nextElementSibling.querySelectorAll('.e-grabbed'));
|
|
1990
|
+
}
|
|
1991
|
+
return elems;
|
|
1992
|
+
}
|
|
1993
|
+
|
|
1994
|
+
private getDragArgs(args: DragEventArgs , isDragEnd?: boolean): DragEventArgs {
|
|
1995
|
+
let elems: Element[] = this.getGrabbedItems(args);
|
|
1996
|
+
if (elems.length) {
|
|
1997
|
+
if (isDragEnd) {
|
|
1998
|
+
elems.push(args.target);
|
|
1999
|
+
}
|
|
2000
|
+
} else {
|
|
2001
|
+
elems = [args.target];
|
|
2002
|
+
}
|
|
2003
|
+
return { elements: elems, items: this.getDataByElems(elems) } as DragEventArgs;
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
private onKeyDown(e: KeyboardEvent): void {
|
|
2007
|
+
this.keyDownHandler(e);
|
|
2008
|
+
e.stopPropagation();
|
|
2009
|
+
}
|
|
2010
|
+
|
|
2011
|
+
private keyDownStatus: boolean = false;
|
|
2012
|
+
|
|
2013
|
+
private keyDownHandler(e: KeyboardEvent): void {
|
|
2014
|
+
if ([32, 35, 36, 37, 38, 39, 40, 65].indexOf(e.keyCode) > -1 && !this.allowFiltering) {
|
|
2015
|
+
if (e.target && (e.target as Element).className.indexOf('e-edit-template') > -1) {
|
|
2016
|
+
return;
|
|
2017
|
+
}
|
|
2018
|
+
e.preventDefault();
|
|
2019
|
+
if (e.keyCode === 32 && this.ulElement.children.length) {
|
|
2020
|
+
this.selectHandler({
|
|
2021
|
+
target: this.ulElement.getElementsByClassName('e-focused')[0],
|
|
2022
|
+
ctrlKey: e.ctrlKey, shiftKey: e.shiftKey
|
|
2023
|
+
});
|
|
2024
|
+
} else if (e.keyCode === 65 && e.ctrlKey) {
|
|
2025
|
+
this.selectAll();
|
|
2026
|
+
} else if ((e.keyCode === 38 || e.keyCode === 40) && e.ctrlKey && e.shiftKey) {
|
|
2027
|
+
this.moveUpDown(e.keyCode === 38 ? true : false, true);
|
|
2028
|
+
} else if ((this.toolbarSettings.items.length || this.tBListBox) && (e.keyCode === 39 || e.keyCode === 37) && e.ctrlKey) {
|
|
2029
|
+
const listObj: ListBox = this.tBListBox || this.getScopedListBox();
|
|
2030
|
+
if (e.keyCode === 39) {
|
|
2031
|
+
if (e.shiftKey) {
|
|
2032
|
+
this.moveAllData(this, listObj, true);
|
|
2033
|
+
} else {
|
|
2034
|
+
this.moveData(this, listObj, true);
|
|
2035
|
+
}
|
|
2036
|
+
} else {
|
|
2037
|
+
if (e.shiftKey) {
|
|
2038
|
+
this.moveAllData(listObj, this, true);
|
|
2039
|
+
} else {
|
|
2040
|
+
this.moveData(listObj, this, true);
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
} else if (e.keyCode !== 37 && e.keyCode !== 39 && e.code !== 'KeyA') {
|
|
2044
|
+
this.upDownKeyHandler(e);
|
|
2045
|
+
}
|
|
2046
|
+
} else if (this.allowFiltering) {
|
|
2047
|
+
if (e.keyCode === 40 || e.keyCode === 38) {
|
|
2048
|
+
this.upDownKeyHandler(e);
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
|
|
2053
|
+
private upDownKeyHandler(e: KeyboardEvent): void {
|
|
2054
|
+
const ul: Element = this.ulElement;
|
|
2055
|
+
const defaultIdx: number = (e.keyCode === 40 || e.keyCode === 36) ? 0 : ul.childElementCount - 1;
|
|
2056
|
+
let fliIdx: number = defaultIdx;
|
|
2057
|
+
const fli: Element = ul.getElementsByClassName('e-focused')[0] || ul.getElementsByClassName(cssClass.selected)[0];
|
|
2058
|
+
if (fli) {
|
|
2059
|
+
if (e.keyCode !== 35 && e.keyCode !== 36) {
|
|
2060
|
+
fliIdx = Array.prototype.indexOf.call(ul.children, fli);
|
|
2061
|
+
if (e.keyCode === 40) {
|
|
2062
|
+
fliIdx++;
|
|
2063
|
+
} else {
|
|
2064
|
+
fliIdx--;
|
|
2065
|
+
}
|
|
2066
|
+
if (fliIdx < 0 || fliIdx > ul.childElementCount - 1) {
|
|
2067
|
+
return;
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2070
|
+
removeClass([fli], 'e-focused');
|
|
2071
|
+
}
|
|
2072
|
+
const cli: Element = ul.children[fliIdx as number];
|
|
2073
|
+
if (cli) {
|
|
2074
|
+
fliIdx = this.getValidIndex(cli, fliIdx, e.keyCode);
|
|
2075
|
+
if (fliIdx === -1) {
|
|
2076
|
+
addClass([fli], 'e-focused');
|
|
2077
|
+
return;
|
|
2078
|
+
}
|
|
2079
|
+
(ul.children[fliIdx as number] as HTMLElement).focus();
|
|
2080
|
+
ul.children[fliIdx as number].classList.add('e-focused');
|
|
2081
|
+
if (!e.ctrlKey || !this.selectionSettings.showCheckbox && e.shiftKey && (e.keyCode === 36 || e.keyCode === 35)) {
|
|
2082
|
+
this.selectHandler({ target: ul.children[fliIdx as number], ctrlKey: e.ctrlKey, shiftKey: e.shiftKey }, true);
|
|
2083
|
+
}
|
|
2084
|
+
if (this.selectionSettings.showCheckbox && e.ctrlKey && e.shiftKey && (e.keyCode === 36 || e.keyCode === 35)) {
|
|
2085
|
+
const selectedidx : number = Array.prototype.indexOf.call(ul.children, fli);
|
|
2086
|
+
const sidx : number = e.code === 'Home' ? 0 : selectedidx;
|
|
2087
|
+
const eidx : number = e.code === 'Home' ? selectedidx : ul.children.length - 1;
|
|
2088
|
+
for (let i: number = sidx; i <= eidx; i++) {
|
|
2089
|
+
const item: Element = ul.children[i as number];
|
|
2090
|
+
this.notify('updatelist', { li: item, e: {
|
|
2091
|
+
target: this.ulElement.getElementsByClassName('e-focused')[0],
|
|
2092
|
+
ctrlKey: e.ctrlKey, shiftKey: e.shiftKey
|
|
2093
|
+
}, module: 'listbox' });
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
|
|
2099
|
+
private KeyUp(e: KeyboardEvent): void {
|
|
2100
|
+
const char: string = String.fromCharCode(e.keyCode);
|
|
2101
|
+
const isWordCharacter: Object = char.match(/\w/);
|
|
2102
|
+
if (!isNullOrUndefined(isWordCharacter)) {
|
|
2103
|
+
this.isValidKey = true;
|
|
2104
|
+
}
|
|
2105
|
+
this.isValidKey = (e.keyCode === 8) || (e.keyCode === 46) || this.isValidKey;
|
|
2106
|
+
if (this.isValidKey) {
|
|
2107
|
+
this.isValidKey = false;
|
|
2108
|
+
switch (e.keyCode) {
|
|
2109
|
+
default:
|
|
2110
|
+
if (this.allowFiltering) {
|
|
2111
|
+
const eventArgsData: { [key: string]: Object } = {
|
|
2112
|
+
preventDefaultAction: false,
|
|
2113
|
+
text: this.targetElement(),
|
|
2114
|
+
updateData: (
|
|
2115
|
+
dataSource: {
|
|
2116
|
+
[key: string]: Object
|
|
2117
|
+
}[] | DataManager | string[] | number[], query?: Query, fields?: FieldSettingsModel) => {
|
|
2118
|
+
if (eventArgsData.cancel) { return; }
|
|
2119
|
+
this.isFiltered = true;
|
|
2120
|
+
this.remoteFilterAction = true;
|
|
2121
|
+
this.dataUpdater(dataSource, query, fields);
|
|
2122
|
+
},
|
|
2123
|
+
event: e,
|
|
2124
|
+
cancel: false
|
|
2125
|
+
};
|
|
2126
|
+
this.trigger('filtering', eventArgsData, (args: FilteringEventArgs) => {
|
|
2127
|
+
this.isDataFetched = false;
|
|
2128
|
+
if (args.cancel || (this.filterInput.value !== '' && this.isFiltered)) {
|
|
2129
|
+
return;
|
|
2130
|
+
}
|
|
2131
|
+
if (!args.cancel && !this.isCustomFiltering && !args.preventDefaultAction) {
|
|
2132
|
+
this.inputString = this.filterInput.value;
|
|
2133
|
+
this.filteringAction(this.jsonData, new Query(), this.fields);
|
|
2134
|
+
}
|
|
2135
|
+
if (!this.isFiltered && !this.isCustomFiltering && !args.preventDefaultAction) {
|
|
2136
|
+
this.dataUpdater(this.jsonData, new Query(), this.fields);
|
|
2137
|
+
}
|
|
2138
|
+
});
|
|
2139
|
+
}
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
/**
|
|
2144
|
+
* To filter the data from given data source by using query.
|
|
2145
|
+
*
|
|
2146
|
+
* @param {Object[] | DataManager } dataSource - Set the data source to filter.
|
|
2147
|
+
* @param {Query} query - Specify the query to filter the data.
|
|
2148
|
+
* @param {FieldSettingsModel} fields - Specify the fields to map the column in the data table.
|
|
2149
|
+
* @returns {void}.
|
|
2150
|
+
*/
|
|
2151
|
+
public filter(
|
|
2152
|
+
dataSource: { [key: string]: Object }[] | DataManager | string[] | number[] | boolean[],
|
|
2153
|
+
query?: Query, fields?: FieldSettingsModel): void {
|
|
2154
|
+
this.isCustomFiltering = true;
|
|
2155
|
+
this.filteringAction(dataSource, query, fields);
|
|
2156
|
+
}
|
|
2157
|
+
|
|
2158
|
+
private filteringAction(
|
|
2159
|
+
dataSource: { [key: string]: Object }[] | DataManager | string[] | number[] | boolean[],
|
|
2160
|
+
query?: Query, fields?: FieldSettingsModel): void {
|
|
2161
|
+
this.resetList(dataSource, fields, query);
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
|
|
2165
|
+
protected targetElement(): string {
|
|
2166
|
+
this.targetInputElement = this.list.getElementsByClassName('e-input-filter')[0] as HTMLInputElement;
|
|
2167
|
+
return this.targetInputElement.value;
|
|
2168
|
+
}
|
|
2169
|
+
|
|
2170
|
+
private dataUpdater(
|
|
2171
|
+
dataSource: { [key: string]: Object }[] | DataManager | string[] | number[] | boolean[],
|
|
2172
|
+
query?: Query, fields?: FieldSettingsModel): void {
|
|
2173
|
+
this.isDataFetched = false;
|
|
2174
|
+
const backCommand: boolean = true;
|
|
2175
|
+
if (this.targetElement().trim() === '') {
|
|
2176
|
+
const list: HTMLElement = this.mainList.cloneNode ? <HTMLElement>this.mainList.cloneNode(true) : this.mainList;
|
|
2177
|
+
if (backCommand) {
|
|
2178
|
+
this.remoteCustomValue = false;
|
|
2179
|
+
this.onActionComplete(list, this.jsonData as { [key: string]: Object }[] | string[] | number[] | boolean[]);
|
|
2180
|
+
this.notify('reOrder', { module: 'CheckBoxSelection', enable: this.selectionSettings.showCheckbox, e: this });
|
|
2181
|
+
}
|
|
2182
|
+
} else {
|
|
2183
|
+
this.resetList(dataSource, fields, query);
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
|
|
2187
|
+
private focusOutHandler(): void {
|
|
2188
|
+
const ele: Element = this.list.getElementsByClassName('e-focused')[0];
|
|
2189
|
+
if (ele) {
|
|
2190
|
+
ele.classList.remove('e-focused');
|
|
2191
|
+
}
|
|
2192
|
+
if (this.allowFiltering) {
|
|
2193
|
+
this.refreshClearIcon();
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
|
|
2197
|
+
private getValidIndex(cli: Element, index: number, keyCode: number): number {
|
|
2198
|
+
const cul: Element = this.ulElement;
|
|
2199
|
+
if (cli.classList.contains('e-disabled') || cli.classList.contains(cssClass.group)) {
|
|
2200
|
+
if (keyCode === 40 || keyCode === 36) {
|
|
2201
|
+
index++;
|
|
2202
|
+
} else {
|
|
2203
|
+
index--;
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
if (index < 0 || index === cul.childElementCount) {
|
|
2207
|
+
return -1;
|
|
2208
|
+
}
|
|
2209
|
+
cli = (cul.childNodes as NodeListOf<Element>)[index as number];
|
|
2210
|
+
if (cli.classList.contains('e-disabled') || cli.classList.contains(cssClass.group)) {
|
|
2211
|
+
index = this.getValidIndex(cli, index, keyCode);
|
|
2212
|
+
}
|
|
2213
|
+
return index;
|
|
2214
|
+
}
|
|
2215
|
+
|
|
2216
|
+
private updateSelectedOptions(): void {
|
|
2217
|
+
const selectedOptions: string[] = [];
|
|
2218
|
+
const values: string[] = [];
|
|
2219
|
+
extend(values, this.value as string[]);
|
|
2220
|
+
this.getSelectedItems().forEach((ele: Element) => {
|
|
2221
|
+
if (!ele.classList.contains('e-grabbed')) {
|
|
2222
|
+
selectedOptions.push(this.getFormattedValue(ele.getAttribute('data-value')) as string);
|
|
2223
|
+
}
|
|
2224
|
+
});
|
|
2225
|
+
if (this.mainList.childElementCount === this.ulElement.childElementCount) {
|
|
2226
|
+
if (this.allowFiltering && this.selectionSettings.showCheckbox) {
|
|
2227
|
+
for (let i: number = 0; i < selectedOptions.length; i++) {
|
|
2228
|
+
if (values.indexOf(selectedOptions[i as number]) > -1) {
|
|
2229
|
+
continue;
|
|
2230
|
+
} else {
|
|
2231
|
+
values.push(selectedOptions[i as number]);
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
this.setProperties({ value: values }, true);
|
|
2235
|
+
} else {
|
|
2236
|
+
this.setProperties({ value: selectedOptions }, true);
|
|
2237
|
+
}
|
|
2238
|
+
|
|
2239
|
+
}
|
|
2240
|
+
this.updateSelectTag();
|
|
2241
|
+
this.updateToolBarState();
|
|
2242
|
+
if (this.tBListBox) {
|
|
2243
|
+
this.tBListBox.updateToolBarState();
|
|
2244
|
+
}
|
|
2245
|
+
}
|
|
2246
|
+
|
|
2247
|
+
private clearSelection(values: (string | number | boolean)[] = this.value): void {
|
|
2248
|
+
if (this.selectionSettings.showCheckbox) {
|
|
2249
|
+
let dvalue: string | number | boolean;
|
|
2250
|
+
this.getSelectedItems().forEach((li: Element) => {
|
|
2251
|
+
dvalue = this.getFormattedValue(li.getAttribute('data-value'));
|
|
2252
|
+
if (values.indexOf(dvalue) < 0) {
|
|
2253
|
+
li.getElementsByClassName('e-check')[0].classList.remove('e-check');
|
|
2254
|
+
li.removeAttribute('aria-selected');
|
|
2255
|
+
}
|
|
2256
|
+
});
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2260
|
+
private setSelection(
|
|
2261
|
+
values: (string | boolean | number | object)[] = this.value, isSelect: boolean = true, isText: boolean = false): void {
|
|
2262
|
+
let li: Element;
|
|
2263
|
+
let liselect: boolean;
|
|
2264
|
+
if (values) {
|
|
2265
|
+
values.forEach((value: string) => {
|
|
2266
|
+
let text: string | number | boolean;
|
|
2267
|
+
if (isText) {
|
|
2268
|
+
text = this.getValueByText(value);
|
|
2269
|
+
} else {
|
|
2270
|
+
text = value;
|
|
2271
|
+
}
|
|
2272
|
+
if (typeof(text) === 'string') {
|
|
2273
|
+
text = text.split('\\').join('\\\\');
|
|
2274
|
+
li = this.list.querySelector('[data-value="' + text.replace(/"/g, '\\"') + '"]');
|
|
2275
|
+
} else {
|
|
2276
|
+
li = this.list.querySelector('[data-value="' + text + '"]');
|
|
2277
|
+
}
|
|
2278
|
+
if (li) {
|
|
2279
|
+
if (this.selectionSettings.showCheckbox) {
|
|
2280
|
+
liselect = li.getElementsByClassName('e-frame')[0].classList.contains('e-check');
|
|
2281
|
+
} else {
|
|
2282
|
+
liselect = li.classList.contains('e-selected');
|
|
2283
|
+
}
|
|
2284
|
+
if (!isSelect && liselect || isSelect && !liselect && li) {
|
|
2285
|
+
if (this.selectionSettings.showCheckbox) {
|
|
2286
|
+
this.notify('updatelist', { li: li, module: 'listbox' });
|
|
2287
|
+
(li as HTMLElement).focus();
|
|
2288
|
+
} else {
|
|
2289
|
+
if (isSelect) {
|
|
2290
|
+
li.classList.add(cssClass.selected);
|
|
2291
|
+
li.setAttribute('aria-selected', 'true');
|
|
2292
|
+
(li as HTMLElement).focus();
|
|
2293
|
+
} else {
|
|
2294
|
+
li.classList.remove(cssClass.selected);
|
|
2295
|
+
li.removeAttribute('aria-selected');
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2300
|
+
});
|
|
2301
|
+
}
|
|
2302
|
+
this.updateSelectTag();
|
|
2303
|
+
}
|
|
2304
|
+
|
|
2305
|
+
private updateSelectTag(): void {
|
|
2306
|
+
const ele: Element = this.getSelectTag(); let innerHTML: string = '';
|
|
2307
|
+
ele.innerHTML = '';
|
|
2308
|
+
if (this.value) {
|
|
2309
|
+
for (let i: number = 0, len: number = this.value.length; i < len; i++) {
|
|
2310
|
+
innerHTML += '<option selected>' + this.value[i as number] + '</option>';
|
|
2311
|
+
}
|
|
2312
|
+
ele.innerHTML += innerHTML;
|
|
2313
|
+
for (let i: number = 0, len: number = ele.childNodes.length; i < len; i++) {
|
|
2314
|
+
(ele.childNodes[i as number] as HTMLElement).setAttribute('value', this.value[i as number].toString());
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
this.checkSelectAll();
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
private checkDisabledState(inst: ListBox): boolean {
|
|
2321
|
+
return inst.ulElement.querySelectorAll('.' + cssClass.li).length === 0;
|
|
2322
|
+
}
|
|
2323
|
+
|
|
2324
|
+
private updateToolBarState(): void {
|
|
2325
|
+
if (this.toolbarSettings.items.length) {
|
|
2326
|
+
const listObj: ListBox = this.getScopedListBox();
|
|
2327
|
+
const wrap: Element = this.list.parentElement.getElementsByClassName('e-listbox-tool')[0];
|
|
2328
|
+
this.toolbarSettings.items.forEach((value: string) => {
|
|
2329
|
+
const btn: HTMLButtonElement = wrap.querySelector('[data-value="' + value + '"]');
|
|
2330
|
+
switch (value) {
|
|
2331
|
+
case 'moveAllTo':
|
|
2332
|
+
btn.disabled = this.checkDisabledState(this);
|
|
2333
|
+
break;
|
|
2334
|
+
case 'moveAllFrom':
|
|
2335
|
+
btn.disabled = this.checkDisabledState(listObj);
|
|
2336
|
+
break;
|
|
2337
|
+
case 'moveFrom':
|
|
2338
|
+
btn.disabled = listObj.value && listObj.value.length ? false : true;
|
|
2339
|
+
break;
|
|
2340
|
+
case 'moveUp':
|
|
2341
|
+
btn.disabled = this.value && this.value.length
|
|
2342
|
+
&& !this.isSelected(this.ulElement.children[0]) ? false : true;
|
|
2343
|
+
break;
|
|
2344
|
+
case 'moveDown':
|
|
2345
|
+
btn.disabled = this.value && this.value.length
|
|
2346
|
+
&& !this.isSelected(this.ulElement.children[this.ulElement.childElementCount - 1]) ? false : true;
|
|
2347
|
+
break;
|
|
2348
|
+
default:
|
|
2349
|
+
btn.disabled = this.value && this.value.length ? false : true;
|
|
2350
|
+
break;
|
|
2351
|
+
}
|
|
2352
|
+
});
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2356
|
+
private setCheckboxPosition(): void {
|
|
2357
|
+
const listWrap: HTMLElement = this.list;
|
|
2358
|
+
if (!this.initLoad && this.selectionSettings.checkboxPosition === 'Left') {
|
|
2359
|
+
listWrap.classList.remove('e-right');
|
|
2360
|
+
}
|
|
2361
|
+
if (this.selectionSettings.checkboxPosition === 'Right') {
|
|
2362
|
+
listWrap.classList.add('e-right');
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2365
|
+
|
|
2366
|
+
private showCheckbox(showCheckbox: boolean): void {
|
|
2367
|
+
let index: number = 0;
|
|
2368
|
+
const liColl: NodeListOf<Element> = this.list.lastElementChild.querySelectorAll('li');
|
|
2369
|
+
const liCollLen: number = this.list.lastElementChild.getElementsByClassName('e-list-item').length;
|
|
2370
|
+
if (showCheckbox) {
|
|
2371
|
+
this.ulElement = this.renderItems(this.listData as obj[], this.fields);
|
|
2372
|
+
this.mainList = this.ulElement;
|
|
2373
|
+
this.list.removeChild(this.list.getElementsByTagName('ul')[0]);
|
|
2374
|
+
this.list.appendChild(this.ulElement);
|
|
2375
|
+
if (this.selectionSettings.showSelectAll && !this.list.getElementsByClassName('e-selectall-parent')[0]) {
|
|
2376
|
+
const l10nShow: L10n = new L10n(
|
|
2377
|
+
this.getModuleName(), { selectAllText: 'Select All', unSelectAllText: 'Unselect All' }, this.locale);
|
|
2378
|
+
this.showSelectAll = true;
|
|
2379
|
+
this.selectAllText = l10nShow.getConstant('selectAllText');
|
|
2380
|
+
this.unSelectAllText = l10nShow.getConstant('unSelectAllText');
|
|
2381
|
+
this.popupWrapper = this.list;
|
|
2382
|
+
this.checkBoxSelectionModule.checkAllParent = null;
|
|
2383
|
+
this.notify('selectAll', {});
|
|
2384
|
+
this.checkSelectAll();
|
|
2385
|
+
}
|
|
2386
|
+
} else {
|
|
2387
|
+
if (this.list.getElementsByClassName('e-selectall-parent')[0]) {
|
|
2388
|
+
this.list.removeChild(this.list.getElementsByClassName('e-selectall-parent')[0]);
|
|
2389
|
+
}
|
|
2390
|
+
for (index; index < liCollLen; index++) {
|
|
2391
|
+
if (liColl[index as number].classList.contains('e-list-item')) {
|
|
2392
|
+
liColl[index as number].removeChild(liColl[index as number].getElementsByClassName('e-checkbox-wrapper')[0]);
|
|
2393
|
+
}
|
|
2394
|
+
if (liColl[index as number].hasAttribute('aria-selected')) {
|
|
2395
|
+
liColl[index as number].removeAttribute('aria-selected');
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
this.mainList = this.ulElement;
|
|
2399
|
+
}
|
|
2400
|
+
this.value = [];
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2403
|
+
private isSelected(ele: Element): boolean {
|
|
2404
|
+
if (!isNullOrUndefined(ele)) {
|
|
2405
|
+
return ele.classList.contains(cssClass.selected) || ele.querySelector('.e-check') !== null;
|
|
2406
|
+
} else {
|
|
2407
|
+
return false;
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2410
|
+
|
|
2411
|
+
private getSelectTag(): Element {
|
|
2412
|
+
return this.list.getElementsByClassName('e-hidden-select')[0];
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
private getToolElem(): Element {
|
|
2416
|
+
return this.list.parentElement.getElementsByClassName('e-listbox-tool')[0];
|
|
2417
|
+
}
|
|
2418
|
+
|
|
2419
|
+
private formResetHandler(): void {
|
|
2420
|
+
this.value = this.initialSelectedOptions;
|
|
2421
|
+
}
|
|
2422
|
+
|
|
2423
|
+
/**
|
|
2424
|
+
* Return the module name.
|
|
2425
|
+
*
|
|
2426
|
+
* @private
|
|
2427
|
+
* @returns {string} - Module name
|
|
2428
|
+
*/
|
|
2429
|
+
public getModuleName(): string {
|
|
2430
|
+
return 'listbox';
|
|
2431
|
+
}
|
|
2432
|
+
|
|
2433
|
+
/**
|
|
2434
|
+
* Get the properties to be maintained in the persisted state.
|
|
2435
|
+
*
|
|
2436
|
+
* @returns {string} - Persist data
|
|
2437
|
+
*/
|
|
2438
|
+
protected getPersistData(): string {
|
|
2439
|
+
return this.addOnPersist(['value']);
|
|
2440
|
+
}
|
|
2441
|
+
|
|
2442
|
+
protected getLocaleName(): string {
|
|
2443
|
+
return 'listbox';
|
|
2444
|
+
}
|
|
2445
|
+
|
|
2446
|
+
public destroy(): void {
|
|
2447
|
+
this.unwireEvents();
|
|
2448
|
+
if (this.element.tagName === 'EJS-LISTBOX') {
|
|
2449
|
+
this.element.innerHTML = '';
|
|
2450
|
+
} else {
|
|
2451
|
+
this.element.style.display = 'inline-block';
|
|
2452
|
+
if (this.toolbarSettings.items.length) {
|
|
2453
|
+
this.list.parentElement.parentElement.insertBefore(this.list, this.list.parentElement);
|
|
2454
|
+
detach(this.list.nextElementSibling);
|
|
2455
|
+
}
|
|
2456
|
+
this.list.parentElement.insertBefore(this.element, this.list);
|
|
2457
|
+
}
|
|
2458
|
+
super.destroy();
|
|
2459
|
+
this.enableRtlElements = []; this.liCollections = null; this.list = null; this.ulElement = null;
|
|
2460
|
+
this.mainList = null; this.spinner = null; this.rippleFun = null;
|
|
2461
|
+
if (this.itemTemplate) { this.clearTemplate(); }
|
|
2462
|
+
}
|
|
2463
|
+
|
|
2464
|
+
/**
|
|
2465
|
+
* Called internally if any of the property value changed.
|
|
2466
|
+
*
|
|
2467
|
+
* @param {ListBoxModel} newProp - Specifies the new properties.
|
|
2468
|
+
* @param {ListBoxModel} oldProp - Specifies the old properties.
|
|
2469
|
+
* @returns {void}
|
|
2470
|
+
* @private
|
|
2471
|
+
*/
|
|
2472
|
+
public onPropertyChanged(newProp: ListBoxModel, oldProp: ListBoxModel): void {
|
|
2473
|
+
const wrap: Element = this.toolbarSettings.items.length ? this.list.parentElement : this.list;
|
|
2474
|
+
super.onPropertyChanged(newProp, oldProp);
|
|
2475
|
+
this.setUpdateInitial(['fields', 'query', 'dataSource'], newProp as { [key: string]: string; });
|
|
2476
|
+
for (const prop of Object.keys(newProp)) {
|
|
2477
|
+
switch (prop) {
|
|
2478
|
+
case 'cssClass':
|
|
2479
|
+
if (oldProp.cssClass) {
|
|
2480
|
+
removeClass([wrap], oldProp.cssClass.split(' '));
|
|
2481
|
+
}
|
|
2482
|
+
if (newProp.cssClass) {
|
|
2483
|
+
addClass([wrap], newProp.cssClass.replace(/\s+/g, ' ').trim().split(' '));
|
|
2484
|
+
}
|
|
2485
|
+
break;
|
|
2486
|
+
case 'enableRtl':
|
|
2487
|
+
if (newProp.enableRtl) {
|
|
2488
|
+
this.list.classList.add('e-rtl');
|
|
2489
|
+
} else {
|
|
2490
|
+
this.list.classList.remove('e-rtl');
|
|
2491
|
+
}
|
|
2492
|
+
break;
|
|
2493
|
+
case 'value':
|
|
2494
|
+
removeClass(this.list.querySelectorAll('.' + cssClass.selected), cssClass.selected);
|
|
2495
|
+
this.clearSelection(this.value);
|
|
2496
|
+
this.setSelection();
|
|
2497
|
+
break;
|
|
2498
|
+
case 'height':
|
|
2499
|
+
this.setHeight();
|
|
2500
|
+
break;
|
|
2501
|
+
case 'enabled':
|
|
2502
|
+
this.setEnable();
|
|
2503
|
+
break;
|
|
2504
|
+
case 'allowDragAndDrop':
|
|
2505
|
+
if (newProp.allowDragAndDrop) {
|
|
2506
|
+
this.initDraggable();
|
|
2507
|
+
} else {
|
|
2508
|
+
(getComponent(this.ulElement, 'sortable') as Sortable).destroy();
|
|
2509
|
+
}
|
|
2510
|
+
break;
|
|
2511
|
+
case 'allowFiltering':
|
|
2512
|
+
if (this.allowFiltering) {
|
|
2513
|
+
this.setFiltering();
|
|
2514
|
+
} else {
|
|
2515
|
+
this.list.removeChild(this.list.getElementsByClassName('e-filter-parent')[0]);
|
|
2516
|
+
this.filterParent = null;
|
|
2517
|
+
removeClass([this.list], 'e-filter-list');
|
|
2518
|
+
}
|
|
2519
|
+
break;
|
|
2520
|
+
case 'filterBarPlaceholder':
|
|
2521
|
+
if (this.allowFiltering) {
|
|
2522
|
+
if (this.filterInput) { Input.setPlaceholder(newProp.filterBarPlaceholder, this.filterInput as HTMLInputElement); }
|
|
2523
|
+
}
|
|
2524
|
+
break;
|
|
2525
|
+
case 'scope':
|
|
2526
|
+
if (this.allowDragAndDrop) {
|
|
2527
|
+
(getComponent(this.ulElement, 'sortable') as Sortable).scope = newProp.scope;
|
|
2528
|
+
}
|
|
2529
|
+
if (this.toolbarSettings.items.length) {
|
|
2530
|
+
if (oldProp.scope) {
|
|
2531
|
+
(getComponent(document.querySelector(oldProp.scope) as HTMLElement, this.getModuleName()) as ListBox)
|
|
2532
|
+
.tBListBox = null;
|
|
2533
|
+
}
|
|
2534
|
+
if (newProp.scope) {
|
|
2535
|
+
(getComponent(document.querySelector(newProp.scope) as HTMLElement, this.getModuleName()) as ListBox)
|
|
2536
|
+
.tBListBox = this;
|
|
2537
|
+
}
|
|
2538
|
+
}
|
|
2539
|
+
break;
|
|
2540
|
+
case 'toolbarSettings': {
|
|
2541
|
+
let ele: Element;
|
|
2542
|
+
const pos: string = newProp.toolbarSettings.position;
|
|
2543
|
+
const toolElem: Element = this.getToolElem();
|
|
2544
|
+
if (pos) {
|
|
2545
|
+
removeClass([wrap], ['e-right', 'e-left']);
|
|
2546
|
+
wrap.classList.add('e-' + pos.toLowerCase());
|
|
2547
|
+
if (pos === 'Left') {
|
|
2548
|
+
wrap.insertBefore(toolElem, this.list);
|
|
2549
|
+
} else {
|
|
2550
|
+
wrap.appendChild(toolElem);
|
|
2551
|
+
}
|
|
2552
|
+
}
|
|
2553
|
+
if (newProp.toolbarSettings.items) {
|
|
2554
|
+
if (oldProp.toolbarSettings && oldProp.toolbarSettings.items.length) {
|
|
2555
|
+
ele = this.list.parentElement;
|
|
2556
|
+
ele.parentElement.insertBefore(this.list, ele);
|
|
2557
|
+
detach(ele);
|
|
2558
|
+
}
|
|
2559
|
+
this.initToolbarAndStyles();
|
|
2560
|
+
this.wireToolbarEvent();
|
|
2561
|
+
}
|
|
2562
|
+
break;
|
|
2563
|
+
}
|
|
2564
|
+
case 'selectionSettings': {
|
|
2565
|
+
const showSelectAll: boolean = newProp.selectionSettings.showSelectAll;
|
|
2566
|
+
const showCheckbox: boolean = newProp.selectionSettings.showCheckbox;
|
|
2567
|
+
if (!isNullOrUndefined(showSelectAll)) {
|
|
2568
|
+
this.showSelectAll = showSelectAll;
|
|
2569
|
+
if (this.showSelectAll) {
|
|
2570
|
+
const l10nSel: L10n = new L10n(
|
|
2571
|
+
this.getModuleName(), { selectAllText: 'Select All', unSelectAllText: 'Unselect All' }, this.locale);
|
|
2572
|
+
this.checkBoxSelectionModule.checkAllParent = null;
|
|
2573
|
+
this.showSelectAll = true;
|
|
2574
|
+
this.selectAllText = l10nSel.getConstant('selectAllText');
|
|
2575
|
+
this.unSelectAllText = l10nSel.getConstant('selectAllText');
|
|
2576
|
+
this.popupWrapper = this.list;
|
|
2577
|
+
}
|
|
2578
|
+
this.notify('selectAll', {});
|
|
2579
|
+
this.checkSelectAll();
|
|
2580
|
+
}
|
|
2581
|
+
if (!isNullOrUndefined(showCheckbox)) {
|
|
2582
|
+
this.showCheckbox(showCheckbox);
|
|
2583
|
+
}
|
|
2584
|
+
if (this.selectionSettings.showCheckbox) {
|
|
2585
|
+
this.setCheckboxPosition();
|
|
2586
|
+
}
|
|
2587
|
+
break;
|
|
2588
|
+
}
|
|
2589
|
+
case 'dataSource':
|
|
2590
|
+
this.isDataSourceUpdate = true;
|
|
2591
|
+
this.jsonData = [].slice.call(this.dataSource);
|
|
2592
|
+
break;
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
}
|
|
2596
|
+
}
|
|
2597
|
+
|
|
2598
|
+
/**
|
|
2599
|
+
* Interface for before item render event.
|
|
2600
|
+
*/
|
|
2601
|
+
export interface BeforeItemRenderEventArgs extends BaseEventArgs {
|
|
2602
|
+
/**
|
|
2603
|
+
* Returns the list element before rendering.
|
|
2604
|
+
*/
|
|
2605
|
+
element: Element;
|
|
2606
|
+
/**
|
|
2607
|
+
* Returns the list item before rendering.
|
|
2608
|
+
*/
|
|
2609
|
+
item: { [key: string]: Object };
|
|
2610
|
+
}
|
|
2611
|
+
|
|
2612
|
+
/**
|
|
2613
|
+
* Interface for drag and drop event args.
|
|
2614
|
+
*/
|
|
2615
|
+
export interface SourceDestinationModel {
|
|
2616
|
+
/**
|
|
2617
|
+
* Specifies the list items before drag or drop in the ListBox.
|
|
2618
|
+
*/
|
|
2619
|
+
previousData?: string[] | boolean[] | number[] | { [key: string]: Object; }[] | DataManager;
|
|
2620
|
+
/**
|
|
2621
|
+
* Specifies the list items after drag or drop in the ListBox.
|
|
2622
|
+
*/
|
|
2623
|
+
currentData?: string[] | boolean[] | number[] | { [key: string]: Object; }[] | DataManager;
|
|
2624
|
+
}
|
|
2625
|
+
|
|
2626
|
+
/**
|
|
2627
|
+
* Interface for drag and drop event.
|
|
2628
|
+
*/
|
|
2629
|
+
export interface DragEventArgs {
|
|
2630
|
+
/**
|
|
2631
|
+
* Returns the previous index of the selected list item.
|
|
2632
|
+
*/
|
|
2633
|
+
previousIndex?: number;
|
|
2634
|
+
/**
|
|
2635
|
+
* Returns the current index of the selected list item.
|
|
2636
|
+
*/
|
|
2637
|
+
currentIndex?: number;
|
|
2638
|
+
/**
|
|
2639
|
+
* Returns the selected list element.
|
|
2640
|
+
*/
|
|
2641
|
+
elements: Element[];
|
|
2642
|
+
/**
|
|
2643
|
+
* Returns the selected list items.
|
|
2644
|
+
*/
|
|
2645
|
+
items: Object[];
|
|
2646
|
+
/**
|
|
2647
|
+
* Returns the target list element where the selected list element to be dropped.
|
|
2648
|
+
*/
|
|
2649
|
+
target?: Element;
|
|
2650
|
+
/**
|
|
2651
|
+
* Returns true if the list element is dragged from ListBox. Otherwise, it remains false.
|
|
2652
|
+
*/
|
|
2653
|
+
dragSelected?: boolean;
|
|
2654
|
+
/**
|
|
2655
|
+
* Returns the previous list item.
|
|
2656
|
+
*/
|
|
2657
|
+
previousItem?: object[];
|
|
2658
|
+
/**
|
|
2659
|
+
* Returns the previous and current list items of the source list box.
|
|
2660
|
+
*/
|
|
2661
|
+
source?: SourceDestinationModel;
|
|
2662
|
+
/**
|
|
2663
|
+
* Returns the previous and current list items of the destination list box.
|
|
2664
|
+
*/
|
|
2665
|
+
destination?: SourceDestinationModel;
|
|
2666
|
+
}
|
|
2667
|
+
|
|
2668
|
+
/**
|
|
2669
|
+
* Interface for change event args.
|
|
2670
|
+
*/
|
|
2671
|
+
export interface ListBoxChangeEventArgs extends BaseEventArgs {
|
|
2672
|
+
/**
|
|
2673
|
+
* Returns the selected list elements.
|
|
2674
|
+
*/
|
|
2675
|
+
elements: Element[];
|
|
2676
|
+
/**
|
|
2677
|
+
* Returns the selected list items.
|
|
2678
|
+
*/
|
|
2679
|
+
items: Object[];
|
|
2680
|
+
/**
|
|
2681
|
+
* Returns the selected state or selected list item in the ListBox.
|
|
2682
|
+
*/
|
|
2683
|
+
value: number | string | boolean;
|
|
2684
|
+
/**
|
|
2685
|
+
* Specifies the event.
|
|
2686
|
+
*/
|
|
2687
|
+
event: Event;
|
|
2688
|
+
}
|
|
2689
|
+
|
|
2690
|
+
/**
|
|
2691
|
+
* Interface for Drop event args.
|
|
2692
|
+
*/
|
|
2693
|
+
export interface DropEventArgs {
|
|
2694
|
+
/**
|
|
2695
|
+
* Returns the previous index of the selected list item.
|
|
2696
|
+
*/
|
|
2697
|
+
previousIndex: number;
|
|
2698
|
+
/**
|
|
2699
|
+
* Returns the current index of the selected list item.
|
|
2700
|
+
*/
|
|
2701
|
+
currentIndex: number;
|
|
2702
|
+
/**
|
|
2703
|
+
* Returns the selected list element to be dropped.
|
|
2704
|
+
*/
|
|
2705
|
+
droppedElement: Element;
|
|
2706
|
+
/**
|
|
2707
|
+
* Returns the target list element where the selected list element to be dropped.
|
|
2708
|
+
*/
|
|
2709
|
+
target: Element;
|
|
2710
|
+
/**
|
|
2711
|
+
* Returns the dragged list element.
|
|
2712
|
+
*/
|
|
2713
|
+
helper: Element;
|
|
2714
|
+
/**
|
|
2715
|
+
* Illustrates whether the current action needs to be prevented or not.
|
|
2716
|
+
*/
|
|
2717
|
+
cancel?: boolean;
|
|
2718
|
+
/**
|
|
2719
|
+
* Returns the selected list items.
|
|
2720
|
+
*/
|
|
2721
|
+
items?: Object[];
|
|
2722
|
+
}
|
|
2723
|
+
interface ListBoxClassList {
|
|
2724
|
+
backIcon: string;
|
|
2725
|
+
filterBarClearIcon: string;
|
|
2726
|
+
filterInput: string;
|
|
2727
|
+
filterParent: string;
|
|
2728
|
+
clearIcon: string;
|
|
2729
|
+
}
|
|
2730
|
+
const listBoxClasses: ListBoxClassList = {
|
|
2731
|
+
backIcon: 'e-input-group-icon e-back-icon e-icons',
|
|
2732
|
+
filterBarClearIcon: 'e-input-group-icon e-clear-icon e-icons',
|
|
2733
|
+
filterInput: 'e-input-filter',
|
|
2734
|
+
filterParent: 'e-filter-parent',
|
|
2735
|
+
clearIcon: 'e-clear-icon'
|
|
2736
|
+
};
|