Giter Site home page Giter Site logo

ng2-dnd's Introduction

Angular 2 Drag-and-Drop npm version npm monthly downloads

Angular 2 Drag-and-Drop without dependencies.

Follow me twitter to be notified about new releases.

Build Status Dependency Status devDependency Status Known Vulnerabilities

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

Transpilation to Angular Package Format

The library uses ng-packagr to transpile into the Angular Package Format:

  • Bundles library in FESM2015, FESM5, and UMD formats
  • The npm package can be consumed by Angular CLI, Webpack, or SystemJS
  • Creates type definitions (.d.ts)
  • Generates Ahead-of-Time metadata (.metadata.json)
  • Auto-discovers and bundles secondary entry points such as @my/foo, @my/foo/testing, @my/foo/bar

Installation

npm install ng2-dnd --save

Demo

  • Webpack demo available here
  • SystemJS demo available here

Usage

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/ng2-dnd.umd.js'
    }
});

1. Add the default styles

  • Import the style.css into your web page from node_modules/ng2-dnd/bundles/style.css

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.

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
    ],
    exports: [BrowserModule, DndModule],
})
export class SharedModule {
}

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

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

@Component({
    selector: 'simple-dnd',
    template: `
<h4>Simple Drag-and-Drop</h4>
<div class="row">
    <div class="col-sm-3">
        <div class="panel panel-success">
            <div class="panel-heading">Available to drag</div>
            <div class="panel-body">
                <div class="panel panel-default" dnd-draggable [dragEnabled]="true">
                    <div class="panel-body">
                        <div>Drag Me</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="col-sm-3">
        <div dnd-droppable class="panel panel-info" (onDropSuccess)="simpleDrop=$event">
            <div class="panel-heading">Place to drop</div>
            <div class="panel-body">
                <div *ngIf="simpleDrop">Item was dropped here</div>
            </div>
        </div>
    </div>
</div>`
})
export class SimpleDndComponent {
    simpleDrop: any = null;
}

4. Add handle to restrict draggable zone of component

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

@Component({
    selector: 'simple-dnd-handle',
    template: `
<h4>Simple Drag-and-Drop with handle</h4>
<div class="row">
    <div class="col-sm-3">
        <div class="panel panel-success">
            <div class="panel-heading">Available to drag</div>
            <div class="panel-body">
                <div class="panel panel-default" dnd-draggable [dragEnabled]="true">
                    <div class="panel-body">
                        <div>
                            <span dnd-draggable-handle>=</span>&nbsp;
                            Drag Handle
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="col-sm-3">
        <div dnd-droppable class="panel panel-info" (onDropSuccess)="simpleDrop=$event">
            <div class="panel-heading">Place to drop</div>
            <div class="panel-body">
                <div *ngIf="simpleDrop">Item was dropped here</div>
            </div>
        </div>
    </div>
</div>`
})
export class SimpleDndHandleComponent {
    simpleDrop: any = null;
}

5. 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:

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

@Component({
    selector: 'zone-dnd',
    template: `
<h4>Restricted Drag-and-Drop with zones</h4>
<div class="row">
    <div class="col-sm-3">
        <div class="panel panel-primary">
            <div class="panel-heading">Available to drag</div>
            <div class="panel-body">
                <div class="panel panel-default" dnd-draggable [dragEnabled]="true" [dropZones]="['zone1']">
                    <div class="panel-body">
                        <div>Drag Me</div>
                        <div>Zone 1 only</div>
                    </div>
                </div>
            </div>
        </div>

        <div class="panel panel-success">
            <div class="panel-heading">Available to drag</div>
            <div class="panel-body">
                <div class="panel panel-default" dnd-draggable [dragEnabled]="true" [dropZones]="['zone1', 'zone2']">
                    <div class="panel-body">
                        <div>Drag Me</div>
                        <div>Zone 1 & 2</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="col-sm-3">
        <div dnd-droppable class="panel panel-info" [dropZones]="['zone1']" (onDropSuccess)="restrictedDrop1=$event">
            <div class="panel-heading">Zone 1</div>
            <div class="panel-body">
                <div *ngIf="restrictedDrop1">Item was dropped here</div>
            </div>
        </div>
    </div>
    <div class="col-sm-3">
        <div dnd-droppable class="panel panel-warning" [dropZones]="['zone2']" (onDropSuccess)="restrictedDrop2=$event">
            <div class="panel-heading">Zone 2</div>
            <div class="panel-body">
                <div *ngIf="restrictedDrop2">Item was dropped here</div>
            </div>
        </div>
    </div>
</div>`
})
export class ZoneDndComponent {
    restrictedDrop1: any = null;
    restrictedDrop2: any = null;
}

6. Transfer custom data via Drag-and-Drop

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>
<div class="row">
    <div class="col-sm-3">
        <div class="panel panel-success">
            <div class="panel-heading">Available to drag</div>
            <div class="panel-body">
                <div class="panel panel-default" dnd-draggable [dragEnabled]="true" [dragData]="transferData">
                    <div class="panel-body">
                        <div>Drag Me</div>
                        <div>{{transferData | json}}</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="col-sm-3">
        <div dnd-droppable class="panel panel-info" (onDropSuccess)="transferDataSuccess($event)">
            <div class="panel-heading">Place to drop (Items:{{receivedData.length}})</div>
            <div class="panel-body">
                <div [hidden]="!receivedData.length > 0" *ngFor="let data of receivedData">{{data | json}}</div>
            </div>
        </div>
    </div>
