How to Build Ionic 2 Drag and Drop using Dragula Last update: 2016-08-11
Having drag and drop functionality in your mobile app is very common, but it’s not really inlcuded in the standard Ionic stuff. I looked around and found a great library called Dragula which gives AngularJS apps great features.
This Tutorial was updated for Ionic 3.2!
Therefore today I will show you how to easily add drag and drop to your Ionic app by including and using ngDragula.
Prerequisite
Learning Ionic can become overwhelming, I know that feeling. Is learning from tutorials and videos sometimes not enough for you? Then I got something for you.
If you want to learn Ionic with step-by-step video courses, hands-on training projects and a helpful community who has your back, then take a look at the Ionic Academy.
Setting up a blank app
As always we start with a blank Ionic app. We also already install the ng2-dragula library wich is the version of Dragula for Angular 2. So go ahead and run:
ionic start devdactic-drag blank
cd devdactic-drag
npm install ng2-dragula dragula --save
There are many great examples in the Dragula Demo, basically you can drag an item from one list/div to another defined area. You can also specify all kinds of attributes how the drag or drop feature should behave in special cases.
For us, we simply want to have 2 Ionic lists side by side and drag and drop items between those 2 lists.
To use Dragula we need to make sure it is imported to our module so change your src/app/app.module.ts to:
import { BrowserModule } from '@angular/platform-browser';
import { ErrorHandler, NgModule } from '@angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { SplashScreen } from '@ionic-native/splash-screen';
import { StatusBar } from '@ionic-native/status-bar';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { DragulaModule } from 'ng2-dragula';
@NgModule({
declarations: [
MyApp,
HomePage
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp),
DragulaModule
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage
],
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler}
]
})
export class AppModule {}
Importing and using ngDragula
To use the library we need to import it inside our class and add the directive and provider of ngDragula to our component.
Inside our class we have 2 arrays for our 2 lists. The lists will be filled with *ngFor
, but the library will actually take care of moving the dragged item to the new array of our class, so all the data is updated.
Pretty awesome, right?
For an example we also subscribe to the drop
event of the DragulaService
and create a little alert. This means, whenever we drop something it should appear in the new place and also a popup should come up.
Now go ahead and insert in your app/pages/home/home.ts:
import { Component } from '@angular/core';
import { NavController, AlertController } from 'ionic-angular';
import { DragulaService } from 'ng2-dragula/ng2-dragula';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
q1 = [];
q2 = [];
constructor(private navController: NavController, public alertCtrl: AlertController, private dragulaService: DragulaService) {
for (var i = 0; i < 20; i++) {
this.q1.push("1. <" + i + ">");
this.q2.push("2. <" + i + ">");
}
dragulaService.drop.subscribe((value) => {
let alert = this.alertCtrl.create({
title: 'Item moved',
subTitle: 'So much fun!',
buttons: ['OK']
});
alert.present();
});
}
}
That’s actually everything we need for our little demo to work with. Let’s craft the view around it.
Setting up our view for Drag and drop
As said before, we want to have 2 lists to drop from one to the other.
We give both our lists 50% width using the Ionic grid system.
For Dragula we actually need to define only 2 things:
- [dragula]: The name of a general bag, should be the same for sources where you want to have drag and drop
- [dragulaModel]: The actual array inside our class
Open the app/pages/home/home.html and insert:
<ion-header>
<ion-navbar>
<ion-title>
Devdactic Drag & Drop
</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-row>
<ion-col col-6 class="left">
<div class="header">First Bucket</div>
<ion-list [dragula]='"my-bag"' [dragulaModel]="q1">
<button ion-item *ngFor="let item of q1" detail-none>
{{item}}
</button>
</ion-list>
</ion-col>
<ion-col col-6 class="right">
<div class="header">Second Bucket</div>
<ion-list [dragula]='"my-bag"' [dragulaModel]="q2">
<button ion-item *ngFor="let item of q2" detail-none>
{{item}}
</button>
</ion-list>
</ion-col>
</ion-row>
</ion-content>
As you can see, we specify the name "my-bag"
to let Dragula know those 2 lists have a connection, and for each list we specify either q1
or q2
, the arrays from our previously created class.
Now this should already work, but to get the cool effects you might have seen on the Demo page we need to add some styling, which we can directly take from Dragula.
This is an important step, otherwise you might see no animation or working drag & drop at all!
The best way to do so is writing your own copy config for NPM packages, which I have described here.
Simply create the copy config, add it to your package.json and let it copy the file like this:
copyDragulaCss: {
src: './node_modules/dragula/dist/dragula.css',
dest: '{{BUILD}}'
}
Inside your index.html you can now use that file by loading it inside the header:
<link rel="stylesheet" href="build/dragula.css">
Now we got the animations, let’s finish it up with a few more classes for our own elements.
Adding finishing touches
These animations and stylings will add the effect of items floating above the rest while dragging and getting smooth into their new position. We also apply some own stylings to a few elements as well, so go ahead and insert in your app/pages/home/home.css:
page-home {
.header {
height: 30px;
padding-left: 5px;
padding-top: 2px;
text-align: center;
}
.left {
border-right: 1px solid #000000;
padding: 0px;
overflow: scroll;
}
.right {
padding: 0px;
overflow: scroll;
}
}
Now go ahead and drag and drop all the items of your list!
Conclusion
It’s pretty easy to include a mighty feature like drag and drop with Ionic and Angular. If you found libraries like these that are already available with Angular 2+, you won’t have any problems most of the time. What are your experiences with other frameworks for animation or cool features? Let me know your experiences!
Happy Coding, Simon
Click below for a video version of this tutorial!