a suite of UI Components for development of web apps
If you have any questions, don't hesitate to contact us at support@lidorsystems.com
Advanced User Interface Controls and Components
Created: 21 Jan 2019
Whenever an item is dragged within the ListBox component, based on user action several drag and drop events can occur. You can handle these events in your code and provide additional conditions that may alter the default drag and drop functionality. In this article you will learn about all drag drop events that are supported and how to handle them in different situations.
If you have any questions, don't hesitate to contact us at support@lidorsystems.com
As item is dragged in the ListBox, the list on the right side will display event when fired. As explained in sections below, when item is dragged over target item "Gladiator", it can only drop below it. In other cases you can freely reorder items.
The list on the right displays events that fires during drag drop. You can see the event name, dragged item, target item and drop position. If the event fires multiple times subsequently, it can happen with drag over event, a counter will appear left from the event name stating how many times that event fired. In addition, if an event is cancelled, the event log will add 'cancelled' in red, next to the event message.
During item drag and drop operation, several events are fired that you can handle in your code. Here is the list of supported events:
By adding handlers for these events in your code, you can intercept the drag drop operation and change its course using custom conditions.
The drag and drop event data contains information that you can use in your code to customize the drag drop operations in whole and create the best solution for your application requirements. Depending on the event, a different data is included. In general, here is a list of data fields available:
Whenever item is dragged over another item or a different ListBox component, the dragOver event will fire. You can create a handler function for this event, where you can set custom conditions that will allow or not drops of dragged item.
For example, let's say that if the target item is "Gladiator" and you want the dragged item to only drop below it. In this case, at first you need to check whether there is a target item and the current drop position:
listDragOver(e: any){
if (e.dropPos == 1 && e.targetItem && e.targetItem.text == 'Gladiator')
e.cancel = true;
}
<div class="app-block" #application>
<iui-listbox [appRef]="applicationRef" [items]="items" [controlStyle]="lBoxStyle" [allowDrag]="true" (dragEnter)="listDragEnter($event)" (dragOver)="listDragOver($event)" (dragLeave)="listDragLeave($event)" (dragDrop)="listDragDrop($event)" #listbox>
<iui-listitem *ngFor="let item of items" [controlStyle]="lboxItemStyle" [allowAnimation]="true">
<div class="lbox-dd-evnt-item-content">
<span class="lbox-dd-evnt-icons {{item.icon}}"></span>
<span class="lbox-dd-evnt-title">{{item.text}}</span>
</div>
</iui-listitem>
</iui-listbox>
<div class="app-event-block">
<button (click)="clearEventLog()">Clear</button>
<p>Event log:</p>
<ul class="app-event-log">
<li *ngFor="let ev of eventLog">
<div><span *ngIf="ev.count" class="app-event-count">{{ev.count}}</span> <span class="app-event-name">{{ev.name}}</span></div>
<div>{{ev.info}}<span class="app-event-value"> at position: {{ev.position}}</span> <span *ngIf="ev.cancelled" class="app-event-cancelled">cancelled</span></div>
</li>
</ul>
</div>
</div>
As you can see from code, if the drop position is 1, it means the dragged item is about to drop above the target item, which we don't want. To prevent it, just set the cancel field to true.
Related: How to Move Multiple Items with Drag and Drop
The dragged item can still drop over this target item, but only if it is over the lower part of the target space, that is with drop position 2 which means below the target item.
Note This is another way to prevent drops over target items, instead of using the allowDrop field of the item object.
When item is dropped the dragDrop event will fire. This event concludes the drag and drop operation and it's called once the drop is completed. You can still cancel this event and prevent item from dropping, if some action on your side is not yet completed.
Instead of preventing item to drop above the target item within the dragOver event handler (see above), you can do it in dragDrop event handler. In this case, you can check the drop position and if it is 1, cancel the event and proceed with placing the dragged item below the target item.
listDragDrop(e: any){
if (e.dropPos == 1 && e.targetItem){
e.cancel = true;
e.targetCtrl.insertItemAfter(e.dragItem, e.targetItem);
}
}
<div class="app-block" #application>
<iui-listbox [appRef]="applicationRef" [items]="items" [controlStyle]="lBoxStyle" [allowDrag]="true" (dragEnter)="listDragEnter($event)" (dragOver)="listDragOver($event)" (dragLeave)="listDragLeave($event)" (dragDrop)="listDragDrop($event)" #listbox>
<iui-listitem *ngFor="let item of items" [controlStyle]="lboxItemStyle" [allowAnimation]="true">
<div class="lbox-dd-evnt-item-content">
<span class="lbox-dd-evnt-icons {{item.icon}}"></span>
<span class="lbox-dd-evnt-title">{{item.text}}</span>
</div>
</iui-listitem>
</iui-listbox>
<div class="app-event-block">
<button (click)="clearEventLog()">Clear</button>
<p>Event log:</p>
<ul class="app-event-log">
<li *ngFor="let ev of eventLog">
<div><span *ngIf="ev.count" class="app-event-count">{{ev.count}}</span> <span class="app-event-name">{{ev.name}}</span></div>
<div>{{ev.info}}<span class="app-event-value"> at position: {{ev.position}}</span> <span *ngIf="ev.cancelled" class="app-event-cancelled">cancelled</span></div>
</li>
</ul>
</div>
</div>
In this way, you can intercept the drag and drop operation and in both cases of drop position (above or below), the dragged item will be placed always below the target item.
In similar way like explained above cancelling item drops above the target item, you can cancel the drag and drop in all cases, for the specific item or for all items.
For example, if you set the cancel field to false, without any conditions the item can't drop. In similar way like if the allowDrop property for ListBox component is set to false.
The more suitable case for cancelling a drop event is to set it if some action required was not yet completed, like data loading is not yet finished. In addition, it is useful to cancel the item drop in whole when you want to change the item data on your own.
listDragDrop(e: any){
e.cancel = true;
if (e.dragItem){
// Remove the item from the source component
e.sourceCtrl.removeItem(e.dragItem);
// Change the item text
e.dragItem.text = 'New Item';
// Add the item to target component at location, depending on drop position
switch (e.dropPos){
case 1: // Above the target item
e.targetCtrl.insertItemBefore(e.dragItem, e.targetItem);
break;
case 2: // Below the target item
e.targetCtrl.insertItemAfter(e.dragItem, e.targetItem);
break;
default: // At the end of the list
e.targetCtrl.addItem(e.dragItem);
break;
}
e.targetCtrl.updateLayout();
}
}
Related: How to Copy Item with Drag and Drop
For example, cancel the event and change the item text to 'New Item'. Therefore, any item that drops will have the same name. You can proceed with custom actions to add the dropped item to the new component at location specified by the drop position.
Note If the drag and drop operation is set to 'move', you also need to remove the dropped item from the source component.
IntegralUI ListBox component for Angular accompanies few drag and drop events. By handling these events in your code, you can change the item drag and drop in part or completely using custom conditions. In some cases, using the event data you may even cancel the whole drag and drop operation.
The ListBox component is part of IntegralUI Web.