Angular TreeView Drag and Drop Events

Created: 23 Jan 2019

When you drag one or multiple items within the IntegralUI TreeView for Angular, drag and drop events are fired, which you can handle in your code. An event can fire when dragged item enters or leaves the tree view space, when it is dragged over some other item or when item drops. Although the default drag and drop functionality is sufficient im most cases, you have an option to alter it by handling these events. You can find below a detailed information about each event.

TreeView component is part of IntegralUI Web
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

In the demo, you are free to drag and drop items one by one within the TreeView. When item is dragged over a different item, you can drop it above, below or as a child of the target item. In this particular example, if you drag an item over the "Download" item, you can only drop it as a child, the above and below positions are disabled within the drag over event handler. To see how, read further below.

To see which event is fired and in what order, the list on right logs all drag and drop events that are fired, where last event is placed on top. The list shows event name, information about the source and target item, position and how many times event fires.

Events in Angular TreeView with Drag and Drop

Here is a list of available drag and drop events:

  • dragEnter - occurs when item is dragged over TreeView space for the first time
  • dragDrop - occurs when item drops within the TreeView
  • dragLeave - occurs when dragged item leaves the TreeView space
  • dragOver - occurs when item is dragged over other items and TreeView space

By handling one or all of these events, you can place different conditions and change the overall drag drop behavior. But first you need to check what data is included with each event.

What Data is Included in Drag and Drop Event

In general, the event data is the same for all events with some exceptions. For example, dragEnter and dragLeave events don't have an option for cancellation. Here is a list of all fields available within the event data:

  • action - can be move or copy
  • cancel - when set to true the event is cancelled
  • dragItem - a single or multiple items that are dragged
  • dropPos - position at which item(s) can drop
    • 0 - middle space of target item, means item drops as a child
    • 1 - top space of target item, means item drops above it at same level
    • 2 - botom space of target item, means item drops below it at same level
    • -1 - tree view space, item drops at the end of the tree hierarachy
  • event - reference to standard HTML5 drag and drop event data
  • isDropAllowed - determines whether item is allowed to drop
  • mousePos - the position of the mouse in page coordinates
  • sourceCtrl - a reference to the source component from where dragging starts
  • targetCtrl - a reference to the target component where item drops
  • targetItem - specifies the target item over which the item can drop

As you can see, there is enough data that you can use it in your code to create different conditions and change the drag drop in part or in whole.

Note The event data is not limited to the Tree View only, sourceCtrl and targetCtrl can hold a references to other components like Grid, ListBox, ListView, and TreeGrid or it can even be a custom angular component. As long as the component uses IntegralUI Drag Drop Service, you can share data from different components.

Related: Drag and Drop between Custom Angular Components

How to Handle Drag Enter and Drag Leave Events in TreeView for Angular

The dragEnter and dragLeave events fire only once, the first one when dragged item enters the tree view space for the first time and the second event when it leaves.

You can use these events to add some conditions like:

  • validate whether the targetCtrl from the event data is a valid component or not in cases when you have multiple tree views
  • change the TreeView style so that its border appears in different color on enter
  • change the TreeView allowDrop property to false, and suspend any drops over its space
  • . . .

In case of changing the tree view appearance, when you start to drag an item, change the TreeView border color to red, and when you leave its space while dragging an item, return it back to normal. For this purpose you can use the ngClass directive in TreeView HTML settings, and activate this class on drag enter.

treeDragEnter(e: any){
    this.isDragEnter = true;
}

treeDragLeave(e: any){
    this.isDragEnter = false;
}
                            
<div class="app-block" #application>
    <iui-treeview [items]="items" [appRef]="applicationRef" [allowDrag]="true" [controlStyle]="ctrlStyle" [allowAnimation]="true" (dragEnter)="treeDragEnter($event)" (dragLeave)="treeDragLeave($event)" (dragOver)="treeDragOver($event)" (dragDrop)="treeDragDrop($event)" [ngClass]="{ 'trw-dd-evnt-hover': isDragEnter }" #treeview>
        <ng-template let-item>
            <span [ngClass]="item.icon"></span>
            <span>{{item.text}}</span>
        </ng-template>
    </iui-treeview>
    <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==true" class="app-event-cancelled">cancelled</span></div>
            </li>
        </ul>
    </div>
