Drag and Drop in Angular 7 with Ng2-Dragula

Sri Harsha
7 min readApr 24, 2020
Photo by Tudor Baciu on Unsplash

Before we head into the post, I just want to say I am not fully competent in Angular and am still learning the in’s and out’s of angular 7. So if there are any mistakes or such, kindly do let me know so that I can learn where I went wrong and add it in the comments section of the post so that others who are learning from this can benefit from my mistakes.

This post is just a small peek into what I learned in angular for the drag and drop functionality.

So without further ado, Let's jump in!

What this post is about:

This post deals with the implementation of the Drag and Drop Functionality in Angular 7 using Ng2-Dragula by creating a basic To-Do List.

The Git Repo Link for the whole code -> https://github.com/Yalamarthi97/Angular-Drag-and-Drop-MediumRepo

What this post will be covering:

Installing Ng2-Dragula Module using npm install.

Importing the Dragula module into the project and implementing it.

Creating Elements in Angular which can be dragged and dropped around.

Code is at the end, so if you just want the code jump to the end but don’t forget to read the conclusion to get a quick glimpse on working of drag and drop using Ng2-Dragula

There is an official GitHub page for Ng2-Dragula which covers the basic concepts of the drag and drop module along with code snippets of their implementation for various functionalities.

Source: From Giphy by Robert E Blackmon

Installing Ng2-Dragula Module:

The Dragula module can be installed by running the following command in the root directory of the project.

Once the installation of the module is done, We can move onto the next step of importing the module in the App.Module.Ts file.

Importing the Dragula Module:

Step 1:

Before importing the Dragula module into the app.module.ts file there is an issue that has to be bypassed for the Dragula to work.

Without bypassing the above error it might generate the following error.

To bypass the error add the following line in the polyfills.ts file in the project directory.

(window as any).global = window;

Step 2: Importing the Dragula Module

Import DragulaModule from ‘ng2-dragula’ and then add the DragulaModule.forRoot() under imports in the app.module.ts file

