@syncfusion/ej2-lists 22.2.11 → 23.1.42
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 +18 -54
- package/dist/ej2-lists.min.js +3 -3
- package/dist/ej2-lists.umd.min.js +3 -3
- package/dist/ej2-lists.umd.min.js.map +1 -1
- package/dist/es6/ej2-lists.es2015.js +100 -218
- package/dist/es6/ej2-lists.es2015.js.map +1 -1
- package/dist/es6/ej2-lists.es5.js +108 -237
- package/dist/es6/ej2-lists.es5.js.map +1 -1
- package/dist/global/ej2-lists.min.js +3 -3
- package/dist/global/ej2-lists.min.js.map +1 -1
- package/dist/global/index.d.ts +2 -2
- package/dist/ts/common/list-base.ts +1286 -0
- package/dist/ts/component.ts +4 -0
- package/dist/ts/list-view/list-view.ts +2653 -0
- package/dist/ts/list-view/virtualization.ts +1187 -0
- package/dist/ts/sortable/sortable.ts +485 -0
- package/package.json +9 -9
- package/src/common/list-base.d.ts +0 -6
- package/src/common/list-base.js +1 -1
- package/src/list-view/list-view-model.d.ts +7 -7
- package/src/list-view/list-view.d.ts +6 -6
- package/src/list-view/list-view.js +6 -18
- package/src/list-view/virtualization.d.ts +3 -3
- package/src/list-view/virtualization.js +101 -218
- package/styles/list-view/bootstrap-dark.scss +1 -1
- package/styles/list-view/bootstrap.scss +1 -1
- package/styles/list-view/bootstrap4.scss +1 -1
- package/styles/list-view/bootstrap5-dark.scss +1 -1
- package/styles/list-view/bootstrap5.scss +1 -1
- package/styles/list-view/fabric-dark.scss +1 -1
- package/styles/list-view/fabric.scss +1 -1
- package/styles/list-view/fluent-dark.scss +1 -1
- package/styles/list-view/fluent.scss +1 -1
- package/styles/list-view/highcontrast-light.scss +1 -1
- package/styles/list-view/highcontrast.scss +1 -1
- package/styles/list-view/material-dark.css +0 -1
- package/styles/list-view/material-dark.scss +1 -1
- package/styles/list-view/material.css +0 -1
- package/styles/list-view/material.scss +1 -1
- package/styles/list-view/material3-dark.css +0 -1
- package/styles/list-view/material3-dark.scss +1 -1
- package/styles/list-view/material3.css +0 -1
- package/styles/list-view/material3.scss +1 -1
- package/styles/list-view/tailwind-dark.css +0 -1
- package/styles/list-view/tailwind-dark.scss +1 -1
- package/styles/list-view/tailwind.css +0 -1
- package/styles/list-view/tailwind.scss +1 -1
- package/styles/material-dark.css +0 -1
- package/styles/material.css +0 -1
- package/styles/material3-dark.css +0 -1
- package/styles/material3-dark.scss +1 -1
- package/styles/material3.css +0 -1
- package/styles/material3.scss +1 -1
- package/styles/sortable/bootstrap-dark.scss +1 -1
- package/styles/sortable/bootstrap.scss +1 -1
- package/styles/sortable/bootstrap4.scss +1 -1
- package/styles/sortable/bootstrap5-dark.scss +1 -1
- package/styles/sortable/bootstrap5.scss +1 -1
- package/styles/sortable/fabric-dark.scss +1 -1
- package/styles/sortable/fabric.scss +1 -1
- package/styles/sortable/fluent-dark.scss +1 -1
- package/styles/sortable/fluent.scss +1 -1
- package/styles/sortable/highcontrast-light.scss +1 -1
- package/styles/sortable/highcontrast.scss +1 -1
- package/styles/sortable/material-dark.css +0 -1
- package/styles/sortable/material-dark.scss +1 -1
- package/styles/sortable/material.css +0 -1
- package/styles/sortable/material.scss +1 -1
- package/styles/sortable/material3-dark.css +0 -1
- package/styles/sortable/material3-dark.scss +1 -1
- package/styles/sortable/material3.css +0 -1
- package/styles/sortable/material3.scss +1 -1
- package/styles/sortable/tailwind-dark.css +0 -1
- package/styles/sortable/tailwind-dark.scss +1 -1
- package/styles/sortable/tailwind.css +0 -1
- package/styles/sortable/tailwind.scss +1 -1
- package/styles/tailwind-dark.css +0 -2
- package/styles/tailwind.css +0 -2
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
import { Base, Event, getUniqueID, NotifyPropertyChanges, INotifyPropertyChanged, Property } from '@syncfusion/ej2-base';
|
|
2
|
+
import { closest, Draggable, DragPosition, MouseEventArgs, remove, compareElementParent } from '@syncfusion/ej2-base';
|
|
3
|
+
import { addClass, isNullOrUndefined, getComponent, isBlazor, BlazorDragEventArgs, EventHandler } from '@syncfusion/ej2-base';
|
|
4
|
+
import { SortableModel } from './sortable-model';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Sortable Module provides support to enable sortable functionality in Dom Elements.
|
|
8
|
+
* ```html
|
|
9
|
+
* <div id="sortable">
|
|
10
|
+
* <div>Item 1</div>
|
|
11
|
+
* <div>Item 2</div>
|
|
12
|
+
* <div>Item 3</div>
|
|
13
|
+
* <div>Item 4</div>
|
|
14
|
+
* <div>Item 5</div>
|
|
15
|
+
* </div>
|
|
16
|
+
* ```
|
|
17
|
+
* ```typescript
|
|
18
|
+
* let ele: HTMLElement = document.getElementById('sortable');
|
|
19
|
+
* let sortObj: Sortable = new Sortable(ele, {});
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
@NotifyPropertyChanges
|
|
23
|
+
export class Sortable extends Base<HTMLElement> implements INotifyPropertyChanged {
|
|
24
|
+
private target: HTMLElement;
|
|
25
|
+
private curTarget: HTMLElement;
|
|
26
|
+
private placeHolderElement: HTMLElement;
|
|
27
|
+
/**
|
|
28
|
+
* It is used to enable or disable the built-in animations. The default value is `false`
|
|
29
|
+
*
|
|
30
|
+
* @default false
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
@Property(false)
|
|
34
|
+
public enableAnimation: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Specifies the sortable item class.
|
|
37
|
+
*
|
|
38
|
+
* @default null
|
|
39
|
+
*/
|
|
40
|
+
@Property(null)
|
|
41
|
+
public itemClass: string;
|
|
42
|
+
/**
|
|
43
|
+
* Defines the scope value to group sets of sortable libraries.
|
|
44
|
+
* More than one Sortable with same scope allows to transfer elements between different sortable libraries which has same scope value.
|
|
45
|
+
*/
|
|
46
|
+
@Property(null)
|
|
47
|
+
public scope: string;
|
|
48
|
+
/**
|
|
49
|
+
* Defines the callback function for customizing the cloned element.
|
|
50
|
+
*/
|
|
51
|
+
@Property()
|
|
52
|
+
public helper: (Element: object) => HTMLElement;
|
|
53
|
+
/**
|
|
54
|
+
* Defines the callback function for customizing the placeHolder element.
|
|
55
|
+
*/
|
|
56
|
+
@Property()
|
|
57
|
+
public placeHolder: (Element: object) => HTMLElement;
|
|
58
|
+
/**
|
|
59
|
+
* Specifies the callback function for drag event.
|
|
60
|
+
*
|
|
61
|
+
* @event 'object'
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@Event()
|
|
66
|
+
public drag: (e: any) => void;
|
|
67
|
+
/**
|
|
68
|
+
* Specifies the callback function for beforeDragStart event.
|
|
69
|
+
*
|
|
70
|
+
* @event 'object'
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
@Event()
|
|
74
|
+
public beforeDragStart: (e: any) => void;
|
|
75
|
+
/**
|
|
76
|
+
* Specifies the callback function for dragStart event.
|
|
77
|
+
*
|
|
78
|
+
* @event 'object'
|
|
79
|
+
*/
|
|
80
|
+
|
|
81
|
+
@Event()
|
|
82
|
+
public dragStart: (e: any) => void;
|
|
83
|
+
/**
|
|
84
|
+
* Specifies the callback function for beforeDrop event.
|
|
85
|
+
*
|
|
86
|
+
* @event 'object'
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
@Event()
|
|
90
|
+
public beforeDrop: (e: any) => void;
|
|
91
|
+
/**
|
|
92
|
+
* Specifies the callback function for drop event.
|
|
93
|
+
*
|
|
94
|
+
* @event 'object'
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
@Event()
|
|
98
|
+
public drop: (e: any) => void;
|
|
99
|
+
constructor(element: HTMLElement, options?: SortableModel) {
|
|
100
|
+
super(options, element);
|
|
101
|
+
this.bind();
|
|
102
|
+
}
|
|
103
|
+
protected bind(): void {
|
|
104
|
+
if (!this.element.id) {
|
|
105
|
+
this.element.id = getUniqueID('sortable');
|
|
106
|
+
}
|
|
107
|
+
if (!this.itemClass) {
|
|
108
|
+
this.itemClass = 'e-sort-item';
|
|
109
|
+
this.dataBind();
|
|
110
|
+
}
|
|
111
|
+
this.initializeDraggable();
|
|
112
|
+
}
|
|
113
|
+
private initializeDraggable(): void {
|
|
114
|
+
new Draggable(this.element, {
|
|
115
|
+
helper: this.getHelper,
|
|
116
|
+
dragStart: this.onDragStart,
|
|
117
|
+
drag: this.onDrag,
|
|
118
|
+
dragStop: this.onDragStop,
|
|
119
|
+
dragTarget: `.${this.itemClass}`,
|
|
120
|
+
enableTapHold: true,
|
|
121
|
+
tapHoldThreshold: 200,
|
|
122
|
+
queryPositionInfo: this.queryPositionInfo,
|
|
123
|
+
distance: 5
|
|
124
|
+
});
|
|
125
|
+
this.wireEvents();
|
|
126
|
+
}
|
|
127
|
+
private wireEvents(): void {
|
|
128
|
+
const wrapper: Element = this.element;
|
|
129
|
+
EventHandler.add(wrapper, 'keydown', this.keyDownHandler, this);
|
|
130
|
+
}
|
|
131
|
+
private unwireEvents(): void {
|
|
132
|
+
const wrapper: Element = this.element;
|
|
133
|
+
EventHandler.remove(wrapper, 'keydown', this.keyDownHandler);
|
|
134
|
+
}
|
|
135
|
+
private keyDownHandler(e: KeyboardEvent): void {
|
|
136
|
+
if (e.keyCode === 27) {
|
|
137
|
+
let dragStop: Draggable = getComponent(this.element, 'draggable');
|
|
138
|
+
if (dragStop) {
|
|
139
|
+
dragStop.intDestroy(null);
|
|
140
|
+
}
|
|
141
|
+
const dragWrapper: Element = document.getElementsByClassName('e-sortableclone')[0];
|
|
142
|
+
if (dragWrapper) {
|
|
143
|
+
dragWrapper.remove();
|
|
144
|
+
}
|
|
145
|
+
const dragPlaceholder: Element = document.getElementsByClassName('e-sortable-placeholder')[0];
|
|
146
|
+
if (dragPlaceholder) {
|
|
147
|
+
dragPlaceholder.remove();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private getPlaceHolder(target: HTMLElement, instance: Sortable): HTMLElement {
|
|
153
|
+
if (instance.placeHolder) {
|
|
154
|
+
const placeHolderElement: HTMLElement = instance.placeHolder(
|
|
155
|
+
{ element: instance.element, grabbedElement: this.target, target: target });
|
|
156
|
+
placeHolderElement.classList.add('e-sortable-placeholder');
|
|
157
|
+
return placeHolderElement;
|
|
158
|
+
}
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
private getHelper: Function = (e: { sender: MouseEventArgs, element: HTMLElement }) => {
|
|
163
|
+
// eslint-disable-next-line prefer-const
|
|
164
|
+
let target: HTMLElement = this.getSortableElement(e.sender.target as HTMLElement);
|
|
165
|
+
if (!this.isValidTarget(target as Element, this)) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
let element: HTMLElement;
|
|
169
|
+
if (this.helper) {
|
|
170
|
+
element = this.helper({ sender: target, element: e.element });
|
|
171
|
+
} else {
|
|
172
|
+
element = target.cloneNode(true) as HTMLElement;
|
|
173
|
+
element.style.width = `${target.offsetWidth}px`; element.style.height = `${target.offsetHeight}px`;
|
|
174
|
+
}
|
|
175
|
+
addClass([element], ['e-sortableclone']);
|
|
176
|
+
document.body.appendChild(element);
|
|
177
|
+
return element;
|
|
178
|
+
}
|
|
179
|
+
private isValidTarget(target: Element, instance: Sortable): boolean {
|
|
180
|
+
return target && compareElementParent(target, instance.element) && target.classList.contains(instance.itemClass) &&
|
|
181
|
+
!target.classList.contains('e-disabled');
|
|
182
|
+
}
|
|
183
|
+
// eslint-disable-next-line
|
|
184
|
+
private onDrag: Function = (e: { target: HTMLElement, event: MouseEventArgs }) => {
|
|
185
|
+
if (!e.target) { return; }
|
|
186
|
+
this.trigger('drag', { event: e.event, element: this.element, target: e.target });
|
|
187
|
+
let newInst: Sortable = this.getSortableInstance(e.target); let target: HTMLElement = this.getSortableElement(e.target, newInst);
|
|
188
|
+
if ((this.isValidTarget(target, newInst) || e.target.className.indexOf('e-list-group-item') > -1) && (this.curTarget !== target ||
|
|
189
|
+
!isNullOrUndefined(newInst.placeHolder)) && (newInst.placeHolderElement ? newInst.placeHolderElement !== e.target : true)) {
|
|
190
|
+
if (e.target.className.indexOf('e-list-group-item') > -1) {
|
|
191
|
+
target = e.target;
|
|
192
|
+
}
|
|
193
|
+
this.curTarget = target;
|
|
194
|
+
if (this.target === target) { return; }
|
|
195
|
+
let oldIdx: number = this.getIndex(newInst.placeHolderElement, newInst);
|
|
196
|
+
const placeHolder: HTMLElement = this.getPlaceHolder(target, newInst);
|
|
197
|
+
let newIdx: number;
|
|
198
|
+
if (placeHolder) {
|
|
199
|
+
oldIdx = isNullOrUndefined(oldIdx) ? this.getIndex(this.target) : oldIdx;
|
|
200
|
+
newIdx = this.getIndex(target, newInst, e.event);
|
|
201
|
+
const isPlaceHolderPresent: boolean = this.isPlaceHolderPresent(newInst);
|
|
202
|
+
if (isPlaceHolderPresent && oldIdx === newIdx) { return; }
|
|
203
|
+
if (isPlaceHolderPresent) { remove(newInst.placeHolderElement); }
|
|
204
|
+
newInst.placeHolderElement = placeHolder;
|
|
205
|
+
if (e.target.className.indexOf('e-list-group-item') > -1) {
|
|
206
|
+
newInst.element.insertBefore(newInst.placeHolderElement, newInst.element.children[newIdx as number]);
|
|
207
|
+
} else if (newInst.element !== this.element && newIdx === newInst.element.childElementCount) {
|
|
208
|
+
newInst.element.appendChild(newInst.placeHolderElement);
|
|
209
|
+
} else {
|
|
210
|
+
newInst.element.insertBefore(newInst.placeHolderElement, newInst.element.children[newIdx as number]);
|
|
211
|
+
}
|
|
212
|
+
this.refreshDisabled(oldIdx, newIdx, newInst);
|
|
213
|
+
} else {
|
|
214
|
+
oldIdx = isNullOrUndefined(oldIdx) ? this.getIndex(this.target) :
|
|
215
|
+
this.getIndex(target, newInst) < oldIdx || !oldIdx ? oldIdx : oldIdx - 1;
|
|
216
|
+
newIdx = this.getIndex(target, newInst);
|
|
217
|
+
const idx: number = newInst.element !== this.element ? newIdx : oldIdx < newIdx ? newIdx + 1 : newIdx;
|
|
218
|
+
this.updateItemClass(newInst);
|
|
219
|
+
newInst.element.insertBefore(this.target, newInst.element.children[idx as number]);
|
|
220
|
+
this.refreshDisabled(oldIdx, newIdx, newInst);
|
|
221
|
+
this.curTarget = this.target;
|
|
222
|
+
this.trigger('drop', {
|
|
223
|
+
droppedElement: this.target, element: newInst.element, previousIndex: oldIdx, currentIndex: newIdx,
|
|
224
|
+
target: e.target, helper: document.getElementsByClassName('e-sortableclone')[0], event: e.event, scope: this.scope
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
} else if (this.curTarget !== this.target && this.scope && this.curTarget !== target && !isNullOrUndefined(newInst.placeHolder)) {
|
|
228
|
+
remove(this.getSortableInstance(this.curTarget).placeHolderElement);
|
|
229
|
+
this.curTarget = this.target;
|
|
230
|
+
}
|
|
231
|
+
newInst = this.getSortableInstance(this.curTarget);
|
|
232
|
+
if (isNullOrUndefined(target) && e.target !== newInst.placeHolderElement) {
|
|
233
|
+
if (this.isPlaceHolderPresent(newInst)) { this.removePlaceHolder(newInst); }
|
|
234
|
+
} else {
|
|
235
|
+
const placeHolders: Element[] = [].slice.call(document.getElementsByClassName('e-sortable-placeholder')); let inst: Sortable;
|
|
236
|
+
placeHolders.forEach((placeHolder: Element) => {
|
|
237
|
+
inst = this.getSortableInstance(placeHolder);
|
|
238
|
+
if (inst.element && inst !== newInst) { this.removePlaceHolder(inst); }
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
private removePlaceHolder(instance: Sortable): void {
|
|
243
|
+
remove(instance.placeHolderElement);
|
|
244
|
+
instance.placeHolderElement = null;
|
|
245
|
+
}
|
|
246
|
+
private updateItemClass(instance: Sortable): void {
|
|
247
|
+
if (this !== instance) {
|
|
248
|
+
this.target.classList.remove(this.itemClass);
|
|
249
|
+
this.target.classList.add(instance.itemClass);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
private getSortableInstance(element: Element): Sortable {
|
|
253
|
+
element = closest(element, `.e-${this.getModuleName()}`);
|
|
254
|
+
if (element) {
|
|
255
|
+
const inst: Sortable = getComponent(element as HTMLElement, Sortable) as Sortable;
|
|
256
|
+
return inst.scope && this.scope && inst.scope === this.scope ? inst : this;
|
|
257
|
+
} else {
|
|
258
|
+
return this;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
private refreshDisabled(oldIdx: number, newIdx: number, instance: Sortable): void {
|
|
262
|
+
if (instance === this) {
|
|
263
|
+
let element: Element; const increased: boolean = oldIdx < newIdx; let disabledIdx: number;
|
|
264
|
+
let start: number = increased ? oldIdx : newIdx; const end: number = increased ? newIdx : oldIdx;
|
|
265
|
+
while (start <= end) {
|
|
266
|
+
element = this.element.children[start as number];
|
|
267
|
+
if (element.classList.contains('e-disabled')) {
|
|
268
|
+
disabledIdx = this.getIndex(element);
|
|
269
|
+
this.element.insertBefore(element, this.element.children[increased ? disabledIdx + 2 : disabledIdx - 1]);
|
|
270
|
+
start = increased ? disabledIdx + 2 : disabledIdx + 1;
|
|
271
|
+
} else {
|
|
272
|
+
start++;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
private getIndex(target: Element, instance: Sortable = this, e?: MouseEventArgs): number {
|
|
278
|
+
let idx: number; let placeHolderPresent: boolean;
|
|
279
|
+
[].slice.call(instance.element.children).forEach((element: HTMLElement, index: number): void => {
|
|
280
|
+
if (element.classList.contains('e-sortable-placeholder')) { placeHolderPresent = true; }
|
|
281
|
+
if (element === target) {
|
|
282
|
+
idx = index;
|
|
283
|
+
if (!isNullOrUndefined(e)) {
|
|
284
|
+
if (placeHolderPresent) { idx -= 1; }
|
|
285
|
+
const offset: ClientRect = target.getBoundingClientRect();
|
|
286
|
+
const clientY: number = offset.bottom - ((offset.bottom - offset.top) / 2);
|
|
287
|
+
const cltY: number = e.changedTouches ? e.changedTouches[0].clientY : e.clientY;
|
|
288
|
+
idx = cltY <= clientY ? idx : idx + 1;
|
|
289
|
+
}
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
return idx;
|
|
294
|
+
}
|
|
295
|
+
private getSortableElement(element: HTMLElement, instance: Sortable = this): HTMLElement {
|
|
296
|
+
return closest(element, `.${instance.itemClass}`) as HTMLElement;
|
|
297
|
+
}
|
|
298
|
+
// eslint-disable-next-line
|
|
299
|
+
private onDragStart: Function = (e: { target: HTMLElement, event: MouseEventArgs, helper: Element } & BlazorDragEventArgs) => {
|
|
300
|
+
this.target = this.getSortableElement(e.target);
|
|
301
|
+
let cancelDrag: boolean = false;
|
|
302
|
+
this.target.classList.add('e-grabbed');
|
|
303
|
+
this.curTarget = this.target;
|
|
304
|
+
e.helper = document.getElementsByClassName('e-sortableclone')[0];
|
|
305
|
+
const args: object = { cancel: false, element: this.element, target: this.target };
|
|
306
|
+
this.trigger('beforeDragStart', args, (observedArgs: BeforeDragEventArgs) => {
|
|
307
|
+
if (observedArgs.cancel) {
|
|
308
|
+
cancelDrag = observedArgs.cancel;
|
|
309
|
+
this.onDragStop(e);
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
if (cancelDrag) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
if (isBlazor) {
|
|
316
|
+
this.trigger('dragStart', {
|
|
317
|
+
event: e.event, element: this.element, target: this.target,
|
|
318
|
+
bindEvents: e.bindEvents, dragElement: e.dragElement
|
|
319
|
+
});
|
|
320
|
+
} else {
|
|
321
|
+
this.trigger('dragStart', { event: e.event, element: this.element, target: this.target });
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
private queryPositionInfo(value: DragPosition): DragPosition {
|
|
325
|
+
value.left = pageXOffset ? `${parseFloat(value.left) - pageXOffset}px` : value.left;
|
|
326
|
+
value.top = pageYOffset ? `${parseFloat(value.top) - pageYOffset}px` : value.top;
|
|
327
|
+
return value;
|
|
328
|
+
}
|
|
329
|
+
private isPlaceHolderPresent(instance: Sortable): boolean {
|
|
330
|
+
return instance.placeHolderElement && !!closest(instance.placeHolderElement, `#${instance.element.id}`);
|
|
331
|
+
}
|
|
332
|
+
// eslint-disable-next-line
|
|
333
|
+
private onDragStop: Function = (e: { target: HTMLElement, event: MouseEvent & TouchEvent, helper: Element }) => {
|
|
334
|
+
let dropInst: Sortable = this.getSortableInstance(this.curTarget); let prevIdx: number; let curIdx: number; let handled: boolean;
|
|
335
|
+
prevIdx = this.getIndex(this.target);
|
|
336
|
+
const isPlaceHolderPresent: boolean = this.isPlaceHolderPresent(dropInst);
|
|
337
|
+
if (isPlaceHolderPresent) {
|
|
338
|
+
const curIdx: number = this.getIndex(dropInst.placeHolderElement, dropInst);
|
|
339
|
+
const args: DropEventArgs = {
|
|
340
|
+
previousIndex: prevIdx, currentIndex: curIdx, target: e.target, droppedElement: this.target,
|
|
341
|
+
helper: e.helper, cancel: false, handled: false
|
|
342
|
+
};
|
|
343
|
+
this.trigger('beforeDrop', args, (observedArgs: DropEventArgs) => {
|
|
344
|
+
if (!observedArgs.cancel) {
|
|
345
|
+
handled = observedArgs.handled;
|
|
346
|
+
this.updateItemClass(dropInst);
|
|
347
|
+
if (observedArgs.handled) {
|
|
348
|
+
const ele: Node = this.target.cloneNode(true);
|
|
349
|
+
this.target.classList.remove('e-grabbed');
|
|
350
|
+
this.target = ele as HTMLElement;
|
|
351
|
+
}
|
|
352
|
+
dropInst.element.insertBefore(this.target, dropInst.placeHolderElement);
|
|
353
|
+
const curIdx: number = this.getIndex(this.target, dropInst);
|
|
354
|
+
prevIdx = this === dropInst && (prevIdx - curIdx) > 1 ? prevIdx - 1 : prevIdx;
|
|
355
|
+
this.trigger('drop', {
|
|
356
|
+
event: e.event, element: dropInst.element, previousIndex: prevIdx, currentIndex: curIdx,
|
|
357
|
+
target: e.target, helper: e.helper, droppedElement: this.target, scopeName: this.scope, handled: handled
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
remove(dropInst.placeHolderElement);
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
dropInst = this.getSortableInstance(e.target);
|
|
364
|
+
// eslint-disable-next-line prefer-const
|
|
365
|
+
curIdx = dropInst.element.childElementCount;
|
|
366
|
+
prevIdx = this.getIndex(this.target);
|
|
367
|
+
if (dropInst.element === e.target || (!isPlaceHolderPresent && this.curTarget === this.target)) {
|
|
368
|
+
const beforeDropArgs: DropEventArgs = {
|
|
369
|
+
previousIndex: prevIdx, currentIndex: this.curTarget === this.target ? prevIdx : curIdx,
|
|
370
|
+
target: e.target, droppedElement: this.target, helper: e.helper, cancel: false
|
|
371
|
+
};
|
|
372
|
+
this.trigger('beforeDrop', beforeDropArgs, (observedArgs: DropEventArgs) => {
|
|
373
|
+
if ((dropInst.element === e.target || e.target.className.indexOf('e-list-nrt') > -1 || e.target.className.indexOf('e-list-nr-template') > -1
|
|
374
|
+
|| e.target.closest('.e-list-nr-template')) && !observedArgs.cancel) {
|
|
375
|
+
this.updateItemClass(dropInst);
|
|
376
|
+
dropInst.element.appendChild(this.target);
|
|
377
|
+
this.trigger('drop', {
|
|
378
|
+
event: e.event, element: dropInst.element, previousIndex: prevIdx, currentIndex: curIdx,
|
|
379
|
+
target: e.target, helper: e.helper, droppedElement: this.target, scopeName: this.scope
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
this.target.classList.remove('e-grabbed');
|
|
385
|
+
this.target = null;
|
|
386
|
+
this.curTarget = null;
|
|
387
|
+
remove(e.helper);
|
|
388
|
+
(getComponent(this.element, 'draggable') as Draggable).intDestroy(e.event);
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* It is used to sort array of elements from source element to destination element.
|
|
392
|
+
*
|
|
393
|
+
* @param destination - Defines the destination element to which the sortable elements needs to be appended.
|
|
394
|
+
*
|
|
395
|
+
* If it is null, then the Sortable library element will be considered as destination.
|
|
396
|
+
* @param targetIndexes - Specifies the sortable elements indexes which needs to be sorted.
|
|
397
|
+
* @param insertBefore - Specifies the index before which the sortable elements needs to be appended.
|
|
398
|
+
* If it is null, elements will be appended as last child.
|
|
399
|
+
* @function moveTo
|
|
400
|
+
* @returns {void}
|
|
401
|
+
*/
|
|
402
|
+
|
|
403
|
+
public moveTo(destination?: HTMLElement, targetIndexes?: number[], insertBefore?: number): void {
|
|
404
|
+
moveTo(this.element, destination, targetIndexes, insertBefore);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* It is used to destroy the Sortable library.
|
|
409
|
+
*/
|
|
410
|
+
|
|
411
|
+
public destroy(): void {
|
|
412
|
+
this.unwireEvents();
|
|
413
|
+
if (this.itemClass === 'e-sort-item') { this.itemClass = null; this.dataBind(); }
|
|
414
|
+
(getComponent(this.element, Draggable) as Draggable).destroy();
|
|
415
|
+
super.destroy();
|
|
416
|
+
}
|
|
417
|
+
public getModuleName(): string {
|
|
418
|
+
return 'sortable';
|
|
419
|
+
}
|
|
420
|
+
public onPropertyChanged(newProp: SortableModel, oldProp: SortableModel): void {
|
|
421
|
+
for (const prop of Object.keys(newProp)) {
|
|
422
|
+
switch (prop) {
|
|
423
|
+
case 'itemClass':
|
|
424
|
+
[].slice.call(this.element.children).forEach((element: HTMLElement): void => {
|
|
425
|
+
if (element.classList.contains(oldProp.itemClass)) {
|
|
426
|
+
element.classList.remove(oldProp.itemClass);
|
|
427
|
+
}
|
|
428
|
+
if (newProp.itemClass) {
|
|
429
|
+
element.classList.add(newProp.itemClass);
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
break;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* It is used to sort array of elements from source element to destination element.
|
|
440
|
+
*
|
|
441
|
+
* @private
|
|
442
|
+
*/
|
|
443
|
+
|
|
444
|
+
export function moveTo(from: HTMLElement, to?: HTMLElement, targetIndexes?: number[], insertBefore?: number): void {
|
|
445
|
+
let targetElements: Element[] = [];
|
|
446
|
+
if (!to) { to = from; }
|
|
447
|
+
if (targetIndexes && targetIndexes.length) {
|
|
448
|
+
targetIndexes.forEach((index: number): void => {
|
|
449
|
+
targetElements.push(from.children[index as number]);
|
|
450
|
+
});
|
|
451
|
+
} else {
|
|
452
|
+
targetElements = [].slice.call(from.children);
|
|
453
|
+
}
|
|
454
|
+
if (isNullOrUndefined(insertBefore)) {
|
|
455
|
+
targetElements.forEach((target: Element): void => {
|
|
456
|
+
to.appendChild(target);
|
|
457
|
+
});
|
|
458
|
+
} else {
|
|
459
|
+
const insertElement: HTMLElement = to.children[insertBefore as number] as HTMLElement;
|
|
460
|
+
targetElements.forEach((target: Element): void => {
|
|
461
|
+
to.insertBefore(target, insertElement);
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* An interface that holds item drop event arguments
|
|
468
|
+
*/
|
|
469
|
+
export interface DropEventArgs {
|
|
470
|
+
previousIndex: number;
|
|
471
|
+
currentIndex: number;
|
|
472
|
+
droppedElement: Element;
|
|
473
|
+
target: Element;
|
|
474
|
+
helper: Element;
|
|
475
|
+
cancel?: boolean;
|
|
476
|
+
handled?: boolean;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* An interface that holds item before drag event arguments
|
|
481
|
+
*/
|
|
482
|
+
export interface BeforeDragEventArgs {
|
|
483
|
+
cancel?: boolean;
|
|
484
|
+
target: Element;
|
|
485
|
+
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_from": "@syncfusion/ej2-lists@*",
|
|
3
|
-
"_id": "@syncfusion/ej2-lists@22.
|
|
3
|
+
"_id": "@syncfusion/ej2-lists@22.1.1",
|
|
4
4
|
"_inBundle": false,
|
|
5
|
-
"_integrity": "sha512-
|
|
5
|
+
"_integrity": "sha512-jBtRRqzsH1qGVl/Y8NGkBIY04wOvQy2grGsN748ycD+JdOddlO14d9S0QA1CemMOcuBm1vLMEqi1gR1XWpFdVw==",
|
|
6
6
|
"_location": "/@syncfusion/ej2-lists",
|
|
7
7
|
"_phantomChildren": {},
|
|
8
8
|
"_requested": {
|
|
@@ -35,18 +35,18 @@
|
|
|
35
35
|
"/@syncfusion/ej2-schedule",
|
|
36
36
|
"/@syncfusion/ej2-vue-lists"
|
|
37
37
|
],
|
|
38
|
-
"_resolved": "https://nexus.syncfusion.com/repository/ej2-hotfix-new/@syncfusion/ej2-lists/-/ej2-lists-22.
|
|
39
|
-
"_shasum": "
|
|
38
|
+
"_resolved": "https://nexus.syncfusion.com/repository/ej2-hotfix-new/@syncfusion/ej2-lists/-/ej2-lists-22.1.1.tgz",
|
|
39
|
+
"_shasum": "8e9b20d503a0da30682fe271bdb2d35a3923a978",
|
|
40
40
|
"_spec": "@syncfusion/ej2-lists@*",
|
|
41
|
-
"_where": "/jenkins/workspace/elease-
|
|
41
|
+
"_where": "/jenkins/workspace/elease-automation_release_23.1.1/packages/included",
|
|
42
42
|
"author": {
|
|
43
43
|
"name": "Syncfusion Inc."
|
|
44
44
|
},
|
|
45
45
|
"bundleDependencies": false,
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@syncfusion/ej2-base": "~
|
|
48
|
-
"@syncfusion/ej2-buttons": "~
|
|
49
|
-
"@syncfusion/ej2-data": "~
|
|
47
|
+
"@syncfusion/ej2-base": "~23.1.41",
|
|
48
|
+
"@syncfusion/ej2-buttons": "~23.1.42",
|
|
49
|
+
"@syncfusion/ej2-data": "~23.1.36"
|
|
50
50
|
},
|
|
51
51
|
"deprecated": false,
|
|
52
52
|
"description": "The listview control allows you to select an item or multiple items from a list-like interface and represents the data in interactive hierarchical structure across different layouts or views.",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"url": "https://github.com/syncfusion/ej2-javascript-ui-controls/tree/master/controls/lists"
|
|
87
87
|
},
|
|
88
88
|
"typings": "index.d.ts",
|
|
89
|
-
"version": "
|
|
89
|
+
"version": "23.1.42",
|
|
90
90
|
"sideEffects": false,
|
|
91
91
|
"homepage": "https://www.syncfusion.com/javascript-ui-controls"
|
|
92
92
|
}
|
|
@@ -319,20 +319,14 @@ export interface ListBaseOptions {
|
|
|
319
319
|
sortOrder?: SortOrder;
|
|
320
320
|
/**
|
|
321
321
|
* Specifies the item template
|
|
322
|
-
*
|
|
323
|
-
* @aspType string
|
|
324
322
|
*/
|
|
325
323
|
template?: string | Function;
|
|
326
324
|
/**
|
|
327
325
|
* Specifies the group header template
|
|
328
|
-
*
|
|
329
|
-
* @aspType string
|
|
330
326
|
*/
|
|
331
327
|
groupTemplate?: string | Function;
|
|
332
328
|
/**
|
|
333
329
|
* Specifies the ListView header template
|
|
334
|
-
*
|
|
335
|
-
* @aspType string
|
|
336
330
|
*/
|
|
337
331
|
headerTemplate?: string | Function;
|
|
338
332
|
/**
|
package/src/common/list-base.js
CHANGED
|
@@ -280,7 +280,7 @@ export var ListBase;
|
|
|
280
280
|
li = generateLI(createElement, curItem, fieldData, fields, curOpt.itemClass, options, componentInstance);
|
|
281
281
|
li.classList.add(cssClass.level + '-' + ariaAttributes.level);
|
|
282
282
|
li.setAttribute('aria-level', ariaAttributes.level.toString());
|
|
283
|
-
if (ariaAttributes.groupItemRole == 'presentation') {
|
|
283
|
+
if (ariaAttributes.groupItemRole == 'presentation' || ariaAttributes.itemRole == 'presentation') {
|
|
284
284
|
li.removeAttribute('aria-level');
|
|
285
285
|
}
|
|
286
286
|
anchorElement = li.querySelector('.' + cssClass.anchorWrap);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Virtualization } from './virtualization';import { merge, formatUnit, isNullOrUndefined, append, detach, ModuleDeclaration, extend } from '@syncfusion/ej2-base';import { attributes, addClass, removeClass, prepend, closest, remove } from '@syncfusion/ej2-base';import { Component, EventHandler, BaseEventArgs, Property, Complex, Event } from '@syncfusion/ej2-base';import { NotifyPropertyChanges, INotifyPropertyChanged, ChildProperty } from '@syncfusion/ej2-base';import { KeyboardEventArgs, EmitType, compile, SanitizeHtmlHelper } from '@syncfusion/ej2-base';import { Animation, AnimationOptions, Effect, rippleEffect, Touch, SwipeEventArgs } from '@syncfusion/ej2-base';import { DataManager, Query } from '@syncfusion/ej2-data';import { createCheckBox } from '@syncfusion/ej2-buttons';import { ListBase, ListBaseOptions, SortOrder, getFieldValues, FieldsMapping } from '../common/list-base';
|
|
1
|
+
import { Virtualization } from './virtualization';import { merge, formatUnit, isNullOrUndefined, append, detach, ModuleDeclaration, extend } from '@syncfusion/ej2-base';import { attributes, addClass, removeClass, prepend, closest, remove } from '@syncfusion/ej2-base';import { Component, EventHandler, BaseEventArgs, Property, Complex, Event } from '@syncfusion/ej2-base';import { NotifyPropertyChanges, INotifyPropertyChanged, ChildProperty } from '@syncfusion/ej2-base';import { KeyboardEventArgs, EmitType, compile, SanitizeHtmlHelper } from '@syncfusion/ej2-base';import { Animation, AnimationOptions, Effect, rippleEffect, Touch, SwipeEventArgs, animationMode } from '@syncfusion/ej2-base';import { DataManager, Query } from '@syncfusion/ej2-data';import { createCheckBox } from '@syncfusion/ej2-buttons';import { ListBase, ListBaseOptions, SortOrder, getFieldValues, FieldsMapping } from '../common/list-base';
|
|
2
2
|
import {AnimationSettings,checkBoxPosition,SelectEventArgs} from "./list-view";
|
|
3
3
|
import {ComponentModel} from '@syncfusion/ej2-base';
|
|
4
4
|
|
|
@@ -254,9 +254,9 @@ export interface ListViewModel extends ComponentModel{
|
|
|
254
254
|
* @angularType string | object
|
|
255
255
|
* @reactType string | function | JSX.Element
|
|
256
256
|
* @vueType string | function
|
|
257
|
-
|
|
257
|
+
* @aspType string
|
|
258
258
|
*/
|
|
259
|
-
template?: string;
|
|
259
|
+
template?: string | Function;
|
|
260
260
|
|
|
261
261
|
/**
|
|
262
262
|
* The ListView has an option to custom design the ListView header title with the help of `headerTemplate` property.
|
|
@@ -267,9 +267,9 @@ export interface ListViewModel extends ComponentModel{
|
|
|
267
267
|
* @angularType string | object
|
|
268
268
|
* @reactType string | function | JSX.Element
|
|
269
269
|
* @vueType string | function
|
|
270
|
-
|
|
270
|
+
* @aspType string
|
|
271
271
|
*/
|
|
272
|
-
headerTemplate?: string;
|
|
272
|
+
headerTemplate?: string | Function;
|
|
273
273
|
|
|
274
274
|
/**
|
|
275
275
|
* The ListView has an option to custom design the group header title with the help of `groupTemplate` property.
|
|
@@ -280,9 +280,9 @@ export interface ListViewModel extends ComponentModel{
|
|
|
280
280
|
* @angularType string | object
|
|
281
281
|
* @reactType string | function | JSX.Element
|
|
282
282
|
* @vueType string | function
|
|
283
|
-
|
|
283
|
+
* @aspType string
|
|
284
284
|
*/
|
|
285
|
-
groupTemplate?: string;
|
|
285
|
+
groupTemplate?: string | Function;
|
|
286
286
|
|
|
287
287
|
/**
|
|
288
288
|
* Triggers when we select the list item in the component.
|
|
@@ -331,9 +331,9 @@ export declare class ListView extends Component<HTMLElement> implements INotifyP
|
|
|
331
331
|
* @angularType string | object
|
|
332
332
|
* @reactType string | function | JSX.Element
|
|
333
333
|
* @vueType string | function
|
|
334
|
-
|
|
334
|
+
* @aspType string
|
|
335
335
|
*/
|
|
336
|
-
template: string;
|
|
336
|
+
template: string | Function;
|
|
337
337
|
/**
|
|
338
338
|
* The ListView has an option to custom design the ListView header title with the help of `headerTemplate` property.
|
|
339
339
|
*
|
|
@@ -343,9 +343,9 @@ export declare class ListView extends Component<HTMLElement> implements INotifyP
|
|
|
343
343
|
* @angularType string | object
|
|
344
344
|
* @reactType string | function | JSX.Element
|
|
345
345
|
* @vueType string | function
|
|
346
|
-
|
|
346
|
+
* @aspType string
|
|
347
347
|
*/
|
|
348
|
-
headerTemplate: string;
|
|
348
|
+
headerTemplate: string | Function;
|
|
349
349
|
/**
|
|
350
350
|
* The ListView has an option to custom design the group header title with the help of `groupTemplate` property.
|
|
351
351
|
*
|
|
@@ -355,9 +355,9 @@ export declare class ListView extends Component<HTMLElement> implements INotifyP
|
|
|
355
355
|
* @angularType string | object
|
|
356
356
|
* @reactType string | function | JSX.Element
|
|
357
357
|
* @vueType string | function
|
|
358
|
-
|
|
358
|
+
* @aspType string
|
|
359
359
|
*/
|
|
360
|
-
groupTemplate: string;
|
|
360
|
+
groupTemplate: string | Function;
|
|
361
361
|
/**
|
|
362
362
|
* Triggers when we select the list item in the component.
|
|
363
363
|
*
|