</div>
                            
.trw-dd-evnt-hover > div {
    border: 2px solid #c60d0d;
}
                            

These are only few examples on when you can use these events, but you can add any other that is more suitable for your application.

How to Change Action on Drag Over and Drop

We mentioned in beginning that you can drop and item above, below and as a child or target item. In this example, you can learn how to override the default behavior and on drag over, if the drop position is 1 (above) or 2 (below) the "Downloads" item, cancel the operation. This will hide the drop marker and show a NO DROP icon:

treeDragOver(e: any){
    if (e.dropPos != 0 && e.targetItem && e.targetItem.text == 'Downloads')
        e.cancel = true;
}
                            
<div class="app-block" #application>
    <iui-treeview [items]="items" [appRef]="applicationRef" [allowDrag]="true" [controlStyle]="ctrlStyle" [allowAnimation]="true" (dragEnter)="treeDragEnter($event)" (dragLeave)="treeDragLeave($event)" (dragOver)="treeDragOver($event)" (dragDrop)="treeDragDrop($event)" [ngClass]="{ 'trw-dd-evnt-hover': isDragEnter }" #treeview>
        <ng-template let-item>
            <span [ngClass]="item.icon"></span>
            <span>{{item.text}}</span>
        </ng-template>
    </iui-treeview>
    <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==true" class="app-event-cancelled">cancelled</span></div>
            </li>
        </ul>
    </div>
</div>
                            

If you want to allow drop in position 1 and 2, but still item to drop as a child, you can handle the drop event like this:

  1. Add a handler for dragDrop event
  2. Cancel the default behavior if the target is the "Downloads" item
  3. Remove the dragged item from the source component
  4. Add it as a child to the target item
treeDragDrop(e: any){
    if (e.dropPos != 0 && e.targetItem && e.targetItem.text == 'Downloads'){
        e.cancel = true;

        // Remove the item from the source component
        e.sourceCtrl.removeItem(e.dragItem);

        // Add the item as a child to target item
        e.targetCtrl.addItem(e.dragItem, e.targetItem);
    }
}
                            
<div class="app-block" #application>
    <iui-treeview [items]="items" [appRef]="applicationRef" [allowDrag]="true" [controlStyle]="ctrlStyle" [allowAnimation]="true" (dragEnter)="treeDragEnter($event)" (dragLeave)="treeDragLeave($event)" (dragOver)="treeDragOver($event)" (dragDrop)="treeDragDrop($event)" [ngClass]="{ 'trw-dd-evnt-hover': isDragEnter }" #treeview>
        <ng-template let-item>
            <span [ngClass]="item.icon"></span>
            <span>{{item.text}}</span>
        </ng-template>
    </iui-treeview>
    <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==true" class="app-event-cancelled">cancelled</span></div>
            </li>
        </ul>
    </div>
</div>
                            

Note In this case you don't need to handle the dragOver event.

You can add other kinds of conditions, based on the event data. For example, you can use the drop position, whether action is drag move or drag copy, single or multiple items are dragged etc.

How to Cancel an Event

You can only cancel the dragOver and dragDrop events. It is simple, add a handler function to these events and set the cancel field of the event data to true.

treeDragOver(e: any){
    e.cancel = true;
}

treeDragDrop(e: any){
    e.cancel = true;
}
                            

However, this will prevent any item drops. In real scenarios, you may need to set some condition and cancel the drag and drop when fulfilled, like in previous example.

In most cases, you may need to cancel the default behavior, when you want to change the item data prior it drops, or when you need to first validate whether the server data is updated prior committing the change in the client.

Conclusion

Drag and Drop in the IntegralUI TreeView component for Angular is accompanied by few events that may occur when on dragged item enters, it is over, drops or leaves the tree view space. By handling these events in your code, you can add custom conditions and change the default functionality. In some cases, when required you can cancel the event and prevent item from dropping.

The TreeView component is part of IntegralUI Web.

Newsletter


Sign-up to our newsletter and you will receive news on upcoming events, latest articles, samples and special offers.
Name: Email: *
*By checking this box, I agree to receive a newsletter from Lidor Systems in accordance with the Privacy Policy. I understand that I can unsubscribe from these communications at any time by clicking on the unsubscribe link in all emails.