AppDividend
Latest Code Tutorials

Angular 7 Drag and Drop Tutorial With Example

3

Angular 7 Drag and Drop Tutorial With Example is today’s leading topic.  We will use Angular 7 and Angular Material 7 for this example.  Angular Material is the ground running with significant, modern UI components. Angular Material Design components will help us to construct attractive UI and UX, consistent, and functional web pages and web applications while keeping modern web design principles like browser portability and compatibility. In today’s post, we will use the DragDropModule in the Angular Material library. So let us start an Angular 7 Drag and Drop Tutorial With Example From Scratch.

If you want to learn more about Angular, then check out this Angular 7 – The complete Guide course.

Angular 7 Drag and Drop Tutorial With Example

Let us create an Angular 7 project. If you have Angular CLI 6, then you need to upgrade your CLI. For that, you can refer to this article.

#1: Install Angular 7 project and Angular Material Library

ng new ang7drag

 

Angular 7 Drag and Drop Tutorial With Example

Now, go into the project folder and open the project inside the visual studio code.

cd ang7drag
code .

Install the hammerjs using the following command.

npm install --save hammerjs

Hammer.js is an optional dependency and helps with touch support for the few of the material components.

Now, install an Angular Material and Angular Animations using the following command.

npm install --save @angular/material @angular/animations @angular/cdk

Now, include hammerjs inside an angular.json file. You can find this file on the root of the angular project.

"scripts": [
     "./node_modules/hammerjs/hammer.min.js"
]

#3: Import the pre-built theme and Material icons

Angular Material comes with some pre-built themes. These themes provide us set off the colors and basic styling. The main available themes are these: indigo-pinkdeeppurple-amberpurple-green and pink-bluegrey. To import the theme in our project, we can add the following code to your global styles.css file. The file is inside the src folder.

@import '~@angular/material/prebuilt-themes/indigo-pink.css';

You can also have access to the Material Design icons and use these named icons with the <mat-icon> component. To import them to your project, you can add this to the head section of your project’s root index.html file.

<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">

Now the final step is to import BrowserAnimationsModule inside the app.module.ts file.

// app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

#4: API reference for Angular CDK drag-drop

We need to import the DragDropModule inside the app.module.ts file.

// app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { DragDropModule } from '@angular/cdk/drag-drop';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    DragDropModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

It is the container that wraps a set of draggable items.

Selector: [cdkDropList] cdk-drop-list

Exported as: cdkDropList

Methods

It has the drop() method. It drops an item into this container.

Parameters

item

CdkDrag<any>

The item is dropped into the container.

currentIndex

number

Index at which the item should be inserted.
previousContainer

Partial<CdkDropListContainer<any>>

Container from which the item got dragged in.

isPointerOverContainer

boolean

Whether the user’s pointer was over the container when the item was dropped.

 

#5: Create a service and model files

Create an Angular service using the following command.

ng g s student --spec=false

It will create a file student.service.ts file inside the src >> app folder.

We have created service because we will use service to handle the data that needs to be displayed on the frontend.

Also, create a new file inside the src >> app folder called student.model.ts and add the following code inside it.

// student.model.ts

export class Student {
    name: String;
}

Now, we need to add the demo data inside the student.service.ts file. The data is the type of Student model which we have defined above.

// student.service.ts

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Student } from './student.model';

@Injectable({
  providedIn: 'root'
})
export class StudentService {

    students: Student[] = [
    {
        name: 'Krunal'
    },
    {
        name: 'Ankit'
    },
    {
        name: 'Rushabh'
    },
    {
        name: 'Dhaval'
    },
    {
        name: 'Nehal'
    },

  constructor() { }

  public getStudents(): any {
     const studentsObservable = new Observable(observer => {
            setTimeout(() => {
                observer.next(this.students);
            }, 1000);
     });

     return studentsObservable;
 }
}

So, here we have done is first import the Observable from rxjs. Then defined one function that will return an observable. The observable object gets one argument that has a timeout function. So after 1 second, it will produce the whole student’s array if the subscriber subscribes the observable.

In simple terms, here studentObservable are publishing our primary data array that is students. So if any entity needs to get the values out of observable, then it first needs to subscribe that observable and then studentObservable starts to publish the values, and then subscriber get the values.

#6: Define the Subscriber

We have created the Publisher for the Observables. Now, we need to create a subscriber. So write the following code inside the app.component.ts file.

// app.component.ts

import { Component, OnInit } from '@angular/core';
import {CdkDragDrop, moveItemInArray} from '@angular/cdk/drag-drop';
import { Student } from './student.model';
import { StudentService } from './student.service';

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

    constructor(private studentservice: StudentService) {}

    drop(event: CdkDragDrop<string[]>) {
        moveItemInArray(this.students, event.previousIndex, event.currentIndex);
    }

    ngOnInit() {
        const studentsObservable = this.studentservice.getStudents();
        studentsObservable.subscribe((studentsData: Student[]) => {
            this.students = studentsData;
        });
    }
}

So, when the component Initializes, we will call the service method’s getStudents() methods and fetch all the student names in an array.