</div>`
})
export class CustomDataDndComponent {
    transferData: Object = {id: 1, msg: 'Hello'};
    receivedData: Array<any> = [];

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

7. Use a custom function to determine where dropping is allowed

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>
<div class="row">
    <div class="col-sm-3">
        <div class="panel panel-success">
            <div class="panel-heading">Available to drag</div>
            <div class="panel-body">
                <div class="panel panel-default" dnd-draggable [dragData]="6">
                    <div class="panel-body">dragData = 6</div>
                </div>
                <div class="panel panel-default" dnd-draggable [dragData]="10">
                    <div class="panel-body">dragData = 10</div>
                </div>
                <div class="panel panel-default" dnd-draggable [dragData]="30">
                    <div class="panel-body">dragData = 30</div>
                </div>
            </div>
        </div>
    </div>
    <div class="col-sm-6">
        <pre>allowDropFunction(baseInteger: any): any {{ '{' }}
  return (dragData: any) => dragData % baseInteger === 0;
{{ '}' }}</pre>
        <div class="row">
            <div class="col-sm-6">
                <div dnd-droppable class="panel panel-info" [allowDrop]="allowDropFunction(box1Integer)" (onDropSuccess)="addTobox1Items($event)">
                    <div class="panel-heading">
                        Multiples of
                        <input type="number" [(ngModel)]="box1Integer" style="width: 4em">
                        only
                    </div>
                    <div class="panel-body">
                        <div *ngFor="let item of box1Items">dragData = {{item}}</div>
                    </div>
                </div>
            </div>
            <div class="col-sm-6">
                <div dnd-droppable class="panel panel-warning" [allowDrop]="allowDropFunction(box2Integer)" (onDropSuccess)="addTobox2Items($event)">
                    <div class="panel-heading">
                        Multiples of
                        <input type="number" [(ngModel)]="box2Integer" style="width: 4em">
                        only
                    </div>
                    <div class="panel-body">
                        <div *ngFor="let item of box2Items">dragData = {{item}}</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
`
})
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);
    }
}

8. Shopping basket with Drag-and-Drop

Here is an example of shopping backet with products adding via drag and drop operation:

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

@Component({
    selector: 'shoping-basket-dnd',
    template: `
<h4>Drag-and-Drop - Shopping basket</h4>
<div class="row">

    <div class="col-sm-3">
        <div class="panel panel-success">
            <div class="panel-heading">Available products</div>
            <div class="panel-body">
                <div *ngFor="let product of availableProducts" class="panel panel-default"
                    dnd-draggable [dragEnabled]="product.quantity>0" [dragData]="product" (onDragSuccess)="orderedProduct($event)" [dropZones]="['demo1']">
                    <div class="panel-body">
                        <div [hidden]="product.quantity===0">{{product.name}} - \${{product.cost}}<br>(available: {{product.quantity}})</div>
                        <div [hidden]="product.quantity>0"><del>{{product.name}}</del><br>(NOT available)</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="col-sm-3">
        <div dnd-droppable (onDropSuccess)="addToBasket($event)" [dropZones]="['demo1']" class="panel panel-info">
            <div class="panel-heading">Shopping Basket<br>(to pay: \${{totalCost()}})</div>
            <div class="panel-body">
                <div *ngFor="let product of shoppingBasket" class="panel panel-default">
                    <div class="panel-body">
                    {{product.name}}<br>(ordered: {{product.quantity}}<br>cost: \${{product.cost * product.quantity}})
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>`
})
export class ShoppingBasketDndComponent {
    availableProducts: Array<Product> = [];
    shoppingBasket: Array<Product> = [];

    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) {}
}

9. Simple sortable with Drag-and-Drop

Here is an example of simple sortable of favorite drinks moving in container via drag and drop operation:

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

@Component({
    selector: 'simple-sortable',
    template: `
<h4>Simple sortable</h4>
<div class="row">
    <div class="col-sm-3">
        <div class="panel panel-success">
            <div class="panel-heading">
                Favorite drinks
            </div>
            <div class="panel-body">
                <ul class="list-group" dnd-sortable-container [sortableData]="listOne">
                    <li *ngFor="let item of listOne; let i = index" class="list-group-item" dnd-sortable [sortableIndex]="i">{{item}}</li>
                </ul>
            </div>
        </div>
    </div>
    <div class="col-sm-6">
        <div class="panel panel-default">
            <div class="panel-body">
                My prefences:<br/>
                <span *ngFor="let item of listOne; let i = index">{{i + 1}}) {{item}}<br/></span>
            </div>
        </div>
    </div>
</div>`
})
export class SimpleSortableComponent {
    listOne: Array<string> = ['Coffee', 'Orange Juice', 'Red Wine', 'Unhealty drink!', 'Water'];
}

10. Simple sortable with Drag-and-Drop handle

Add handle to restict grip zone of sortable component.

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

@Component({
    selector: 'simple-sortable-handle',
    template: `
<h4>Simple sortable handle</h4>
<div class="row">
    <div class="col-sm-3">
        <div class="panel panel-success">
            <div class="panel-heading">
                Favorite drinks
            </div>
            <div class="panel-body">
                <ul class="list-group" dnd-sortable-container [sortableData]="listOne">
                    <li *ngFor="let item of listOne; let i = index" class="list-group-item" dnd-sortable [sortableIndex]="i">
                      <span dnd-sortable-handle>=</span>&nbsp;
                      {{item}}
                    </li>
                </ul>
            </div>
        </div>
    </div>
    <div class="col-sm-6">
        <div class="panel panel-default">
            <div class="panel-body">
                My prefences:<br/>
                <span *ngFor="let item of listOne; let i = index">{{i + 1}}) {{item}}<br/></span>
            </div>
        </div>
    </div>
</div>`
})
export class SimpleSortableHandleComponent {
    listOne: Array<string> = ['Coffee', 'Orange Juice', 'Red Wine', 'Unhealty drink!', 'Water'];
}

