An open API service indexing awesome lists of open source software.

https://github.com/gnucoop/ng2-dnd

Angular 2 Drag-and-Drop without dependencies
https://github.com/gnucoop/ng2-dnd

Last synced: 9 months ago
JSON representation

Angular 2 Drag-and-Drop without dependencies

Awesome Lists containing this project

README

          

# Angular 2+ Drag-and-Drop
Angular 2+ Drag-and-Drop without dependencies.
Based on [Angular 2 Drag-and-Drop by Sergey Akopkokhyants](https://github.com/akserg/ng2-dnd)

_Some of these APIs and Components are not final and are subject to change!_

## Installation
```bash
npm install ngx-dnd --save
```

## Usage
If you use SystemJS to load your files, you might have to update your config:

```js
System.config({
map: {
'ngx-dnd': 'node_modules/ngx-dnd/bundles/ngx-dnd.umd.js'
}
});
```

#### 1. Add the default styles
- Import the `style.css` into your web page

#### 2. Import the `DndModule`
Import `DndModule.forRoot()` in the NgModule of your application.
The `forRoot` method is a convention for modules that provide a singleton service.

```ts
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {DndModule} from 'ngx-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.

```ts
@NgModule({
imports: [
BrowserModule,
DndModule.forRoot()
],
exports: [BrowserModule, DndModule],
})
export class SharedModule {
}
```

#### 3. Use Drag-and-Drop operations with no code

```js
import {Component} from '@angular/core';

@Component({
selector: 'simple-dnd',
template: `

Simple Drag-and-Drop





Available to drag




Drag Me








Place to drop


Item was dropped here




`
})
export class SimpleDndComponent {
simpleDrop: any = null;
}
```

#### 4. Restriction Drag-and-Drop operations with drop zones
You can use property *dropZones* (actually an array) to specify in which place you would like to drop the draggable element:

```js
import {Component} from '@angular/core';

@Component({
selector: 'zone-dnd',
template: `

Restricted Drag-and-Drop with zones





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;
}
```

#### 5. Transfer custom data via Drag-and-Drop
You can transfer data from draggable to droppable component via *dragData* property of Draggable component:

```js
import {Component} from '@angular/core';

@Component({
selector: 'custom-data-dnd',
template: `

Transfer custom data in Drag-and-Drop





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 = [];

transferDataSuccess($event: any) {
this.receivedData.push($event);
}
}
```

#### 6. Use a custom function to determine where dropping is allowed
For use-cases when a static set of `dropZone`s 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. `dropZone`s are not helpful here because they are static, whereas the user input is dynamic.

```js
import { Component } from '@angular/core';

@Component({
selector: 'custom-function-dnd',
template: `

Use a custom function to determine where dropping is allowed





Available to drag



dragData = 6



dragData = 10



dragData = 30






allowDropFunction(baseInteger: any): any {{ '{' }}

return (dragData: any) => dragData % baseInteger === 0;
{{ '}' }}





Multiples of

only


dragData = {{item}}







Multiples of

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);
}
}
```

#### 7. Shopping basket with Drag-and-Drop
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: `

Drag-and-Drop - Shopping basket




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 = [];
shoppingBasket: Array = [];

constructor() {
this.availableProducts.push(new Product('Blue Shoes', 3, 35));
this.availableProducts.push(new Product('Good Jacket', 1, 90));
this.availableProducts.push(new Product('Red Shirt', 5, 12));
this.availableProducts.push(new Product('Blue Jeans', 4, 60));
}

orderedProduct($event: any) {
let orderedProduct: Product = $event.dragData;
orderedProduct.quantity--;
}

addToBasket($event: any) {
let newProduct: Product = $event.dragData;
for (let indx in this.shoppingBasket) {
let product: Product = this.shoppingBasket[indx];
if (product.name === newProduct.name) {
product.quantity++;
return;
}
}
this.shoppingBasket.push(new Product(newProduct.name, 1, newProduct.cost));
this.shoppingBasket.sort((a: Product, b: Product) => {
return a.name.localeCompare(b.name);
});
}

totalCost(): number {
let cost: number = 0;
for (let indx in this.shoppingBasket) {
let product: Product = this.shoppingBasket[indx];
cost += (product.cost * product.quantity);
}
return cost;
}
}

class Product {
constructor(public name: string, public quantity: number, public cost: number) {}
}
```

#### 8. Simple sortable with Drag-and-Drop
Here is an example of simple sortable of favorite drinks moving in container via drag and drop operation:

```js
import {Component} from '@angular/core';

@Component({
selector: 'simple-sortable',
template: `

Simple sortable






Favorite drinks



  • {{item}}








My prefences:

{{i + 1}}) {{item}}




`
})
export class SimpleSortableComponent {
listOne: Array = ['Coffee', 'Orange Juice', 'Red Wine', 'Unhealty drink!', 'Water'];
}
```

#### 9. Simple sortable With Drop into recycle bin
Here is an example of multi list sortable of boxers moving in container and between containers via drag and drop operation:

```js
import {Component} from '@angular/core';

@Component({
selector: 'recycle-multi-sortable',
template: `

Simple sortable With Drop into recycle bin






Favorite drinks



  • {{item}}








Recycle bin: Drag into me to delete it




Recycled: {{listRecycled.toString()}}


`
})
export class RecycleMultiSortableComponent {
listOne: Array = ['Coffee', 'Orange Juice', 'Red Wine', 'Unhealty drink!', 'Water'];
listRecycled: Array = [];
}
```

#### 10. Simple sortable With Drop into something, without delete it
Here is an example of simple sortable list of items copying in target container:

```js
import {Component} from '@angular/core';

@Component({
selector: 'simple-sortable-copy',
template: `

Simple sortable With Drop into something, without delete it





Source List



  • {{source.name}}







Target List




  • {{target.name}}





`
})
export class SimpleSortableCopyComponent {

sourceList: Widget[] = [
new Widget('1'), new Widget('2'),
new Widget('3'), new Widget('4'),
new Widget('5'), new Widget('6')
];

targetList: Widget[] = [];
addTo($event: any) {
this.targetList.push($event.dragData);
}
}

class Widget {
constructor(public name: string) {}
}
```

#### 11. Multi list sortable between containers
Here is an example of multi list sortable of boxers moving in container and between containers via drag and drop operation:

```js
import {Component} from '@angular/core';

@Component({
selector: 'embedded-sortable',
template: `

Move items between multi list sortable containers




Drag Containers




{{container.id}} - {{container.name}}



  • {{widget.name}}









Widgets




{{widget.name}}





`
})
export class EmbeddedSortableComponent {
dragOperation: boolean = false;

containers: Array = [
new Container(1, 'Container 1', [new Widget('1'), new Widget('2')]),
new Container(2, 'Container 2', [new Widget('3'), new Widget('4')]),
new Container(3, 'Container 3', [new Widget('5'), new Widget('6')])
];

widgets: Array = [];
addTo($event: any) {
if ($event) {
this.widgets.push($event.dragData);
}
}
}

class Container {
constructor(public id: number, public name: string, public widgets: Array) {}
}

class Widget {
constructor(public name: string) {}
}
```

# Credits
- [Francesco Cina](https://github.com/ufoscout)
- [Sergey Akopkokhyants](https://github.com/akserg)

# License
[MIT](/LICENSE)