//  All the other imports
import { DragulaModule } from 'ng2-dragula';
@NgModule({
declarations: [
AppComponent
],
imports: [
// Other imports
DragulaModule.forRoot() // Just this Line will do along with import
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Implementation of Ng2-Dragula Module

Making elements in the project draggable is as easy as adding a keyword, dragula = “xxxxx” in the Html tag of the element.

xxxxx → stands for any word or combination of characters, it can be something meaningful as “Draggable” or a mix and match of words like “Aseq1” or just a few numbers or special characters of any length.

Note: Just make sure the elements if present in different containers or divs should have the same dragula value for their elements to be draggable between the two containers or divs.

<h1>Done </h1>
<div class="hold" dragula="<A3"> //can be alphanumeric of any length
<div class="Done">Task 1 : Wash Clothes </div>
<div class="Done">Task 2 : Take out the trash! </div>
<div class="Done">Task 3 : Shop for essentials </div>
</div>
<h1>To do </h1>
<div class="hold" dragula="<A3">
<div class="ToDo">Task 4 : Cut the Vegetables for Cooking </div>
<div class="ToDo">Task 5 : Make Dinner </div>
<div class="ToDo">Task 6 : Make Bed </div>
</div>

The above code creates an outer div having the dragula value and other divs inside the outer div, since both the element’s ( Outer Divs ) dragula value are the same it enables the movement of elements from one to another.

The following code can be added to the above code to demonstrate the importance of dragula values being the same for drag-dropping elements between them.

<h1>Not Relevant</h1>
<div class="hold" dragula="CantMoveIntoAbove">
<div class="notRelevant">Task 10 : Build a dog house </div>
<div class="notRelevant">Task 11 : Go for a drive </div>
<div class="notRelevant">Task 12 : Fix a virtual meetup</div>
</div>

The Not Relevant Div has a different dragula value when compared to the other 2 divs, This prevents the elements under “No Relevant ” from being dragged and dropped in the other containers. But the elements will still be draggable inside the same div.

Additional Points to remember:

  1. It is not necessary to import or write any functions or code in the app.component.ts file for the drag and drop functionality to work if you are not going to implement other complicated functions using triggers and events like
  • Making the Dropped Element go back to its source when dropped outside the div/container
  • Instead of dragging and dropping the element, want a shadow clone of the element to be dropped in the target container/div. ( Similar to shadow clones in anime 😉)
  • Remove an item from the container when it is dragged and dropped outside the container.

The additional functions which can be achieved using Ng2-Dragula can be found here.

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Drag';
}

The above code snippet is the app.component.ts and you can notice there are no functions or constructors pertaining to Ng2- Dragula.

2. Not only text but even videos or images be dragged and dropped in the same div/container or to different div/container, just have to replace

<div> Some Text </div>

with other necessary tags like <img src> or <video src > and making sure they have the same dragula value for inter container drags.

<div> 
Necessary tags like <img src> </img src> or <video src> </video src> </div>
Example Code Snippet:
<div dragula="Anyvalue">
<img src="Source" >
</div>

Codes:

App.component.html

<h1>Done </h1>
<div class="hold" dragula="<A3">
<div class="Done">Task 1 : Wash Clothes </div>
<div class="Done">Task 2 : Take out the trash! </div>
<div class="Done">Task 3 : Shop for essentials </div>
</div>
<h1>To do </h1>
<div class="hold" dragula="<A3">
<div class="ToDo">Task 4 : Cut the Vegetables for Cooking </div>
<div class="ToDo">Task 5 : Make Dinner </div>
<div class="ToDo">Task 6 : Make Bed </div>
</div>
<!--
This comment can be removed to display another div element "Low Priority Tasks" which is also under the same dragula class I.e Elements can be moved from this div to others
<h1>Low Priority Tasks</h1>
<div class="hold" dragula="<A3">
<div class="LowPriority">Task 7 : Adjust the thermostat </div>
<div class="LowPriority">Task 8 : Clean the windows </div>
<div class="LowPriority">Task 9 : Mow the lawn </div>
</div>
-->
<!--This comment can be removed to see the difference between different dragula values. This particular elements cannot be moved into the above divs as the dragula value is different,But this does not stop the elements from moving inside the div<h1>Not Relevant</h1>
<div class="hold" dragula="CantMoveIntoAbove">
<div class="notRelevant">Task 10 : Build a dog house </div>
<div class="notRelevant">Task 11 : Go for a drive </div>
<div class="notRelevant">Task 12 : Fix a virtual meetup </div>
</div>
-->

App.component.css

.hold{
height: auto;
min-height: 37px;
border:black solid 3px;
}
/* Css for the Done Div */
.Done{
padding: 10px 10px 10px 10px;
border: green 1px solid;
font-size: large;
font-family: 'Times New Roman', Times, serif;
background-color: pink ;
}
/* Css for the To Do Div */
.ToDo{
padding: 10px 10px 10px 10px;
border: red 1px solid;
font-size: large;
font-family: 'Times New Roman', Times, serif;
background-color:yellow;
}
/* Css for the Low Priority List */
.LowPriority{
padding: 10px 10px 10px 10px;
border: white 1px solid;
font-size: large;
font-family: 'Times New Roman', Times, serif;
color: white;
background-color:black;
}
/* Css for the Not Relevant Div */
.notRelevant{
padding: 10px 10px 10px 10px;
border: orange 1px solid;
font-size: large;
font-family: 'Times New Roman', Times, serif;
}

Output:

Output of the above code along with Css

You can notice the divs under the first three headings i.e Done, To Do and Low Priority Tasks can be interchanged or dragged and dropped between each other as they have the same Dragula value.

The Not Relevant div cannot be dragged and dropped with the other three divs but its elements can be interchanged within the div.

Conclusion:

Ng2-Dragula is an awesome and simple way to implement drag and drop in Angular 7 without the need of writing complicated functions to perform basic drag and drop

The elements within a div or a container can be inter dragged ( from one div/container to another) only if their “dragula” values are same, but they can be intra dragged ( within the div or container ) but just adding dragula value to the container.

The Dragula value can be alphanumeric and can contain special characters as well and can be of any length.

And Thanks to @valorkin and @walkerrunpdx for making drag and drop functionality in angular such a breeze.

Love my blogs? It wasn’t possible without a steady input stream of hot coffee! Want to support me and help me write more blogs?? Buy me a cup of coffee https://www.buymeacoffee.com/SriharshaY and let the magic continue!

--

--