Create Drag and Drop with Ionic 2

Create Drag and Drop with Ionic 2

  • 2016-08-16
  • 1536

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.

Therefore today I will show you how to easily add drag and drop to your Ionic 2 app by including and using ngDragula.

Setting up a blank app

As always we start with a blank Ionic 2 app using TypeScript. We also already install the ng2-dragula library wich is the version of Dragula for Angular 2. So go ahead and run:

Start a new Ionic 2 project and install Dragula

ionic start devdactic-drag blank --v2 --ts
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.

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:
The class for our Items

import {Component} from [email protected]/core';
import {NavController, Alert} from 'ionic-angular';
import {Dragula, DragulaService} from "../../../node_modules/ng2-dragula/ng2-dragula"
 
@Component({
  templateUrl: 'build/pages/home/home.html',
  directives: [Dragula],
  providers: [DragulaService],
})
export class HomePage {
  q1 = [];
  q2 = [];
 
  constructor(private navController: NavController, 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 = Alert.create({
        title: 'Item moved',
        subTitle: 'So much fun!',
        buttons: ['OK']
      });
      this.navController.present(alert);
    });
  }
}

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. This is no limitation, I actually used 4 different lists inside my recently created app Priortrix.

We give both our lists 50% width using the Ionic 2 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:
The view for our drag&drop buckets

<ion-header>
  <ion-navbar>
    <ion-title>
      Devdactic Drag & Drop
    </ion-title>
  </ion-navbar>
</ion-header>
 
<ion-content>
  <ion-row>
    <ion-col width-50 class="left">
      <div class="header">First Bucket</div>
      <ion-list [dragula]='"my-bag"' [dragulaModel]="q1">
        <button ion-item *ngFor="let item of q1">
          {{item}}
      </button>
      </ion-list>
    </ion-col>
 
    <ion-col width-50 class="right">
      <div class="header">Second Bucket</div>
      <ion-list [dragula]='"my-bag"' [dragulaModel]="q2">
        <button ion-item *ngFor="let item of q2">
          {{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 I found somewhere but I can’t remember where) which uses the CSS names of Dragula.

Adding cool animations

These animations and stylings will add the effect of items floating above the rest while dragging and getting smooth into their new position. Obviously you can change this stuff to whatever you want the animation to look like!

So go ahead and insert in your app/pages/home/home.css:

Style the shit out of our view

.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;
}
 
// Dragula stuff
 
.gu-mirror {
  position: fixed !important;
  margin: 0 !important;
  z-index: 9999 !important;
  opacity: 0.8;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
  filter: alpha(opacity=80);
}
 
.gu-hide {
  display: none !important;
}
 
.gu-unselectable {
  -webkit-user-select: none !important;
  -moz-user-select: none !important;
  -ms-user-select: none !important;
  user-select: none !important;
}
 
.gu-transit {
  opacity: 0.2;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
  filter: alpha(opacity=20);
}

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 2 and Angular 2. 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!**

Click below for a video version of this tutorial!

Suggest

Ionic 2 Tutorial with Two Complete Apps

Ionic by Example: Create Mobile Apps in HTML5

Build an Ebay Classified Clone using Stamplay and Ionic

Learn Angular 2 Development By Building 10 Apps

Rails 5: Learning Web Development the Ruby Way