Now, we need to create the drop() method which is provided by CdkDragDrop module. Also, we are calling the moveItemInArray which takes three arguments, and we pass that students array to that list.

#7: Add CSS and HTML code

Now, we need to add the CSS3 classes inside the app.component.css file. So let us do that. 
.example-list {
    width: 500px;
    max-width: 100%;
    border: solid 1px #ccc;
    min-height: 60px;
    display: block;
    background: white;
    border-radius: 4px;
    overflow: hidden;
  }
  
  .example-box {
    padding: 20px 10px;
    border-bottom: solid 1px #ccc;
    color: rgba(0, 0, 0, 0.87);
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    box-sizing: border-box;
    cursor: move;
    background: white;
    font-size: 14px;
  }
  
  .cdk-drag-preview {
    box-sizing: border-box;
    border-radius: 4px;
    box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
                0 8px 10px 1px rgba(0, 0, 0, 0.14),
                0 3px 14px 2px rgba(0, 0, 0, 0.12);
  }
  
  .cdk-drag-placeholder {
    opacity: 0;
  }
  
  .cdk-drag-animating {
    transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
  }
  
  .example-box:last-child {
    border: none;
  }
  
  .example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder) {
    transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
  }

It will help us to transform the HTML elements. Now, the final step is to add the HTML code inside the app.component.html file.

<!-- app.component.html -->

<div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)">
    <div class="example-box" *ngFor="let student of students" cdkDrag>{{ student.name }}</div>
</div>

Save the file and start the angular dev server.

ng serve --open

 

Angular 7 Drag and Drop Tutorial

You will see something like this and now you can able to drag and drop the items inside that box.

The cdkDropList directive supports transferring dragged items between connected drop zones. You can connect one or more cdkDropList instances together by setting the cdkDropListConnectedTo property or by wrapping the elements in an element with the cdkDropListGroup attribute.

Okay, now we will create the two section and we can interchange the lists between that two sections.

So, we need to create a second array called students2. We will define that array inside the app.component.ts file and do not go for services.

Write the following code inside the app.component.ts file.

// app.component.ts

import { Component, OnInit } from '@angular/core';
import {CdkDragDrop, moveItemInArray, transferArrayItem} from '@angular/cdk/drag-drop';
import { Student } from './student.model';
import { StudentService } from './student.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
    students: Student[] = [];
    students2: Student[] = [
        {
            name: 'Siddharth'
        },
        {
            name: 'Jay'
        },
        {
            name: 'Jaydeep'
        },
        {
            name: 'Chirag'
        }];
    constructor(private studentservice: StudentService) {}

    drop(event: CdkDragDrop<string[]>) {
        if (event.previousContainer === event.container) {
            moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
        } else {
        transferArrayItem(event.previousContainer.data,
                        event.container.data,
                        event.previousIndex,
                        event.currentIndex);
        }
    }

    ngOnInit() {
        const studentsObservable = this.studentservice.getStudents();
        studentsObservable.subscribe((studentsData: Student[]) => {
            this.students = studentsData;
        });
    }
}

Also, we need to modify the app.component.html code.

<!-- app.component.html -->

<div class="example-container">
    <h2>Students</h2>
    <div
      cdkDropList
      #studentsList="cdkDropList"
      [cdkDropListData]="students"
      [cdkDropListConnectedTo]="[students2List]"
      class="example-list"
      (cdkDropListDropped)="drop($event)">
      <div class="example-box" *ngFor="let student of students" cdkDrag>{{student.name}}</div>
    </div>
  </div>
  
  <div class="example-container">
    <h2>Students 2</h2>
    <div
      cdkDropList
      #students2List="cdkDropList"
      [cdkDropListData]="students2"
      [cdkDropListConnectedTo]="[studentsList]"
      class="example-list"
      (cdkDropListDropped)="drop($event)">
      <div class="example-box" *ngFor="let student2 of students2" cdkDrag>{{student2.name}}</div>
  </div>
</div>

Save the file and go to the browser and you will see something like this.

Angular Drag and Drop Example
Finally, Angular 7 Drag and Drop Tutorial With Example is over.
3 Comments
  1. Saranya Sekar says

    ERROR in src/app/app.component.ts(21,56): error TS2339: Property ‘getStudents’ does not exist on type ‘StudentService’.
    src/app/student.service.ts(29,3): error TS2662: Cannot find name ‘constructor’. Did you mean the static member ‘StudentService.constructor’?
    src/app/student.service.ts(31,3): error TS2304: Cannot find name ‘public’.
    src/app/student.service.ts(31,10): error TS2304: Cannot find name ‘getStudents’.
    src/app/student.service.ts(31,25): error TS2693: ‘any’ only refers to a type, but is being used as a value here.
    src/app/student.service.ts(32,12): error TS2304: Cannot find name ‘studentsObservable’.
    src/app/student.service.ts(38,13): error TS2304: Cannot find name ‘studentsObservable’.

  2. Divya says

    Hi,

    I need to move the item from one div to another.. but Div should not be cdkDropList. Random arrangemement of items inside div.

  3. Claudio Almeida says

    The student service you need to close the students array by putting a ] in the place of the ,

Leave A Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.