PrimeNG Drag And Drop Example | CodeUsingJava








PrimeNG Drag And Drop Example


Overview

Using PrimeNG Drag and Drop, we can be get hold of an object and move it to a different location. This ability to move objects help us make the UI more interactive. Using PrimeNG implementing the Drag and Drop functionality is very easy. pDraggable and pDroppable are attached to a target element to add drag-drop behavior.
We will be implementing a functionality where a user can create a list of his favorite books from the available books. He can drag a book from the available books section to the favorite books section.
PrimeNG Drag and Drop Example

Technology Stack

We will be making use of-
  • Angular 8
  • PrimeNG

Video Tutorial

Table Of Contents :


Implementation

For this tutorial series we make use of Visual Studio Code
The Angular project we will be developing is as follows-
PrimeNG Project

Develop Angular Application

  • Install NodeJS. Go to NodeJS downloads page and download installer. Start the installer and install nodejs.
  • Install angular cli using the command-
    
    npm install -g @angular/cli
    

    Install Angular CLI
  • Create new Angular Project named drg example
    
    ng new dragexample --skip-git
    

    New Angular CLI
  • Go inside the created the created angular project and start Angular Project-
    
    ng serve
    

    Start Angular CLI
  • Go to localhost:4200

    Angular Home Page

Use PrimeNG Components

  • Install PrimeNG
    
    npm install primeng --save
    

    PrimeNG Install
  • Install Prime Icons
    
    npm install primeicons --save
    

    Prime Icons Install
  • Install Font Awesome
    
    npm install font-awesome --save
    

    Font Awesome Install
  • Install Angular CDK
    
    npm install @angular/cdk --save
    

    PrimeNG Angular CDK
  • If we now go to package.json, we will see the following primeng dependencies
    PrimeNG package dependencies
  • Open the angular.json and add the following in the styles section
    
    "./node_modules/primeicons/primeicons.css",
      "./node_modules/primeng/resources/themes/nova-light/theme.css",
      "./node_modules/primeng/resources/primeng.min.css",
    

    PrimeNG style sheet
Create a new Component named drg-component as follows-

ng generate component drg

PrimeNG Component
In the app-routing.module.ts add the route as drg for our new DrgComponent

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DrgComponent } from './drg/drg.component';

