LIDOR SYSTEMS

Advanced User Interface Controls and Components

Handling Drag Drop Events in TreeView for AngularJS

Created: 27 August 2014

Updated: 13 January 2015

TreeView directive has a built-in HTML5 drag-drop functionality which allows you to drag and drop items within the same tree view, other tree views or to some other component. Each drag drop operation is accompanied with several events can be handled in your code. The following demonstration shows how to reorder items using drag drop and how to transfer items from one TreeView to another.


TreeView directive is part of IntegralUI Studio for Web
a suite of UI Components for development of web apps

Similar: Drag Drop Items Between Two TreeViews in Angular 2

By default drag drop operations are disabled. TreeView directive has two properties which controls whether drag drop is allowed or not:

To allow an item to be dragged the allowDrag property must have its value set to true. In similar fashion allowDrop property when set to true, allows items to be dropped in the TreeView. This is very useful in case when for example you want only to allow dragging but not reordering of items. To see more how looks in action, uncheck the check boxes in above demonstration.

angular

.module("appModule", ["integralui"])

.controller("appCtrl", ["$scope", "IntegralUITreeViewService", function($scope, $treeService){

$scope.treeData = [

{

text: "Books",

icon: "icons books",

items: [

{

text: "Business",

expanded: false,

icon: "icons business",

items: [

{ text: "Economics" },

{ text: "Investing", icon: "icons chart" },

{ text: "Management" }

]

},

{ text: "Health", icon: "icons health" },

{ text: "Literature" },

{

text: "Science",

expanded: false,

icon: "icons science",

items: [

{ text: "Astronomy" },

{ text: "Mathematics" },

{ text: "Evolution" },

{ text: "Nature" }

]

}

]

},

{

text: "Electronics",

expanded: false,

items: [

{ text: "Camera" },

{ text: "Cell Phones" },

{ text: "Video Game Consoles" }

]

},

{

text: "Music",

icon: "icons music",

items: [

{ text: "Blues" },

{ text: "Classic Rock" },

{ text: "Pop" },

{ text: "Jazz" }

]

},

{

text: "Sports",

expanded: false,

items: [

{ text: "Baseball" },

{ text: "Martial Arts" },

{ text: "Running" },

{

text: "Tennis",

expanded: false,

items: [

{ text: "Accessories" },

{ text: "Balls" },

{ text: "Racquets" }

]

}

]

},

];

 

$scope.treeData2 = [];

$scope.allowDrag = true;

$scope.allowDrop = true;

$scope.allowDrag2 = true;

$scope.allowDrop2 = true;

 

$scope.toggleAllowDrag = function(){

$scope.allowDrag = !$scope.allowDrag;

}

 

$scope.toggleAllowDrop = function(){

$scope.allowDrop = !$scope.allowDrop;

}

 

$scope.toggleAllowDrag2 = function(){

$scope.allowDrag2 = !$scope.allowDrag2;

}

 

$scope.toggleAllowDrop2 = function(){

$scope.allowDrop2 = !$scope.allowDrop2;

}

}]);

<!DOCTYPE html>

<html>

<head>

<link rel="stylesheet" href="css/integralui.treeview.css" />

<link rel="stylesheet" href="css/themes/theme-blue.css" />

<script type="text/javascript" src="external/angular.min.js"></script>

<script type="text/javascript" src="js/angular.integralui.treeview.min.js"></script>

</head>

<body>

<div ng-app="appModule" ng-controller="appCtrl">

<iui-treeview items="treeData" allow-drag="allowDrag" allow-drop="allowDrop"></iui-treeview>

<iui-treeview items="treeData2" allow-drag="allowDrag2" allow-drop="allowDrop2"></iui-treeview>

</div>

</body>

</html>

.icons

{

background-image: url(icons.png);

background-repeat: no-repeat;

display: inline-block;

overflow: hidden;

padding: 0;

margin: 0 1px 0 0;

width: 16px;

height: 16px;

}

.empty

{

background-position: 0px 0px;

}

.health

{

background-position: -128px -48px;

}

.business

{

background-position: -192px -48px;

}

.science

{

background-position: 0 -64px;

}

.books

{

background-position: -16px -64px;

}

.music

{

background-position: -32px -64px;

}

.chart

{

background-position: -96px -64px;

}

To start a drag drop of an item, you need to press the left mouse button and move the mouse cursor a little bit in any direction. An image which is a clone of dragged item will be displayed, stating that drag drop operation has started. While moving the dragged item over other items in TreeView, the drop marker will appear stating the position at which dragged item will be placed. If there is no target item, only the image is shown, and if the dragged item is dropped, it will be added as a root item to the targeted TreeView.

Related: Drag Drop Between TreeView and TreeGrid AngularJS

Whenever an item is dragged, dragOver event is fired. The following objects are carried with this event:

  • dragItem - the item object that is dragged
  • targetItem - the item object over which mouse cursor is currently positioned
  • isDropAllowed - a Boolean value stating whether dragged item is allowed to drop
  • dropPos - the position where dragged item will be placed. Here is a list of dropPos values:
    • -1, item will be placed to the end of tree hierarchy as a root item
    • 0, item on drop will become child of target item
    • 1, item will be placed above target item
    • 2, item will be placed below target item
  • mousePos - the position of mouse cursor in page coordinates

By handling this event you can get the position where dragged item will be placed and determine whether you want to place the dragged item at that position or not. Here how a handler to dragOver event looks like in code:

$scope.onDragOver = function(e){

if (e.targetItem)

console.log("dragOver event was fired when " + e.dragItem.text + " is dragged over " + e.targetItem.text);

else

console.log("dragOver event was fired when " + e.dragItem.text + " is dragged over TreeView space");

}

<iui-treeview items="treeData" allow-drag="allowDrag" allow-drop="allowDrop" drag-over="onDragOver(e)"></iui-treeview>

At the end when left mouse button is released, the item is dropped and dragDrop event is fired. The same objects as in dragOver event are carried with this event, except that the name 'dragItem' is replaced by 'dropItem'. By handling this event you can determine whether item can be dropped over designated position and prevent item from dropping if some condition is not met. For example in our demonstration whenever an item is dropped over target item with its text set to 'Health', drop is cancelled:

$scope.onDragDrop = function(e){

if (e.targetItem && e.targetItem.text === 'Health')

return false;

}

<iui-treeview items="treeData" allow-drag="allowDrag" allow-drop="allowDrop" drag-drop="onDragDrop(e)"></iui-treeview>

Also by default, parent items cannot drop over their child items. This is prevented from built-in code.

Although above demonstration shows only drag and drop of items within the same TreeView and also between two TreeViews, you can drag drop an item to any other element in the DOM. You only need to handle the required HTML5 events. You can also drag drop an element from other components into the TreeView, but when element is dropped a tree item object will be automatically created with its text set to the text of dragged element. Of course in your code you can customize this, so whenever an item is dropped, you can create your own item object and add it to the TreeView.

Did you Like this Article?


Enter your e-mail address below and you will receive latest articles as well as news on upcoming events and special offers.