11. 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:

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

@Component({
    selector: 'recycle-multi-sortable',
    template: `
<h4>Simple sortable With Drop into recycle bin</h4>
<div class="row">
    <div class="col-sm-3">
        <div class="panel panel-success">
            <div class="panel-heading">
                Favorite drinks
            </div>
            <div class="panel-body" dnd-sortable-container [sortableData]="listOne" [dropZones]="['delete-dropZone']">
                <ul class="list-group">
                    <li *ngFor="let item of listOne; let i = index" class="list-group-item"
                    dnd-sortable [sortableIndex]="i">{{item}}</li>
                </ul>
            </div>
        </div>
    </div>
    <div class="col-sm-6">
        <div class="panel panel-default">
            <div class="panel-body" dnd-sortable-container [dropZones]="['delete-dropZone']" [sortableData]="listRecycled">
                Recycle bin: Drag into me to delete it<br/>
            </div>
        </div>
        <div *ngIf="listRecycled.length">
        <b>Recycled:</b> <span>{{listRecycled.toString()}} </span>
        </div>
    </div>
</div>`
})
export class RecycleMultiSortableComponent {
    listOne: Array<string> = ['Coffee', 'Orange Juice', 'Red Wine', 'Unhealty drink!', 'Water'];
    listRecycled: Array<string> = [];
}

12. Simple sortable With Drop into something, without delete it

Here is an example of simple sortable list of items copying in target container:

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

@Component({
    selector: 'simple-sortable-copy',
    template: `
<h4>Simple sortable With Drop into something, without delete it</h4>
<div class="row">
    <div class="col-sm-3">
        <div class="panel panel-warning"
            dnd-sortable-container [sortableData]="sourceList" [dropZones]="['source-dropZone']">
            <div class="panel-heading">Source List</div>
            <div class="panel-body">
                <ul class="list-group">
                    <li *ngFor="let source of sourceList; let x = index" class="list-group-item"
                        dnd-sortable [sortableIndex]="x" [dragEnabled]="true"
                        [dragData]="source">{{source.name}}</li>
                </ul>
            </div>
        </div>
    </div>
    <div class="col-sm-6">
        <div class="panel panel-info">
            <div class="panel-heading">Target List</div>
            <div class="panel-body" dnd-droppable (onDropSuccess)="addTo($event)" [dropZones]="['source-dropZone']">
                <ul class="list-group">
                    <li *ngFor="let target of targetList" class="list-group-item">
                        {{target.name}}
                    </li>
                </ul>
            </div>
        </div>
    </div>
</div>`
})
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) {}
}

13. 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:

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

@Component({
    selector: 'embedded-sortable',
    template: `
<h4>Move items between multi list sortable containers</h4>
<div class="row">
    <div class="col-sm-3">
        Drag Containers <input type="checkbox" [(ngModel)]="dragOperation"/>
        <div dnd-sortable-container [sortableData]="containers" [dropZones]="['container-dropZone']">
            <div class="col-sm3"
                    *ngFor="let container of containers; let i = index"
                    dnd-sortable [sortableIndex]="i" [dragEnabled]="dragOperation">
                <div class="panel panel-warning"
                    dnd-sortable-container [sortableData]="container.widgets" [dropZones]="['widget-dropZone']">
                    <div class="panel-heading">
                        {{container.id}} - {{container.name}}
                    </div>
                    <div class="panel-body">
                        <ul class="list-group">
                            <li *ngFor="let widget of container.widgets; let x = index" class="list-group-item"
                                dnd-sortable [sortableIndex]="x" [dragEnabled]="!dragOperation"
                                [dragData]="widget">{{widget.name}}</li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="col-sm-6">
        <div class="panel panel-info">
            <div class="panel-heading">Widgets</div>
            <div class="panel-body" dnd-droppable (onDropSuccess)="addTo($event)" [dropZones]="['widget-dropZone']">
                <div *ngFor="let widget of widgets" class="panel panel-default">
                    <div class="panel-body">
                        {{widget.name}}
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>`
})
export class EmbeddedSortableComponent {
    dragOperation: boolean = false;

    containers: Array<Container> = [
        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<Widget> = [];
    addTo($event: any) {
        if ($event) {
            this.widgets.push($event.dragData);
        }
    }
}

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

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

14. Simple FormArray sortable with Drag-and-Drop

Here is an example of simple sortable of favorite drinks moving in container via drag and drop operation but using FormArray instead of Array:

import {Component} from '@angular/core';
import {FormArray, FormControl} from '@angular/forms';

@Component({
    selector: 'simple-formarray-sortable',
    template: `
<h4>Simple FormArray sortable</h4>
<div class="row">
    <div class="col-sm-3">
        <div class="panel panel-success">
            <div class="panel-heading">
                Favorite drinks
            </div>
            <div class="panel-body">
                <ul class="list-group" dnd-sortable-container [sortableData]="listOne">
                    <li *ngFor="let item of listOne.controls; let i = index" class="list-group-item" dnd-sortable [sortableIndex]="i"><input type="text" [formControl]="item"></li>
                </ul>
            </div>
        </div>
    </div>
    <div class="col-sm-6">
        <div class="panel panel-default">
            <div class="panel-body">
                My prefences:<br/>
                <span *ngFor="let item of listOne.controls; let i = index">{{i + 1}}) {{item.value}}<br/></span>
            </div>
        </div>
    </div>
</div>`
})
export class SimpleFormArraySortableComponent {
    listOne: FormArray = new FormArray([
      new FormControl('Coffee'),
      new FormControl('Orange Juice'),
      new FormControl('Red Wine'),
      new FormControl('Unhealty drink!'),
      new FormControl('Water')
    ]);
}

How to pass multiple data in dragData while dragging ?

