Angular 2 Drag-and-Drop without dependencies.
Follow me to be notified about new releases.
Some of these APIs and Components are not final and are subject to change!
npm install ng2-dnd --save
Simple examples using ng2-dnd: - with SystemJS in ng2-systemjs-demo - with Webpack in ng2-webpack-demo
Online demo available here
Plunker demo available here
If you use SystemJS to load your files, you might have to update your config:
System.config({
map: {
'ng2-dnd': 'node_modules/ng2-dnd/bundles/index.umd.js'
}
});
style.css into your web pageDndModuleImport DndModule.forRoot() in the NgModule of your application.
The forRoot method is a convention for modules that provide a singleton service.
import {BrowserModule} from "@angular/platform-browser";
import {NgModule} from '@angular/core';
import {DndModule} from 'ng2-dnd';
@NgModule({
imports: [
BrowserModule,
DndModule.forRoot()
],
bootstrap: [AppComponent]
})
export class AppModule {
}
If you have multiple NgModules and you use one as a shared NgModule (that you import in all of your other NgModules),
don't forget that you can use it to export the DndModule that you imported in order to avoid having to import it multiple times.
@NgModule({
imports: [
BrowserModule,
DndModule.forRoot()
],
exports: [BrowserModule, DndModule],
})
export class SharedModule {
}
import {Component} from '@angular/core';
@Component({
selector: 'simple-dnd',
template: `
<h4>Simple Drag-and-Drop</h4>
Available to drag
Drag Me
Place to drop
Item was dropped here
`
})
export class SimpleDndComponent {
simpleDrop: any = null;
}
import {Component} from '@angular/core';
@Component({
selector: 'simple-dnd-handle',
template: `
<h4>Simple Drag-and-Drop with handle</h4>
Available to drag
<span dnd-draggable-handle>=</span>
Drag Handle
Place to drop
Item was dropped here
`
})
export class SimpleDndHandleComponent {
simpleDrop: any = null;
}simpleDrop: any = null;
}
You can use property dropZones (actually an array) to specify in which place you would like to drop the draggable element:
import {Component} from '@angular/core';
@Component({
selector: 'zone-dnd',
template: `
<h4>Restricted Drag-and-Drop with zones</h4>
Available to drag
Drag Me
Zone 1 only
Available to drag
Drag Me
Zone 1 & 2
Zone 1
Item was dropped here
Zone 2
Item was dropped here
`
})
export class ZoneDndComponent {
restrictedDrop1: any = null;
restrictedDrop2: any = null;
}
You can transfer data from draggable to droppable component via dragData property of Draggable component:
import {Component} from '@angular/core';
@Component({
selector: 'custom-data-dnd',
template: `
<h4>Transfer custom data in Drag-and-Drop</h4>
Available to drag
Drag Me
{{transferData | json}}
Place to drop (Items:{{receivedData.length}})
0" *ngFor="let data of receivedData">{{data | json}}
`
})
export class CustomDataDndComponent {
transferData: Object = {id: 1, msg: 'Hello'};
receivedData: Array<any> = [];
transferDataSuccess($event: any) {
this.receivedData.push($event);
}
}
For use-cases when a static set of dropZones is not possible, a custom function can be used to dynamically determine whether an item can be dropped or not. To achieve that, set the allowDrop property to this boolean function.
In the following example, we have two containers that only accept numbers that are multiples of a user-input base integer. dropZones are not helpful here because they are static, whereas the user input is dynamic.
import { Component } from '@angular/core';
@Component({
selector: 'custom-function-dnd',
template: `
<h4>Use a custom function to determine where dropping is allowed</h4>
Available to drag
dragData = 6
dragData = 10
dragData = 30
<pre>allowDropFunction(baseInteger: any): any {{ '{' }}
return (dragData: any) => dragData % baseInteger === 0;
{{ '}' }}</pre>
Multiples of
<input type="number" [(ngModel)]="box1Integer" style="width: 4em">
only
dragData = {{item}}
Multiples of
<input type="number" [(ngModel)]="box2Integer" style="width: 4em">
only
dragData = {{item}}
`
})
export class CustomFunctionDndComponent {
box1Integer: number = 3;
box2Integer: number = 10;
box1Items: string[] = [];
box2Items: string[] = [];
allowDropFunction(baseInteger: number): any {
return (dragData: any) => dragData % baseInteger === 0;
}
addTobox1Items($event: any) {
this.box1Items.push($event.dragData);
}
addTobox2Items($event: any) {
this.box2Items.push($event.dragData);
}
}
Here is an example of shopping backet with products adding via drag and drop operation:
```js import { Component } from '@angular/core';
@Component({ selector: 'shoping-basket-dnd', template: `
Available products
0" [dragData]="product" (onDragSuccess)="orderedProduct($event)" [dropZones]="['demo1']">
{{product.name}} - \${{product.cost}}
(available: {{product.quantity}})
0">{{product.name}}
(NOT available)
Shopping Basket
(to pay: \${{totalCost()}})
{{product.name}}
(ordered: {{product.quantity}}
cost: \${{product.cost * product.quantity}})
` }) export class ShoppingBasketDndComponent { availableProducts: Array<Prod
$ claude mcp add ng2-dnd \
-- python -m otcore.mcp_server <graph>