{"_id":"@advisorstream/ng2-dnd","_rev":"1-ddbf3f94a5b02cc87991bf19e912b840","name":"@advisorstream/ng2-dnd","dist-tags":{"latest":"8.2.14"},"versions":{"8.2.14":{"name":"@advisorstream/ng2-dnd","description":"Angular 2 Drag-and-Drop without dependencies","version":"8.2.14","repository":{"type":"git","url":"git+https://github.com/AdvisorStream/ng2-dnd.git"},"keywords":["angular","angular2","angular 2","drag","drop","drag-and-drop"],"author":{"name":"Sergey Akopkokhyants","email":"akserg@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/AdvisorStream/ng2-dnd/issues"},"main":"bundles/advisorstream-ng2-dnd.umd.js","module":"fesm5/advisorstream-ng2-dnd.js","typings":"advisorstream-ng2-dnd.d.ts","homepage":"https://github.com/AdvisorStream/ng2-dnd#readme","peerDependencies":{"@angular/core":"~8.2.14","@angular/forms":"~8.2.14"},"devDependencies":{"@angular/animations":"~8.2.14","@angular/common":"~8.2.14","@angular/compiler":"~8.2.14","@angular/compiler-cli":"~8.2.14","@angular/core":"~8.2.14","@angular/forms":"~8.2.14","@angular/platform-browser":"~8.2.14","@angular/platform-browser-dynamic":"~8.2.14","@angular/platform-server":"~8.2.14","@types/hammerjs":"^2.0.36","@types/jasmine":"~3.3.8","@types/node":"~8.9.4","awesome-typescript-loader":"^5.2.0","codelyzer":"^5.0.0","core-js":"^3.4.5","istanbul-instrumenter-loader":"^3.0.1","jasmine-core":"~3.4.0","karma":"~4.1.0","karma-chrome-launcher":"^3.1.0","karma-coverage":"^2.0.1","karma-firefox-launcher":"^1.2.0","karma-jasmine":"~2.0.1","karma-mocha-reporter":"^2.2.5","karma-remap-coverage":"~0.1.5","karma-sourcemap-loader":"^0.3.7","karma-webpack":"^4.0.2","loader-utils":"^1.2.3","ng-packagr":"^5.5.0","reflect-metadata":"^0.1.13","rxjs":"~6.4.0","source-map-loader":"^0.2.4","ts-helpers":"1.1.2","tslint":"~5.15.0","tslint-loader":"^3.5.4","typescript":"~3.5.3","webpack":"^4.41.2","zone.js":"~0.9.1"},"engines":{"npm":">6.0.0"},"es2015":"fesm2015/advisorstream-ng2-dnd.js","esm5":"esm5/advisorstream-ng2-dnd.js","esm2015":"esm2015/advisorstream-ng2-dnd.js","fesm5":"fesm5/advisorstream-ng2-dnd.js","fesm2015":"fesm2015/advisorstream-ng2-dnd.js","metadata":"advisorstream-ng2-dnd.metadata.json","sideEffects":false,"dependencies":{"tslib":"^1.9.0"},"_id":"@advisorstream/ng2-dnd@8.2.14","_nodeVersion":"10.17.0","_npmVersion":"6.13.1","dist":{"integrity":"sha512-fscYjg4ijAhyxftvvkV9sE6dqCIVg7ABXH73QjzKW6TloBiRKhGtAXPvPa2BzorfKYIm18B3jJd0Lvr1hoHUwg==","shasum":"751d3e31bb5297575b8afa759c246827af2a1b52","tarball":"https://registry.npmjs.org/@advisorstream/ng2-dnd/-/ng2-dnd-8.2.14.tgz","fileCount":43,"unpackedSize":721158,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd5uSvCRA9TVsSAnZWagAAcYQP/iLL2AWEnTRYGxELxsxP\n3DB2PPnPalPNLKUZIv9AgI4MPVz+p3Syiow6mG6OSiZI/Zxl9CQ+x+ZqnOqt\n+ZkbQB571B++IVyQ2GPf1AcWj48As91Mt9nGPwIcw+68oA40UsDsjkSunlQq\nOlwZs9Srn1G/MYs0zsxi4882hw0SgIN2Ilb0resExR1tXMT4AoZ7BTmLoEzI\ntmhGTEetEGPH3G06y0FdwJ6dIXpnKix9xgH10549NZvKcd+eyK1fQotDU3oP\n2mYcYe31kBPNohAyQKw4r2MOlpcytmSA0lbgguDd/tPeycShtAV8B/tK0P7k\nff1FggyA6VEWDAUoeJeRGnrPEdA/B/V0Bl/2ynIjdt9E0LnSO4dGAQdt+BD3\nRrhJ0wl52OnnUvvep65Ooc2qm6LkWeJfDhZ1ovNbySAjoIoexiwFSUyFK21E\nompqaAFzUqK1D5H3XDmcZPQ/AfK7wMYaQ/LdxVJPMBiXM/ILYBc0hS3yCphf\nwfb0L0i7z+kQplTExuqdKMO1+vZJsT7W2rcqM7eDjLCUX8TdVaSm9B4SQE6X\nFb2LlJb1+YzmaUk7GWb1/r0LmoJJTIG++atQy5ZwNwh6SbBTtU0ewVi/081/\nv5XGSN0LsyGeAszbrbf2tsWqkieu1VuOQl4LkpXxnZaGCCCTW0xfI7IhC7qw\nRBfE\r\n=mTSz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDgLT0kPa4evKtvYc2MBFZt9rOuqamR4DPOYiEZIpaYmQIhAP65u1V98E013/Kaju6wmZWrRbE5ICfX0ghu5JozXMtp"}]},"maintainers":[{"name":"asdevteam","email":"dev@advisorstream.com"}],"_npmUser":{"name":"asdevteam","email":"dev@advisorstream.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/ng2-dnd_8.2.14_1575412911289_0.45906095093626686"},"_hasShrinkwrap":false}},"time":{"created":"2019-12-03T22:41:51.056Z","8.2.14":"2019-12-03T22:41:51.459Z","modified":"2022-04-04T11:46:31.550Z"},"maintainers":[{"name":"asdevteam","email":"dev@advisorstream.com"}],"description":"Angular 2 Drag-and-Drop without dependencies","homepage":"https://github.com/AdvisorStream/ng2-dnd#readme","keywords":["angular","angular2","angular 2","drag","drop","drag-and-drop"],"repository":{"type":"git","url":"git+https://github.com/AdvisorStream/ng2-dnd.git"},"author":{"name":"Sergey Akopkokhyants","email":"akserg@gmail.com"},"bugs":{"url":"https://github.com/AdvisorStream/ng2-dnd/issues"},"license":"MIT","readme":"# Angular 2 Drag-and-Drop [![npm version](https://badge.fury.io/js/ng2-dnd.svg)](https://badge.fury.io/js/ng2-dnd) [![npm monthly downloads](https://img.shields.io/npm/dm/ng2-dnd.svg?style=flat-square)](https://www.npmjs.com/package/ng2-dnd)\nAngular 2 Drag-and-Drop without dependencies.\n\nFollow me [![twitter](https://img.shields.io/twitter/follow/akopkokhyants.svg?style=social&label=%20akopkokhyants)](https://twitter.com/akopkokhyants) to be notified about new releases.\n\n[![Build Status](https://travis-ci.org/akserg/ng2-dnd.svg?branch=master)](https://travis-ci.org/akserg/ng2-dnd)\n[![Dependency Status](https://david-dm.org/akserg/ng2-dnd.svg)](https://david-dm.org/akserg/ng2-dnd)\n[![devDependency Status](https://david-dm.org/akserg/ng2-dnd/dev-status.svg)](https://david-dm.org/akserg/ng2-dnd#info=devDependencies)\n[![Known Vulnerabilities](https://snyk.io/test/github/akserg/ng2-dnd/badge.svg)](https://snyk.io/test/github/akserg/ng2-dnd)\n\n_Some of these APIs and Components are not final and are subject to change!_\n\n## Transpilation to Angular Package Format\nThe library uses [ng-packagr](https://github.com/dherges/ng-packagr) to transpile into the Angular Package Format:\n- Bundles library in `FESM2015`, `FESM5`, and `UMD` formats\n- The npm package can be consumed by `Angular CLI`, `Webpack`, or `SystemJS`\n- Creates type definitions (`.d.ts`)\n- Generates Ahead-of-Time metadata (`.metadata.json`)\n- Auto-discovers and bundles secondary entry points such as `@my/foo`, `@my/foo/testing`, `@my/foo/bar`\n\n## Installation\n```bash\nnpm install @advisorstream/ng2-dnd --save\n```\n\n## Demo\n- Webpack demo available [here](https://angular-dxqjhj.stackblitz.io)\n- SystemJS demo available [here](http://embed.plnkr.co/JbG8Si)\n\n## Usage\nIf you use SystemJS to load your files, you might have to update your config:\n\n```js\nSystem.config({\n    map: {\n        'ng2-dnd': 'node_modules/ng2-dnd/bundles/ng2-dnd.umd.js'\n    }\n});\n```\n\n#### 1. Add the default styles\n- Import the `style.css` into your web page from `node_modules/ng2-dnd/bundles/style.css`\n\n#### 2. Import the `DndModule`\nImport `DndModule.forRoot()` in the NgModule of your application.\nThe `forRoot` method is a convention for modules that provide a singleton service.\n\n```ts\nimport {BrowserModule} from \"@angular/platform-browser\";\nimport {NgModule} from '@angular/core';\nimport {DndModule} from 'ng2-dnd';\n\n@NgModule({\n    imports: [\n        BrowserModule,\n        DndModule.forRoot()\n    ],\n    bootstrap: [AppComponent]\n})\nexport class AppModule {\n}\n```\n\nIf you have multiple NgModules and you use one as a shared NgModule (that you import in all of your other NgModules),\ndon't forget that you can use it to export the `DndModule` that you imported in order to avoid having to import it multiple times.\n\n```ts\n@NgModule({\n    imports: [\n        BrowserModule,\n        DndModule\n    ],\n    exports: [BrowserModule, DndModule],\n})\nexport class SharedModule {\n}\n```\n\n#### 3. Use Drag-and-Drop operations with no code\n\n```js\nimport {Component} from '@angular/core';\n\n@Component({\n    selector: 'simple-dnd',\n    template: `\n<h4>Simple Drag-and-Drop</h4>\n<div class=\"row\">\n    <div class=\"col-sm-3\">\n        <div class=\"panel panel-success\">\n            <div class=\"panel-heading\">Available to drag</div>\n            <div class=\"panel-body\">\n                <div class=\"panel panel-default\" dnd-draggable [dragEnabled]=\"true\">\n                    <div class=\"panel-body\">\n                        <div>Drag Me</div>\n                    </div>\n                </div>\n            </div>\n        </div>\n    </div>\n    <div class=\"col-sm-3\">\n        <div dnd-droppable class=\"panel panel-info\" (onDropSuccess)=\"simpleDrop=$event\">\n            <div class=\"panel-heading\">Place to drop</div>\n            <div class=\"panel-body\">\n                <div *ngIf=\"simpleDrop\">Item was dropped here</div>\n            </div>\n        </div>\n    </div>\n</div>`\n})\nexport class SimpleDndComponent {\n    simpleDrop: any = null;\n}\n```\n\n#### 4. Add handle to restrict draggable zone of component\n\n```js\nimport {Component} from '@angular/core';\n\n@Component({\n    selector: 'simple-dnd-handle',\n    template: `\n<h4>Simple Drag-and-Drop with handle</h4>\n<div class=\"row\">\n    <div class=\"col-sm-3\">\n        <div class=\"panel panel-success\">\n            <div class=\"panel-heading\">Available to drag</div>\n            <div class=\"panel-body\">\n                <div class=\"panel panel-default\" dnd-draggable [dragEnabled]=\"true\">\n                    <div class=\"panel-body\">\n                        <div>\n                            <span dnd-draggable-handle>=</span>&nbsp;\n                            Drag Handle\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n    </div>\n    <div class=\"col-sm-3\">\n        <div dnd-droppable class=\"panel panel-info\" (onDropSuccess)=\"simpleDrop=$event\">\n            <div class=\"panel-heading\">Place to drop</div>\n            <div class=\"panel-body\">\n                <div *ngIf=\"simpleDrop\">Item was dropped here</div>\n            </div>\n        </div>\n    </div>\n</div>`\n})\nexport class SimpleDndHandleComponent {\n    simpleDrop: any = null;\n}\n```\n\n#### 5. Restriction Drag-and-Drop operations with drop zones\nYou can use property *dropZones* (actually an array) to specify in which place you would like to drop the draggable element:\n\n```js\nimport {Component} from '@angular/core';\n\n@Component({\n    selector: 'zone-dnd',\n    template: `\n<h4>Restricted Drag-and-Drop with zones</h4>\n<div class=\"row\">\n    <div class=\"col-sm-3\">\n        <div class=\"panel panel-primary\">\n            <div class=\"panel-heading\">Available to drag</div>\n            <div class=\"panel-body\">\n                <div class=\"panel panel-default\" dnd-draggable [dragEnabled]=\"true\" [dropZones]=\"['zone1']\">\n                    <div class=\"panel-body\">\n                        <div>Drag Me</div>\n                        <div>Zone 1 only</div>\n                    </div>\n                </div>\n            </div>\n        </div>\n\n        <div class=\"panel panel-success\">\n            <div class=\"panel-heading\">Available to drag</div>\n            <div class=\"panel-body\">\n                <div class=\"panel panel-default\" dnd-draggable [dragEnabled]=\"true\" [dropZones]=\"['zone1', 'zone2']\">\n                    <div class=\"panel-body\">\n                        <div>Drag Me</div>\n                        <div>Zone 1 & 2</div>\n                    </div>\n                </div>\n            </div>\n        </div>\n    </div>\n    <div class=\"col-sm-3\">\n        <div dnd-droppable class=\"panel panel-info\" [dropZones]=\"['zone1']\" (onDropSuccess)=\"restrictedDrop1=$event\">\n            <div class=\"panel-heading\">Zone 1</div>\n            <div class=\"panel-body\">\n                <div *ngIf=\"restrictedDrop1\">Item was dropped here</div>\n            </div>\n        </div>\n    </div>\n    <div class=\"col-sm-3\">\n        <div dnd-droppable class=\"panel panel-warning\" [dropZones]=\"['zone2']\" (onDropSuccess)=\"restrictedDrop2=$event\">\n            <div class=\"panel-heading\">Zone 2</div>\n            <div class=\"panel-body\">\n                <div *ngIf=\"restrictedDrop2\">Item was dropped here</div>\n            </div>\n        </div>\n    </div>\n</div>`\n})\nexport class ZoneDndComponent {\n    restrictedDrop1: any = null;\n    restrictedDrop2: any = null;\n}\n```\n\n#### 6. Transfer custom data via Drag-and-Drop\nYou can transfer data from draggable to droppable component via *dragData* property of Draggable component:\n\n```js\nimport {Component} from '@angular/core';\n\n@Component({\n    selector: 'custom-data-dnd',\n    template: `\n<h4>Transfer custom data in Drag-and-Drop</h4>\n<div class=\"row\">\n    <div class=\"col-sm-3\">\n        <div class=\"panel panel-success\">\n            <div class=\"panel-heading\">Available to drag</div>\n            <div class=\"panel-body\">\n                <div class=\"panel panel-default\" dnd-draggable [dragEnabled]=\"true\" [dragData]=\"transferData\">\n                    <div class=\"panel-body\">\n                        <div>Drag Me</div>\n                        <div>{{transferData | json}}</div>\n                    </div>\n                </div>\n            </div>\n        </div>\n    </div>\n    <div class=\"col-sm-3\">\n        <div dnd-droppable class=\"panel panel-info\" (onDropSuccess)=\"transferDataSuccess($event)\">\n            <div class=\"panel-heading\">Place to drop (Items:{{receivedData.length}})</div>\n            <div class=\"panel-body\">\n                <div [hidden]=\"!receivedData.length > 0\" *ngFor=\"let data of receivedData\">{{data | json}}</div>\n            </div>\n        </div>\n    </div>\n</div>`\n})\nexport class CustomDataDndComponent {\n    transferData: Object = {id: 1, msg: 'Hello'};\n    receivedData: Array<any> = [];\n\n    transferDataSuccess($event: any) {\n        this.receivedData.push($event);\n    }\n}\n```\n\n#### 7. Use a custom function to determine where dropping is allowed\nFor 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.\n\nIn 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.\n\n```js\nimport { Component } from '@angular/core';\n\n@Component({\n    selector: 'custom-function-dnd',\n    template: `\n<h4>Use a custom function to determine where dropping is allowed</h4>\n<div class=\"row\">\n    <div class=\"col-sm-3\">\n        <div class=\"panel panel-success\">\n            <div class=\"panel-heading\">Available to drag</div>\n            <div class=\"panel-body\">\n                <div class=\"panel panel-default\" dnd-draggable [dragData]=\"6\">\n                    <div class=\"panel-body\">dragData = 6</div>\n                </div>\n                <div class=\"panel panel-default\" dnd-draggable [dragData]=\"10\">\n                    <div class=\"panel-body\">dragData = 10</div>\n                </div>\n                <div class=\"panel panel-default\" dnd-draggable [dragData]=\"30\">\n                    <div class=\"panel-body\">dragData = 30</div>\n                </div>\n            </div>\n        </div>\n    </div>\n    <div class=\"col-sm-6\">\n        <pre>allowDropFunction(baseInteger: any): any {{ '{' }}\n  return (dragData: any) => dragData % baseInteger === 0;\n{{ '}' }}</pre>\n        <div class=\"row\">\n            <div class=\"col-sm-6\">\n                <div dnd-droppable class=\"panel panel-info\" [allowDrop]=\"allowDropFunction(box1Integer)\" (onDropSuccess)=\"addTobox1Items($event)\">\n                    <div class=\"panel-heading\">\n                        Multiples of\n                        <input type=\"number\" [(ngModel)]=\"box1Integer\" style=\"width: 4em\">\n                        only\n                    </div>\n                    <div class=\"panel-body\">\n                        <div *ngFor=\"let item of box1Items\">dragData = {{item}}</div>\n                    </div>\n                </div>\n            </div>\n            <div class=\"col-sm-6\">\n                <div dnd-droppable class=\"panel panel-warning\" [allowDrop]=\"allowDropFunction(box2Integer)\" (onDropSuccess)=\"addTobox2Items($event)\">\n                    <div class=\"panel-heading\">\n                        Multiples of\n                        <input type=\"number\" [(ngModel)]=\"box2Integer\" style=\"width: 4em\">\n                        only\n                    </div>\n                    <div class=\"panel-body\">\n                        <div *ngFor=\"let item of box2Items\">dragData = {{item}}</div>\n                    </div>\n                </div>\n            </div>\n        </div>\n    </div>\n</div>\n`\n})\nexport class CustomFunctionDndComponent {\n    box1Integer: number = 3;\n    box2Integer: number = 10;\n\n    box1Items: string[] = [];\n    box2Items: string[] = [];\n\n    allowDropFunction(baseInteger: number): any {\n        return (dragData: any) => dragData % baseInteger === 0;\n    }\n\n    addTobox1Items($event: any) {\n        this.box1Items.push($event.dragData);\n    }\n\n    addTobox2Items($event: any) {\n        this.box2Items.push($event.dragData);\n    }\n}\n```\n\n#### 8. Shopping basket with Drag-and-Drop\nHere is an example of shopping backet with products adding via drag and drop operation:\n\n```js\nimport { Component } from '@angular/core';\n\n@Component({\n    selector: 'shoping-basket-dnd',\n    template: `\n<h4>Drag-and-Drop - Shopping basket</h4>\n<div class=\"row\">\n\n    <div class=\"col-sm-3\">\n        <div class=\"panel panel-success\">\n            <div class=\"panel-heading\">Available products</div>\n            <div class=\"panel-body\">\n                <div *ngFor=\"let product of availableProducts\" class=\"panel panel-default\"\n                    dnd-draggable [dragEnabled]=\"product.quantity>0\" [dragData]=\"product\" (onDragSuccess)=\"orderedProduct($event)\" [dropZones]=\"['demo1']\">\n                    <div class=\"panel-body\">\n                        <div [hidden]=\"product.quantity===0\">{{product.name}} - \\${{product.cost}}<br>(available: {{product.quantity}})</div>\n                        <div [hidden]=\"product.quantity>0\"><del>{{product.name}}</del><br>(NOT available)</div>\n                    </div>\n                </div>\n            </div>\n        </div>\n    </div>\n    <div class=\"col-sm-3\">\n        <div dnd-droppable (onDropSuccess)=\"addToBasket($event)\" [dropZones]=\"['demo1']\" class=\"panel panel-info\">\n            <div class=\"panel-heading\">Shopping Basket<br>(to pay: \\${{totalCost()}})</div>\n            <div class=\"panel-body\">\n                <div *ngFor=\"let product of shoppingBasket\" class=\"panel panel-default\">\n                    <div class=\"panel-body\">\n                    {{product.name}}<br>(ordered: {{product.quantity}}<br>cost: \\${{product.cost * product.quantity}})\n                    </div>\n                </div>\n            </div>\n        </div>\n    </div>\n</div>`\n})\nexport class ShoppingBasketDndComponent {\n    availableProducts: Array<Product> = [];\n    shoppingBasket: Array<Product> = [];\n\n    constructor() {\n        this.availableProducts.push(new Product('Blue Shoes', 3, 35));\n        this.availableProducts.push(new Product('Good Jacket', 1, 90));\n        this.availableProducts.push(new Product('Red Shirt', 5, 12));\n        this.availableProducts.push(new Product('Blue Jeans', 4, 60));\n    }\n\n    orderedProduct($event: any) {\n        let orderedProduct: Product = $event.dragData;\n        orderedProduct.quantity--;\n    }\n\n    addToBasket($event: any) {\n        let newProduct: Product = $event.dragData;\n        for (let indx in this.shoppingBasket) {\n            let product: Product = this.shoppingBasket[indx];\n            if (product.name === newProduct.name) {\n                product.quantity++;\n                return;\n            }\n        }\n        this.shoppingBasket.push(new Product(newProduct.name, 1, newProduct.cost));\n        this.shoppingBasket.sort((a: Product, b: Product) => {\n            return a.name.localeCompare(b.name);\n        });\n    }\n\n    totalCost(): number {\n        let cost: number = 0;\n        for (let indx in this.shoppingBasket) {\n            let product: Product = this.shoppingBasket[indx];\n            cost += (product.cost * product.quantity);\n        }\n        return cost;\n    }\n}\n\nclass Product {\n  constructor(public name: string, public quantity: number, public cost: number) {}\n}\n```\n\n#### 9. Simple sortable with Drag-and-Drop\nHere is an example of simple sortable of favorite drinks moving in container via drag and drop operation:\n\n```js\nimport {Component} from '@angular/core';\n\n@Component({\n    selector: 'simple-sortable',\n    template: `\n<h4>Simple sortable</h4>\n<div class=\"row\">\n    <div class=\"col-sm-3\">\n        <div class=\"panel panel-success\">\n            <div class=\"panel-heading\">\n                Favorite drinks\n            </div>\n            <div class=\"panel-body\">\n                <ul class=\"list-group\" dnd-sortable-container [sortableData]=\"listOne\">\n                    <li *ngFor=\"let item of listOne; let i = index\" class=\"list-group-item\" dnd-sortable [sortableIndex]=\"i\">{{item}}</li>\n                </ul>\n            </div>\n        </div>\n    </div>\n    <div class=\"col-sm-6\">\n        <div class=\"panel panel-default\">\n            <div class=\"panel-body\">\n                My prefences:<br/>\n                <span *ngFor=\"let item of listOne; let i = index\">{{i + 1}}) {{item}}<br/></span>\n            </div>\n        </div>\n    </div>\n</div>`\n})\nexport class SimpleSortableComponent {\n    listOne: Array<string> = ['Coffee', 'Orange Juice', 'Red Wine', 'Unhealty drink!', 'Water'];\n}\n```\n\n\n#### 10. Simple sortable with Drag-and-Drop handle\nAdd handle to restict grip zone of sortable component.\n\n```js\nimport {Component} from '@angular/core';\n\n@Component({\n    selector: 'simple-sortable-handle',\n    template: `\n<h4>Simple sortable handle</h4>\n<div class=\"row\">\n    <div class=\"col-sm-3\">\n        <div class=\"panel panel-success\">\n            <div class=\"panel-heading\">\n                Favorite drinks\n            </div>\n            <div class=\"panel-body\">\n                <ul class=\"list-group\" dnd-sortable-container [sortableData]=\"listOne\">\n                    <li *ngFor=\"let item of listOne; let i = index\" class=\"list-group-item\" dnd-sortable [sortableIndex]=\"i\">\n                      <span dnd-sortable-handle>=</span>&nbsp;\n                      {{item}}\n                    </li>\n                </ul>\n            </div>\n        </div>\n    </div>\n    <div class=\"col-sm-6\">\n        <div class=\"panel panel-default\">\n            <div class=\"panel-body\">\n                My prefences:<br/>\n                <span *ngFor=\"let item of listOne; let i = index\">{{i + 1}}) {{item}}<br/></span>\n            </div>\n        </div>\n    </div>\n</div>`\n})\nexport class SimpleSortableHandleComponent {\n    listOne: Array<string> = ['Coffee', 'Orange Juice', 'Red Wine', 'Unhealty drink!', 'Water'];\n}\n```\n\n#### 11. Simple sortable With Drop into recycle bin\nHere is an example of multi list sortable of boxers moving in container and between containers via drag and drop operation:\n\n```js\nimport {Component} from '@angular/core';\n\n@Component({\n    selector: 'recycle-multi-sortable',\n    template: `\n<h4>Simple sortable With Drop into recycle bin</h4>\n<div class=\"row\">\n    <div class=\"col-sm-3\">\n        <div class=\"panel panel-success\">\n            <div class=\"panel-heading\">\n                Favorite drinks\n            </div>\n            <div class=\"panel-body\" dnd-sortable-container [sortableData]=\"listOne\" [dropZones]=\"['delete-dropZone']\">\n                <ul class=\"list-group\">\n                    <li *ngFor=\"let item of listOne; let i = index\" class=\"list-group-item\"\n                    dnd-sortable [sortableIndex]=\"i\">{{item}}</li>\n                </ul>\n            </div>\n        </div>\n    </div>\n    <div class=\"col-sm-6\">\n        <div class=\"panel panel-default\">\n            <div class=\"panel-body\" dnd-sortable-container [dropZones]=\"['delete-dropZone']\" [sortableData]=\"listRecycled\">\n                Recycle bin: Drag into me to delete it<br/>\n            </div>\n        </div>\n        <div *ngIf=\"listRecycled.length\">\n        <b>Recycled:</b> <span>{{listRecycled.toString()}} </span>\n        </div>\n    </div>\n</div>`\n})\nexport class RecycleMultiSortableComponent {\n    listOne: Array<string> = ['Coffee', 'Orange Juice', 'Red Wine', 'Unhealty drink!', 'Water'];\n    listRecycled: Array<string> = [];\n}\n```\n\n#### 12. Simple sortable With Drop into something, without delete it\nHere is an example of simple sortable list of items copying in target container:\n\n```js\nimport {Component} from '@angular/core';\n\n@Component({\n    selector: 'simple-sortable-copy',\n    template: `\n<h4>Simple sortable With Drop into something, without delete it</h4>\n<div class=\"row\">\n    <div class=\"col-sm-3\">\n        <div class=\"panel panel-warning\"\n            dnd-sortable-container [sortableData]=\"sourceList\" [dropZones]=\"['source-dropZone']\">\n            <div class=\"panel-heading\">Source List</div>\n            <div class=\"panel-body\">\n                <ul class=\"list-group\">\n                    <li *ngFor=\"let source of sourceList; let x = index\" class=\"list-group-item\"\n                        dnd-sortable [sortableIndex]=\"x\" [dragEnabled]=\"true\"\n                        [dragData]=\"source\">{{source.name}}</li>\n                </ul>\n            </div>\n        </div>\n    </div>\n    <div class=\"col-sm-6\">\n        <div class=\"panel panel-info\">\n            <div class=\"panel-heading\">Target List</div>\n            <div class=\"panel-body\" dnd-droppable (onDropSuccess)=\"addTo($event)\" [dropZones]=\"['source-dropZone']\">\n                <ul class=\"list-group\">\n                    <li *ngFor=\"let target of targetList\" class=\"list-group-item\">\n                        {{target.name}}\n                    </li>\n                </ul>\n            </div>\n        </div>\n    </div>\n</div>`\n})\nexport class SimpleSortableCopyComponent {\n\n    sourceList: Widget[] = [\n        new Widget('1'), new Widget('2'),\n        new Widget('3'), new Widget('4'),\n        new Widget('5'), new Widget('6')\n    ];\n\n    targetList: Widget[] = [];\n    addTo($event: any) {\n        this.targetList.push($event.dragData);\n    }\n}\n\nclass Widget {\n  constructor(public name: string) {}\n}\n```\n\n#### 13. Multi list sortable between containers\nHere is an example of multi list sortable of boxers moving in container and between containers via drag and drop operation:\n\n```js\nimport {Component} from '@angular/core';\n\n@Component({\n    selector: 'embedded-sortable',\n    template: `\n<h4>Move items between multi list sortable containers</h4>\n<div class=\"row\">\n    <div class=\"col-sm-3\">\n        Drag Containers <input type=\"checkbox\" [(ngModel)]=\"dragOperation\"/>\n        <div dnd-sortable-container [sortableData]=\"containers\" [dropZones]=\"['container-dropZone']\">\n            <div class=\"col-sm3\"\n                    *ngFor=\"let container of containers; let i = index\"\n                    dnd-sortable [sortableIndex]=\"i\" [dragEnabled]=\"dragOperation\">\n                <div class=\"panel panel-warning\"\n                    dnd-sortable-container [sortableData]=\"container.widgets\" [dropZones]=\"['widget-dropZone']\">\n                    <div class=\"panel-heading\">\n                        {{container.id}} - {{container.name}}\n                    </div>\n                    <div class=\"panel-body\">\n                        <ul class=\"list-group\">\n                            <li *ngFor=\"let widget of container.widgets; let x = index\" class=\"list-group-item\"\n                                dnd-sortable [sortableIndex]=\"x\" [dragEnabled]=\"!dragOperation\"\n                                [dragData]=\"widget\">{{widget.name}}</li>\n                        </ul>\n                    </div>\n                </div>\n            </div>\n        </div>\n    </div>\n    <div class=\"col-sm-6\">\n        <div class=\"panel panel-info\">\n            <div class=\"panel-heading\">Widgets</div>\n            <div class=\"panel-body\" dnd-droppable (onDropSuccess)=\"addTo($event)\" [dropZones]=\"['widget-dropZone']\">\n                <div *ngFor=\"let widget of widgets\" class=\"panel panel-default\">\n                    <div class=\"panel-body\">\n                        {{widget.name}}\n                    </div>\n                </div>\n            </div>\n        </div>\n    </div>\n</div>`\n})\nexport class EmbeddedSortableComponent {\n    dragOperation: boolean = false;\n\n    containers: Array<Container> = [\n        new Container(1, 'Container 1', [new Widget('1'), new Widget('2')]),\n        new Container(2, 'Container 2', [new Widget('3'), new Widget('4')]),\n        new Container(3, 'Container 3', [new Widget('5'), new Widget('6')])\n    ];\n\n    widgets: Array<Widget> = [];\n    addTo($event: any) {\n        if ($event) {\n            this.widgets.push($event.dragData);\n        }\n    }\n}\n\nclass Container {\n  constructor(public id: number, public name: string, public widgets: Array<Widget>) {}\n}\n\nclass Widget {\n  constructor(public name: string) {}\n}\n```\n\n#### 14. Simple FormArray sortable with Drag-and-Drop\nHere is an example of simple sortable of favorite drinks moving in container via drag and drop operation but using FormArray instead of Array:\n\n```js\nimport {Component} from '@angular/core';\nimport {FormArray, FormControl} from '@angular/forms';\n\n@Component({\n    selector: 'simple-formarray-sortable',\n    template: `\n<h4>Simple FormArray sortable</h4>\n<div class=\"row\">\n    <div class=\"col-sm-3\">\n        <div class=\"panel panel-success\">\n            <div class=\"panel-heading\">\n                Favorite drinks\n            </div>\n            <div class=\"panel-body\">\n                <ul class=\"list-group\" dnd-sortable-container [sortableData]=\"listOne\">\n                    <li *ngFor=\"let item of listOne.controls; let i = index\" class=\"list-group-item\" dnd-sortable [sortableIndex]=\"i\"><input type=\"text\" [formControl]=\"item\"></li>\n                </ul>\n            </div>\n        </div>\n    </div>\n    <div class=\"col-sm-6\">\n        <div class=\"panel panel-default\">\n            <div class=\"panel-body\">\n                My prefences:<br/>\n                <span *ngFor=\"let item of listOne.controls; let i = index\">{{i + 1}}) {{item.value}}<br/></span>\n            </div>\n        </div>\n    </div>\n</div>`\n})\nexport class SimpleFormArraySortableComponent {\n    listOne: FormArray = new FormArray([\n      new FormControl('Coffee'),\n      new FormControl('Orange Juice'),\n      new FormControl('Red Wine'),\n      new FormControl('Unhealty drink!'),\n      new FormControl('Water')\n    ]);\n}\n```\n\n## How to pass multiple data in dragData while dragging ?\n\n1) As an array:\n\n``` html\n[dragData]=\"[aComponent,'component-in-bar']\"\n```\n\n``` javascript\nloadComponent($event){\n    console.log($event.dragData[0]); // aComponent\n    console.log($event.dragData[1]); // 'component-in-bar' OR 'component-in-designer'\n}\n```\n\n2) As an object:\n\n``` html\n[dragData]=\"{component: aComponent, location: 'component-in-bar'}\"\n```\n\n``` javascript\nloadComponent($event){\n    console.log($event.dragData.component); // aComponent\n    console.log($event.dragData.location); // 'component-in-bar' OR 'component-in-designer'\n}\n```\n\n# Retreiving files in a drop zone\n\nSince it is possible to drag and drop one or more files to a drop zone, you need to handle the incoming files.\n\n```js\nimport {Component} from '@angular/core';\nimport {Http, Headers} from '@angular/http';\nimport {DND_PROVIDERS, DND_DIRECTIVES} from 'ng2-dnd/ng2-dnd';\nimport {bootstrap} from '@angular/platform-browser-dynamic';\n\nbootstrap(AppComponent, [\n    DND_PROVIDERS // It is required to have 1 unique instance of your service\n]);\n\n@Component({\n    selector: 'app',\n    directives: [DND_DIRECTIVES],\n    template: `\n<h4>Simple Drag-and-Drop</h4>\n<div class=\"row\">\n\n    <div class=\"col-sm-3\">\n        <div dnd-droppable class=\"panel panel-info\"\n            (onDropSuccess)=\"transferDataSuccess($event)\">>\n            <div class=\"panel-heading\">Place to drop</div>\n            <div class=\"panel-body\">\n            </div>\n        </div>\n    </div>\n</div>\n`\n})\nexport class AppComponent {\n\n  constructor(private _http: Http) { }\n\n   /**\n   * The $event is a structure:\n   * {\n   *   dragData: any,\n   *   mouseEvent: MouseEvent\n   * }\n   */\n  transferDataSuccess($event) {\n    // let attachmentUploadUrl = 'assets/data/offerspec/offerspec.json';\n    // loading the FileList from the dataTransfer\n    let dataTransfer: DataTransfer = $event.mouseEvent.dataTransfer;\n    if (dataTransfer && dataTransfer.files) {\n\n      // needed to support posting binaries and usual form values\n      let headers = new Headers();\n      headers.append('Content-Type', 'multipart/form-data');\n\n      let files: FileList = dataTransfer.files;\n\n      // uploading the files one by one asynchrounusly\n      for (let i = 0; i < files.length; i++) {\n        let file: File = files[i];\n\n        // just for debugging\n        console.log('Name: ' + file.name + '\\n Type: ' + file.type + '\\n Size: ' + file.size + '\\n Date: ' + file.lastModifiedDate);\n\n        // collecting the data to post\n        var data = new FormData();\n        data.append('file', file);\n        data.append('fileName', file.name);\n        data.append('fileSize', file.size);\n        data.append('fileType', file.type);\n        data.append('fileLastMod', file.lastModifiedDate);\n\n        // posting the data\n        this._http\n          .post(attachmentUploadUrl, data, {\n            headers: headers\n          })\n          .toPromise()\n          .catch(reason => {\n            console.log(JSON.stringify(reason));\n          });\n      }\n    }\n  }\n}\n\n# Credits\n- [Francesco Cina](https://github.com/ufoscout)\n- [Valerii Kuznetsov](https://github.com/solival)\n- [Shane Oborn](https://github.com/obosha)\n- [Juergen Gutsch](https://github.com/JuergenGutsch)\n- [Damjan Cilenšek](https://github.com/loudandwicked)\n\n# License\n [MIT](/LICENSE)\n","readmeFilename":"README.md"}