const routes: Routes = [
  { path: 'drg', component: DrgComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
Also in the app.component.html keep only the below code and remove the remaining-

<router-outlet></router-outlet>
Start the application using-

ng serve

PrimeNG serve
If we now go to localhost:4200/drg we see the following-
PrimeNG Hello World

Adding the PrimeNG Component in Angular Application

For adding any PrimeNG Component in Angular we will be following below steps-
Add PrimeNG Component
  • Add the following PrimeNG modules to the app.module.ts
    • DragDropModule
    • PanelModule
    • TableModule
    • HttpClientModule
    • BrowserAnimationsModule
    
    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    
    import { AppRoutingModule } from './app-routing.module';
    import { AppComponent } from './app.component';
    import { DrgComponent } from './drg/drg.component';
    
    import { DragDropModule } from 'primeng/dragdrop';
    import { PanelModule } from 'primeng/panel';
    import { TableModule } from 'primeng/table';
    import { HttpClientModule } from '@angular/common/http';
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
    
    
    @NgModule({
      declarations: [
        AppComponent,
        DrgComponent
      ],
      imports: [
        BrowserModule,
        AppRoutingModule,
        DragDropModule,
        PanelModule,
        TableModule,
        HttpClientModule,
        BrowserAnimationsModule
    
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    
    
  • Create a service named BookService
    
    ng generate service service/book
    
    
  • Create the Book domain object
    
    export interface Book {
        name?;
        price?;
        author?;
        serialNo?
    }
    
    
  • We will be having 2 JSON files in the assets folder -
    • all-books.json
      
      {
          "data": [
              {
                  "name": "Harry Potter and the Deathly Hallows",
                  "price": 20,
                  "author": "J.K. Rowling ",
                  "serialNo": "154"
              },
              {
                  "name": "Song Of Ice and Fire",
                  "price": 20,
                  "author": "R.R. Martin",
                  "serialNo": "155"
              }
          ]
      }
      
      
    • favorite-books.json
      
      {
          "data": [
              {
                  "name": "The Godfather",
                  "price": 10,
                  "author": "Mario Puzo",
                  "serialNo": "152"
              },
              {
                  "name": "The Fellowship of the Ring",
                  "price": 15,
                  "author": "J.R.R. Tolkien",
                  "serialNo": "153"
              }
          ]
      }
      
      
    We will be reading these JSON files using the httpclient in the Book Service
    
    import { HttpClient } from '@angular/common/http';
    import { Injectable } from '@angular/core';
    import { Book } from './book';
    
    @Injectable({
      providedIn: 'root'
    })
    export class BookService {
    
      constructor(private http: HttpClient) { }
    
      getAllBooks() {
        return this.http.get<any>('assets/all-books.json')
          .toPromise()
          .then(res => <Book[]>res.data)
          .then(data => {
            return data;
          });
      }
    
      getFavoriteBooks() {
        return this.http.get<any>('assets/favorite-books.json')
          .toPromise()
          .then(res => <Book[]>res.data)
          .then(data => {
            return data;
          });
      }
    
    }
    
    
  • Next in the DrgComponent we will be creating the backing data by calling the BookService getAllBooks and getFavoriteBooks.
    
    import { Component, OnInit } from '@angular/core';
    import { BookService } from '../service/book.service';
    import { Book } from '../service/book';
    
    @Component({
        selector: 'app-drg',
        templateUrl: './drg.component.html',
        styleUrls: ['./drg.component.css']
    })
    export class DrgComponent implements OnInit {
    
    
        availableBooks: Book[];
    
        favoriteBooks: Book[];
    
        draggedBook: Book;
    
        constructor(private bookService: BookService) { }
    
        ngOnInit() {
            this.bookService.getAllBooks().then(books => this.availableBooks = books);
            this.bookService.getFavoriteBooks().then(books => this.favoriteBooks = books);
            console.log(this.availableBooks);
        }
    
        dragStart(event, book: Book) {
            this.draggedBook = book;
        }
    
        drop(event) {
            if (this.draggedBook) {
                let draggedBookIndex = this.findIndex(this.draggedBook);
                this.favoriteBooks = [...this.favoriteBooks, this.draggedBook];
                this.availableBooks = this.availableBooks.filter((val, i) => i != draggedBookIndex);
                this.draggedBook = null;
            }
        }
    
        dragEnd(event) {
            this.draggedBook = null;
        }
    
        findIndex(book: Book) {
            let index = -1;
            for (let i = 0; i < this.availableBooks.length; i++) {
                if (book.name === this.availableBooks[i].name) {
                    index = i;
                    break;
                }
            }
            return index;
        }
    
    }
    
    
  • Finally in the drg component html file we will be using the created backing data - availableBooks and favoriteBooks for the drag and drop functionality. Also it is important to keep name of pDraggable and pDroppable to be the same. In our case we have used the name books.
    Also in the assets folder we will need to provide the images with the serial number as the name.
    
    <div class="p-grid">
    <h1>List Of Available Books</h1>
    
    
        <div class="p-col-12 p-md-6 p-col-nogutter drag-column">
            <div *ngFor="let book of availableBooks" class="ui-helper-clearfix">
                <div class="ui-g-12 ui-md-4" pDraggable="books" (onDragStart)="dragStart($event, book)"
                    (onDragEnd)="dragEnd($event)">
                    <p-panel [header]="book.name" [style]="{'text-align':'center'}">
                        <img src="assets/images/{{book.serialNo}}.PNG">
                    </p-panel>
                </div>
            </div>
        </div>
        <h1>My Personal Favorites</h1>
        <div class="p-col-12 p-md-6 drop-column" pDroppable="books" (onDrop)="drop($event)"
            [ngClass]="{'ui-highlight-book':draggedBook}">
            <p-table [value]="favoriteBooks">
                <ng-template pTemplate="header">
                    <tr>
                        <th>Name</th>
                        <th>Price(Dollars)</th>
                        <th>Author</th>
                    </tr>
                </ng-template>
                <ng-template pTemplate="body" let-book>
                    <tr>
                        <td>{{book.name}}</td>
                        <td>{{book.price}}</td>
                        <td>{{book.author}}</td>
                    </tr>
                </ng-template>
            </p-table>
        </div>
    </div>
    
    

Downloads-

PrimeNG Drag And Drop Example