  1. As an array:
[dragData]="[aComponent,'component-in-bar']"
loadComponent($event){
    console.log($event.dragData[0]); // aComponent 
    console.log($event.dragData[1]); // 'component-in-bar' OR 'component-in-designer' 
}
  1. As an object:
[dragData]="{component: aComponent, location: 'component-in-bar'}"
loadComponent($event){
    console.log($event.dragData.component); // aComponent 
    console.log($event.dragData.location); // 'component-in-bar' OR 'component-in-designer' 
}

Retreiving files in a drop zone

Since it is possible to drag and drop one or more files to a drop zone, you need to handle the incoming files.

import {Component} from '@angular/core';
import {Http, Headers} from '@angular/http';
import {DND_PROVIDERS, DND_DIRECTIVES} from 'ng2-dnd/ng2-dnd';
import {bootstrap} from '@angular/platform-browser-dynamic';

bootstrap(AppComponent, [
    DND_PROVIDERS // It is required to have 1 unique instance of your service
]);

@Component({
    selector: 'app',
    directives: [DND_DIRECTIVES],
    template: `
<h4>Simple Drag-and-Drop</h4>
<div class="row">
   
    <div class="col-sm-3">
        <div dnd-droppable class="panel panel-info"
            (onDropSuccess)="transferDataSuccess($event)">>
            <div class="panel-heading">Place to drop</div>
            <div class="panel-body">
            </div>
        </div>
    </div>
</div>
`
})
export class AppComponent {

  constructor(private _http: Http) { }

   /**
   * The $event is a structure:
   * {
   *   dragData: any,
   *   mouseEvent: MouseEvent
   * }
   */
  transferDataSuccess($event) {
    // let attachmentUploadUrl = 'assets/data/offerspec/offerspec.json';
    // loading the FileList from the dataTransfer
    let dataTransfer: DataTransfer = $event.mouseEvent.dataTransfer;
    if (dataTransfer && dataTransfer.files) {
      
      // needed to support posting binaries and usual form values
      let headers = new Headers();
      headers.append('Content-Type', 'multipart/form-data');

      let files: FileList = dataTransfer.files;
  
      // uploading the files one by one asynchrounusly
      for (let i = 0; i < files.length; i++) {
        let file: File = files[i];
  
        // just for debugging
        console.log('Name: ' + file.name + '\n Type: ' + file.type + '\n Size: ' + file.size + '\n Date: ' + file.lastModifiedDate);
  
        // collecting the data to post
        var data = new FormData();
        data.append('file', file);
        data.append('fileName', file.name);
        data.append('fileSize', file.size);
        data.append('fileType', file.type);
        data.append('fileLastMod', file.lastModifiedDate);
  
        // posting the data
        this._http
          .post(attachmentUploadUrl, data, {
            headers: headers
          })
          .toPromise()
          .catch(reason => {
            console.log(JSON.stringify(reason));
          });
      }
    }
  }
}

# Credits
- [Francesco Cina](https://github.com/ufoscout)
- [Valerii Kuznetsov](https://github.com/solival)
- [Shane Oborn](https://github.com/obosha)
- [Juergen Gutsch](https://github.com/JuergenGutsch)
- [Damjan Cilenšek](https://github.com/loudandwicked)

# License
 [MIT](/LICENSE)

ng2-dnd's People

Contributors

adrienverge avatar akserg avatar brocco avatar chpoit avatar delfil avatar hlobil avatar j-ew-s avatar juergengutsch avatar loudandwicked avatar rmcsharry avatar tsu-la avatar zolekm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ng2-dnd's Issues

Drop is not working

I have try your first example, the drag is working, but not the drop.

I have try with [dropEnabled]="true" too.

No errors in the javascript console.

Thx

Events in the Sortable feature

  • I'm submitting a ...
    [ ] bug report
    [ ] feature request
    [x] question about the decisions made in the repository

I want to know that is there any events in the sorting feature?

I want to sort the data on server side as soon as I sort any element on client side.

Modifying dataTransfert.effectAllowed

Hello ! Thank you for this really useful module.

I'm facing a problem when trying to change the effect when dragging and dropping.
Is there any way to change the config by passing an argument like 'effectAllowed' ?
For example, something like that :

<div dnd-sortable-container [sortableData]="el" [dropZones]="['zone1']">
    <div *ngFor="#e of el; #ie=index" dnd-sortable [sortableIndex]="ie" [effectAllowed]="copy">
        <div>{{e}}</div>
    </div>
</div>

Thanks in advance !

drag start not emitting events

I need to get on dragStart event on sortable. I see it's in the code but it's commented.
Any particular reason? Could we have this enabled?

Thanks so much

How to pass multiple data in dragData while dragging ?

I want to know whether it is possible to pass multiple arguments in dragData ?
For eg.

I want to drag a component from multiple locations so I tried doing something like this.
[dragData]="aComponent,'component-in-bar'"
[dragData]="aComponent,'component-in-designer'"

so When I am catching the event , I could do something like this:
dnd-droppable (onDropSuccess)="loadComponent($event)"

loadComponent($event){ console.log($event.dragData.aComponent); console.log($event.dragData.location); // 'component-in-bar OR component-in-designer }

not working in angular2 rc1

I was trying this demo.but when I am trying to import ng2-dnd module its giving me errors.Also systemjs configuration is not updated according to angular2 rc1. if anyoneone could help .it will be great

DnD in tree structure

  • I'm submitting a ...
    [x] bug report
    [x] feature request
    [ ] question about the decisions made in the repository
  • What is the current behavior?
    I need to support DnD in a tree structure where every node may be a dnd_draggable and dnd_droppable. I could not manage it. I tried differen configuration but most often drop is not allowed (_isDropAllowed()) because it's executed in the draggable-components context. The onDragSuccess-event is never fired. How do I configure ng2-dnd in a tree structure where a node is a node could be a dnd-source and destination?
  • Angular version: 2.0.0-rc.2

Modify the item being dragged

I apologize in advance for skipping the template as it did not seem to accommodate asking a question.

Is there a way to get a handle (CSS selector) to the item being dragged?

I would like to add some additional styles to the item being dragged and have not been able to determine the best course of action. I'd prefer to not use dragImage as I love the idea of showing dynamic content on the item being dragged.

If that does exist then I guess I'm suggesting a feature of adding a class dnd-drag-item to the DOM element being dragged.

Not able to add dropZones

I'm using angular webpack starter with angular2 beta.9 and ng2-dnd 1.0.4 and have this html

<div>
    <h2>Menu</h2>
    <ul id="menu">
      <li dnd-droppable [dropZones]="['xxx']">Menu1</li>
      <li dnd-droppable [dropZones]="['yyy']">Menu2</li>
      <li dnd-droppable [dropZones]="['yyy']">Menu3</li>
    </ul>
  <div>
  <br><br>
  <div id="dashboard">
    <h2>Dashboard</h2>
    <div id="container" class="containerX" dnd-draggable [dragEnabled]="true">
      <p>Container1:</p>
      <div id="widgets">
        <div class="widgetX" dnd-draggable [dragEnabled]="true" [dropZones]="['xxx']">Widget 1</div>
        <div class="widgetX" dnd-draggable [dragEnabled]="true" [dropZones]="['xxx']">Widget 2</div>
        <div class="widgetX" dnd-draggable [dragEnabled]="true" [dropZones]="['xxx']">Widget 3</div>
        <div class="widgetX" dnd-draggable [dragEnabled]="true" [dropZones]="['xxx']">Widget 4</div>
      </div>
    </div>

    <div id="container" class="containerX" dnd-draggable [dragEnabled]="true">
      <p>Container2:</p>
      <div id="widgets">
        <div class="widgetX" dnd-draggable [dragEnabled]="true" [dropZones]="['yyy']">Widget 5</div>
        <div class="widgetX" dnd-draggable [dragEnabled]="true" [dropZones]="['yyy']">Widget 6</div>
        <div class="widgetX" dnd-draggable [dragEnabled]="true" [dropZones]="['yyy']">Widget 7</div>
        <div class="widgetX" dnd-draggable [dragEnabled]="true" [dropZones]="['yyy']">Widget 8</div>
      </div>
    </div>

    <div id="container" class="containerX" dnd-draggable [dragEnabled]="true">
      <p>Container3:</p>
      <div id="widgets">
        <div class="widgetX" dnd-draggable [dragEnabled]="true" [dropZones]="['xxx']">Widget 9</div>
        <div class="widgetX" dnd-draggable [dragEnabled]="true" [dropZones]="['xxx']">Widget 10</div>
        <div class="widgetX" dnd-draggable [dragEnabled]="true" [dropZones]="['xxx']">Widget 11</div>
        <div class="widgetX" dnd-draggable [dragEnabled]="true" [dropZones]="['xxx']">Widget 12</div>
      </div>
    </div>
  </div>

I would like to drag the widgets into the sub menus, in my case the widget from container1 and 3 into Menu1.
But in some way the declaration of [dropZones] in dnd-draggable seam to not work

in private _isDropAllowed(): boolean { in dnd.droppable.ts the value for this._dragDropService.allowedDropZones.length is always 0

I'm doing something wrong?

Update README for latest release

Developers found inconsistency between README file and the source code:

I found the problem, in your sample code your sent the $event to addToBasket() method but you worked on it as a newProduct but you need to assign e.dataDrag to newProduct.

How to use bundled ng2-dnd.js?

  • I'm submitting a ...
    [ ] bug report
    [ ] feature request
    [x] question about the decisions made in the repository

  • What is the current behavior?
    SystemJS isn't able to find registered modules from the bundle.

  • If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar.
    See https://github.com/martinsik/ng2-systemjs-demo

  • What is the expected behavior?
    Loading just ng2-dnd.js bundle should be enough to import ng2-dnd/ng2-dnd.

  • What is the motivation / use case for changing the behavior?
    I'm trying to figure out how to use the bundled version of ng2-dnd. I'd expect that I can just add bundle option to systemjs.config.js. I tried to update the ng2-systemjs-demo demo https://github.com/martinsik/ng2-systemjs-demo and switch from using the unpacked ng2-dnd from node_modules to bundled ng2-dnd.js.
    I'm supposed to import ng2-dnd/ng2-dnd but the main module is registered to SystemJS as ng2-dnd (see line 743) so I don't think it's able to load it properly (even though the js file is found and loaded propertly).
    Another thing is that one of the modules defines as its dependency @angular/common/src/facade/lang (line 519) which is not exposed by the bundled common.umd.js package so even if I change module names in ng2-dnd.js manualy it throws an error because it's not able to load @angular/common/src/facade/lang. The original ng2-systemjs-demo works because it loads angular2 modules from node_modules.

    At the end I was able to run in with two modifications:

    • prepend ng2-dnd to all module names (eg: ng2-dnd/src/dnd.sortable or ng2-dnd/ng2-dnd for the main module).
    • remove @angular/common/src/facade/lang dependency and isPresent function.

    Then add bundle option to SystemJS config:

    var config = {
        bundles: {
            '/path-to-bundles/ng2-dnd.js': ['ng2-dnd/ng2-dnd'],
        }
    }
    

    and it works. Maybe I'm just stupid and I could solve all this with SystemJS config but I tried to follow the same structure as generated by ng2-file-upload package which seems to me very understandable.

  • Angular version: 2.0.0-rc.1

  • Browser: all

Drag-and-Drop doesn't work on IE 11

When starts dragging the browser prompts with following exception:

EXCEPTION: Error: Unexpected call to method or property access.
   EXCEPTION: Error: Unexpected call to method or property access.
   STACKTRACE:
   Error: Unexpected call to method or property access.
   at _elem.ondragstart (http://akserg.github.io/ng2-webpack-demo/boot.1fc11a8a003f8c49b196.bundle.js:504:18)
   at Zone.prototype.run (http://akserg.github.io/ng2-webpack-demo/polyfills.f737c0c46c4580435f22.bundle.js:8959:15)
   at Anonymous function (http://akserg.github.io/ng2-webpack-demo/vendor.758044ce30c8786a3ac1.bundle.js:12567:26)
   at zoneBoundFn (http://akserg.github.io/ng2-webpack-demo/polyfills.f737c0c46c4580435f22.bundle.js:8936:15)

SCRIPT65535: Unexpected call to method or property access.
File: vendor.758044ce30c8786a3ac1.bundle.js, Line: 18850, Column: 14

How to drag and drop when add new row in table

Hi all!

I have a table list, and i set ng2-dnd is run good!
But i have 1 button when click auto add new row to table, after add row done i can not drag and drop this row.

pls help me, thanks a lot

Multi-list sortable with nested lists

I have a situation similar to the multi-list sortable in the demo except that the target list contains nested lists and items may be dragged from the available boxers panel into any of the nested lists in the First Team panel, including the First Team panel itself. I'm not sure how to achieve that. So far everything just gets dropped into the my equivalent of the First Team panel instead of the nested panel.

I was hoping for behavior similar to this

Drag & Drop on same list

Is it possible to drag and drop in the same list?

Same as how sorting works, with an abbility to switch item from position 1 to position 4 in one click.

Failed to execute 'removeChild' on 'Node': parameter 1 is not of type 'Node'.

  • I'm submitting a ...
    [x] bug report
    [ ] feature request
    [ ] question about the decisions made in the repository
  • Do you want to request a feature or report a bug?
  • What is the current behavior?
    Generate an exception:
    dnd.component.ts:155 Uncaught TypeError: Failed to execute 'removeChild' on 'Node': parameter 1 is not of type 'Node'.AbstractComponent._elem.ondragend @ dnd.component.ts:155
  • If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar.
  • What is the expected behavior?
  • What is the motivation / use case for changing the behavior?
  • Please tell us about your environment:
  • Angular version: 2.0.0-rc.X
  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)

Fix bizarre packaging strategy

  • I'm submitting a ...
    [ ] bug report
    [ ] feature request
    [ x ] question about the decisions made in the repository
  • Do you want to request a feature or report a bug?

Neither!

  • What is the current behavior?

Importing ng2-dnd with System.js as per the setup instructions detailed in readme.md results in the creation of an unwanted node_modules folder in the output.

  • What is the expected behavior?

Can import the package without the creation of excess files polluting my app.

  • What is the motivation / use case for changing the behavior?

This is the first time I've discovered a package doing this, and it doesn't seem like a best practice or good idea. We shouldn't be mixing libraries and our code, and this package encourages that by default.

  • Please tell us about your environment:
  • Typescript 1.8.10
  • Angular version: 2.0.0-rc.4
  • Webstorm 2016

tsconfig.json:

{
  "compileOnSave": true,
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false,
    "outDir":"public/angular"
  },
  "exclude": [
    "node_modules",
    "vendor",
    "typings"
  ]
}
  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)

Should be able to import a bundled js file instead.

Simple sortable example error while random text dropped

First of all, excellent work!!

On the Drag and Drop example page (http://akserg.github.io/ng2-webpack-demo/#/dnd), the 'Simple sortable' example will error out if I randomly select some text on the page and drop into the sortable container.

This is for ng2-dnd version 1.4.1.

Error message:

TypeError: Cannot read property 'next' of undefined(…)
!!! Suggestion: Seems you forget add into your html?
Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.
EXCEPTION: TypeError: Cannot read property 'undefined' of undefined
EXCEPTION: TypeError: Cannot read property 'undefined' of undefined
STACKTRACE:
TypeError: Cannot read property 'undefined' of undefined
at SortableComponent._onDragEnterCallback (dnd.sortable.ts:135)
at SortableComponent.AbstractComponent._onDragEnter (dnd.component.ts:104)
at HTMLLIElement.AbstractComponent._elem.ondragenter (dnd.component.ts:46)
at HTMLLIElement.wrapFn as _ondragenter
at ZoneDelegate.invokeTask (zone.js:341)
at Object.NgZoneImpl.inner.inner.fork.onInvokeTask (ng_zone_impl.ts:54)
at ZoneDelegate.invokeTask (zone.js:340)
at Zone.runTask (zone.js:238)
at HTMLLIElement.ZoneTask.invoke (zone.js:408)
Uncaught TypeError: Cannot read property 'undefined' of undefined

Drop zones are draggable by default

  • I'm submitting a ...
    [*] bug report
    [ ] feature request
    [ ] question about the decisions made in the repository
  • Do you want to request a feature or report a bug?
    Bug
  • What is the current behavior?
    Drop zones are draggable by default because a draggable attribute is added to a drop zone.
  • If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar.
    Add [dnd-droppable] to an element
  • What is the expected behavior?
    Drop zones should not be draggable.
  • What is the motivation / use case for changing the behavior?
    Drop zones should only allow dropping other draggables, not be draggable itself.
  • Please tell us about your environment:
  • Angular version: 2.0.0-rc.1
  • Browser: all
  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)
    Now the AbstractComponent sets `this.dragEnabled = true;' on line 63. The draggable component also sets the dragEnabled property. I think the draggable component should be the only one that sets dragEnabled to true so line 63 of AbstractComponent can be removed.

Using ng2DnD with dynamic components.

Sorry for asking here and skipping guide line. As I don't know where to ask question.

I am trying to implement sortable version of dnd. So, I cam move containers and boxes within containers. Last option in example.

But issue is we are having dynamic component for container as well as boxes under them are also dynamic components. So, we can't find index over the head. Because of this things are not working.

Two questions:

  • Is it possible with dynamic component? If yes, any article or guidance how to use it?
  • If not any work around or should be think of ditching dynamic components?

Please let me know if any further details are required.

Regards,
Kunjan Dalal

Display a tool-tip before dropping an element

  • I'm submitting a ...
    [ ] feature request that whenever I am dropping an item on any element , I should get a tooltip message "Drop Here".
  • What is the expected behavior?
    I am dragging and dropping components from component-list and I am able to drop them in certain area.what I am willing to do next is when I am dropping content over certain region that area should display a tool-tip "Drop Here" .
  • Please tell us about your environment:
    I am using angular2-rc1 with angular-cli.
  • Angular version: 2.0.0-rc.1
  • Browser: [Chrome ]

any inputs on this?

Dragging files to a drop zone

  • I'm submitting a ...
    [ ] bug report
    [ x] feature request
    [ ] question about the decisions made in the repository
  • Do you want to request a feature or report a bug?
    feature
  • What is the current behavior?
    When dropping one or more files on a drop zone, nothing happened. It works fine with dropped elements.
  • What is the expected behavior?
    Would like to see a list of JavaScript file objects in the §event or in the $event.dragData
  • What is the motivation / use case for changing the behavior?
    Would like to upload file using drop zones
  • Please tell us about your environment:
  • Angular version: 2.0.0-rc.3
  • Browser: all

[Question] How to sort dragged dropped elements

I have 2 columns.

In the left column I have multiple dnd-draggable elements.
The right column is the DropZone, dragging and dropping the elements from the left to the right column works perfect.

But I would like to be able to sort the elements that have been dropped in the DropZone, is this possible?

Peerinvalid

Hello,

When I'm trying to install ng2-dnd, I get the following errors:

npm ERR! Darwin 14.5.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install" "ng2-dnd" "--save"
npm ERR! node v4.4.1
npm ERR! npm  v2.14.20
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package [email protected] does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants es6-shim@^0.35.0
npm ERR! peerinvalid Peer [email protected] wants es6-shim@~0.33.3

Can someone help me solve this ? :)

Custom dragImage

Hello, can you provide us with feature customization dragImage?
I can't find any @output for this purpose. I tried to extend DragImage class, maybe, for overriding constructor function, but it seems, that it is not easy way (through 'bootstrap' and 'provide'). Is it possible with current implementation? Thank you!

counter intuitive bahaviour when dropping a sortable outside the list

When pulling a sortable outside the list (drop zone) and releasing it (dragend event, not dragsuccess)
the browser animates the dragged item back to its original position while it stays in the last acquired sorted position in the list.

example

----------------(upper bound)
1
2
3
4
----------------(lower bound)

drop here outside sortable-container

dragging the "2" across the lower bound and dropping it there causes an animation in the browser, that guides the "2" back to its original position behind the 1, while the list is reordered as follows:

1
3
4
2

that confuses me, and I have the feeling that the sorting should only be applied when dragsuccess event is emitted, or at least there should be some means to choose between the two behaviors (with some directive for example).

package should not have angular as dependency (but devDependency)

  • I'm submitting a ...
    [ x ] bug report
    [ x ] feature request
    [ ] question about the decisions made in the repository
  • Do you want to request a feature or report a bug?
    The version of the plugin is tied to a particular Angular version as we can see in the package.json (currently RC4). Therefore this plugin is using the RC4 version when resolving internal dependencies even so the main application may have a different version.
    Current side effect, is that RC5 is a breaking update compared to RC4 and this plugin does not work in RC5 even so the base code is fully compatible - because as mentioned before, the plugin is using RC4 dependencies. In my case, I'm currently running my app in RC5 (or what is available so far from RC5) and I had to remove the node_modules in order to "fix" the issue (by removing node_modules, it resolves now automatically to my real own angular version).

Long story short, my suggestion would be to simply move the dependencies into devDependencies to avoid such issues.

Cannot drag items into empty (dnd-sortable-container) that initialized with items

  • I'm submitting a ...
    [x] bug report
    [ ] feature request
    [ ] question about the decisions made in the repository
  • Do you want to request a feature or report a bug?
    Bug
  • What is the current behavior?
    If you drag all dnd-sortable from a dnd-sortable-container (thus emptying it) you can no longer drag items back into this dnd-sortable-container. If the dnd-sortable-container initialized as empty, it works as expected
  • If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem
    On the Demo site http://akserg.github.io/ng2-webpack-demo/#/dnd either, "Multi list sortable" or "Simple sortable With Drop into something, without delete it" example. -- In the case of "Multi list sortable" 1. Drag all items from "Available boxers" into other containers (First or Second Team), 2. Then try to drag these items back to "Available boxers." Notice: First/Second team (which initialized empty) work as expected.
  • What is the expected behavior?
    Items should be able to be dragged back into (empty) containers that initialized with items.
  • What is the motivation / use case for changing the behavior?
    NA
  • Please tell us about your environment:
    Bug is apparent even in Demo site
  • Angular version: 2.0.0-rc.2, using Angular-CLI
  • Browser: Chrome:51.0.2704.79 Firefox:48.0a2 (2016-06-01) IE:11.306.10586
  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix)
    NA

Multiple Drag and Drop Feature

  • I'm submitting a ...
    [ ] bug report
    [x ] feature request
    [ ] question about the decisions made in the repository

Will multiple Drag & Drop from 1 container to a drop zone be on the roadmap?

  • What is the current behavior?
    Is it not supported.
  • What is the motivation / use case for changing the behavior?
    We have a number of requirement that need to select multiple items in one container and drag them to a drop zone all at the same tine,
  • Please tell us about your environment:
    Angular2 RC4/ Net Core
  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
    all

Angular RC5

  • I'm submitting a ...
    [x] bug report
  • Do you want to request a feature or report a bug?
    Is possible to have dnd working for angular rc5?
    Actually it doesn't work if you put the drag in one module and the drop in another one.

Example:
@NgModule({
imports: [
PageManagerModule
],
declarations: [
Charts,
DND_DIRECTIVES
]

Charts contains the drag and PageManager contain the drop.
I'm able to drag but not able to drop.

  • What is the current behavior?
  • If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar.
  • What is the expected behavior?
  • What is the motivation / use case for changing the behavior?
  • Please tell us about your environment:
  • Angular version: 2.0.0-rc.X
  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)

change libraries to @angular/core, etc

The package.json file correctly requires @angular modules as dependencies for 2.0.0-rc.1.

However, the individual files, like dnd.service.ts still import from
angular2/core
angular2/src/facade/lang

I believe that they should be importing from @angular

Sort the items with nested lists

I came across a situation where i need to do sorting in the respective children in the custom tree view. sorting is happening for the parent nodes but not for the child nodes.

[Question] - How use drop and sort together

I have object of arrays

{
'group1' => [
{'name': 'some1'},{'name': 'some2'},{'name': 'some3'}
],
'group2' => [{'name': 'some4'}, {'name': 'some5'}],
'group2' => []
}

all elements are listed in one table (original is more fields). For each group is created new tbody which is drop container.

onDropSuccess I'd like move element from one to another group but also for each of this group I'd like make elements sortable. Sort function also using onDropSuccess.

Does it possible to make make multigroup sortable with moving between groups?

Weird behaviour when container becomes empty

I'm facing weird behaviour for droppable container. When I drop all the items from one container to another, means I emptied first container. After this I'm unable to add back items from second container to first one, the empty one. I'm unable to do so.

Am I missing something? Or it is default behaviour?

Nested Sort-ables

I'm after some help, is it possible to have a nested sort-able drag and drop?

I have one list of groups, which is sort-able, each group contains a list of fields which is sort-able. You shouldn't be able to move a group into a field list, or a field into the group list.

<div dnd-sortable-container [sortableData]="module.groups" class="group card" *ngFor="let group of module.groups; let i = index">
    <div class="card-block" dnd-sortable [sortableIndex]="i">
        <div class="card-title">
            <h5>{{ group.name }}</h5>
        </div>
        <div>
            <div dnd-sortable-container [sortableData]="group.fields" *ngFor="let field of group.fields; let i = index">
                <div dnd-sortable [sortableIndex]="i">
                    <span class="text-capitalize">{{ field.name }} - {{ field.type }}</span>
                </div>
            </div>
        </div>
    </div>
</div>

I tried to use drop zones with the sort-able tags but I get errors "Can't bind to 'dropZones' since it isn't a known property of 'div'."

Is it possible to get such a setup working?

Please tell us about your environment:

  • Angular version: 2.0.0-rc.5
  • Browser: Chrome Version 52.0.2743.116 m (64-bit)

EXCEPTION: Attempt to use a dehydrated detector.

I am getting this exception.
It is most likely my mistake of how I configured everything. But have you seen this before ?
I am trying to update an array when the drop is done and same component uses that array to display the lists (it is a calendar kind of component).

styling the clone element without affecting the actual dragged element

Hi, first of all i would like to thank you for this useful module.

As per my requirement i have to give custom style to the the cloned element without affecting the actual dragged element.I was trying to add style to "dnd-drag-start" class as this class is being added to the dragged element while dragging.but it changes the style for both the actual element and cloned element.

it would be very nice if you can help me to solve this issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.