{"_id":"@edcarroll/ng2-dnd","_rev":"2-ac169e01599f1964b3da6ca7820e78cf","name":"@edcarroll/ng2-dnd","description":"Angular 2 Drag-and-Drop without dependencies","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@edcarroll/ng2-dnd","description":"Angular 2 Drag-and-Drop without dependencies","version":"1.0.0","scripts":{"test":"karma start","test-watch":"tsc --noUnusedParameters --noUnusedLocals && karma start --no-single-run --auto-watch","commit":"npm run prepublish && npm test && git-cz","prepublish":"ngc --noUnusedParameters --noUnusedLocals && npm run build","build":"webpack","semantic-release":"semantic-release pre && npm publish && semantic-release post"},"repository":{"type":"git","url":"git+https://github.com/akserg/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/akserg/ng2-dnd/issues"},"main":"bundles/index.umd.js","module":"index.js","typings":"index.d.ts","homepage":"https://github.com/akserg/ng2-dnd#readme","peerDependencies":{"@angular/core":"^2.4.4 || >=4.0.0"},"devDependencies":{"@angular/common":"^2.4.4 || >=4.0.0","@angular/compiler":"^2.4.4 || >=4.0.0","@angular/compiler-cli":"^2.4.4 || >=4.0.0","@angular/core":"^2.4.4 || >=4.0.0","@angular/forms":"^2.4.4 || >=4.0.0","@angular/platform-browser":"^2.4.4 || >=4.0.0","@angular/platform-browser-dynamic":"^2.4.4 || >=4.0.0","@types/hammerjs":"^2.0.34","@types/jasmine":"^2.5.51","@types/node":"^7.0.29","awesome-typescript-loader":"^3.1.3","codelyzer":"^3.0.1","commitizen":"^2.9.6","core-js":"^2.4.1","cz-conventional-changelog":"^2.0.0","istanbul-instrumenter-loader":"^2.0.0","jasmine-core":"^2.6.2","karma":"^1.7.0","karma-chrome-launcher":"^2.1.1","karma-coverage":"^1.1.1","karma-firefox-launcher":"^1.0.1","karma-jasmine":"^1.1.0","karma-mocha-reporter":"^2.2.3","karma-remap-coverage":"~0.1.4","karma-sourcemap-loader":"^0.3.7","karma-webpack":"^2.0.3","loader-utils":"^1.1.0","reflect-metadata":"^0.1.10","rxjs":"^5.4.0","semantic-release":"^6.3.6","source-map-loader":"^0.2.1","ts-helpers":"1.1.2","tslint":"^5.4.3","tslint-loader":"^3.5.3","typescript":"^2.3.4","webpack":"^2.6.1","zone.js":"^0.8.12"},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"gitHead":"f6e3865c948e39ac249527b28f0c3aec778fc5f7","_id":"@edcarroll/ng2-dnd@1.0.0","_npmVersion":"5.0.4","_nodeVersion":"8.1.3","_npmUser":{"name":"edcarroll","email":"ed@edcarroll.co.uk"},"dist":{"integrity":"sha512-s9UqYqgxf9jB5nelAvMK1WpakUmcwGCrCAWyjphxILQd849aib4E9sFTBT3LfpkYOI1sjOUgkoy2IjWJz/PZyw==","shasum":"11cd4068753231685e05fd917b310ca0555fb7fe","tarball":"https://registry.npmjs.org/@edcarroll/ng2-dnd/-/ng2-dnd-1.0.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDpEdgVeQNHhdjelTza5CmU5cHxqXv8+fKcXEVWOykPbAIgFu2XRcyAUr2cuIvKKWdWo1Ak38oF2C075PUpbhMAJQE="}]},"maintainers":[{"name":"edcarroll","email":"ed@edcarroll.co.uk"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/ng2-dnd-1.0.0.tgz_1500680309719_0.7192524105776101"}},"1.0.1":{"name":"@edcarroll/ng2-dnd","description":"Angular 2 Drag-and-Drop without dependencies","version":"1.0.1","scripts":{"test":"karma start","test-watch":"tsc --noUnusedParameters --noUnusedLocals && karma start --no-single-run --auto-watch","commit":"npm run prepublish && npm test && git-cz","prepublish":"ngc --noUnusedParameters --noUnusedLocals && npm run build","build":"webpack","semantic-release":"semantic-release pre && npm publish && semantic-release post"},"repository":{"type":"git","url":"git+https://github.com/akserg/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/akserg/ng2-dnd/issues"},"main":"bundles/index.umd.js","module":"index.js","typings":"index.d.ts","homepage":"https://github.com/akserg/ng2-dnd#readme","peerDependencies":{"@angular/core":"^2.4.4 || >=4.0.0"},"devDependencies":{"@angular/common":"^2.4.4 || >=4.0.0","@angular/compiler":"^2.4.4 || >=4.0.0","@angular/compiler-cli":"^2.4.4 || >=4.0.0","@angular/core":"^2.4.4 || >=4.0.0","@angular/forms":"^2.4.4 || >=4.0.0","@angular/platform-browser":"^2.4.4 || >=4.0.0","@angular/platform-browser-dynamic":"^2.4.4 || >=4.0.0","@types/hammerjs":"^2.0.34","@types/jasmine":"^2.5.51","@types/node":"^7.0.29","awesome-typescript-loader":"^3.1.3","codelyzer":"^3.0.1","commitizen":"^2.9.6","core-js":"^2.4.1","cz-conventional-changelog":"^2.0.0","istanbul-instrumenter-loader":"^2.0.0","jasmine-core":"^2.6.2","karma":"^1.7.0","karma-chrome-launcher":"^2.1.1","karma-coverage":"^1.1.1","karma-firefox-launcher":"^1.0.1","karma-jasmine":"^1.1.0","karma-mocha-reporter":"^2.2.3","karma-remap-coverage":"~0.1.4","karma-sourcemap-loader":"^0.3.7","karma-webpack":"^2.0.3","loader-utils":"^1.1.0","reflect-metadata":"^0.1.10","rxjs":"^5.4.0","semantic-release":"^6.3.6","source-map-loader":"^0.2.1","ts-helpers":"1.1.2","tslint":"^5.4.3","tslint-loader":"^3.5.3","typescript":"^2.3.4","webpack":"^2.6.1","zone.js":"^0.8.12"},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"gitHead":"461369022976005f42b7c3aaec7cdacd62c2e9e8","_id":"@edcarroll/ng2-dnd@1.0.1","_npmVersion":"5.0.4","_nodeVersion":"8.1.3","_npmUser":{"name":"edcarroll","email":"ed@edcarroll.co.uk"},"dist":{"integrity":"sha512-T9RaXDYdkCgLxnkhUVf8r5TOJCCzsyEwpIhS1huicWpbF651VWqNXS9vU7D8fFRSCbaDK3jcKVAkdtEG4SC7XQ==","shasum":"606520d85327c0778511aedd3486ffd49bb46805","tarball":"https://registry.npmjs.org/@edcarroll/ng2-dnd/-/ng2-dnd-1.0.1.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCd69CbgIRp6qj8lFPP5Q41ZM3FgLBN6hAiR5tQ5UexmgIhAK9NSJR/EBKmptAKhDW4UAZJqJJ+lB9f62Ux0o5+CnOW"}]},"maintainers":[{"name":"edcarroll","email":"ed@edcarroll.co.uk"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/ng2-dnd-1.0.1.tgz_1500681378544_0.5408268228638917"}}},"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)\r\nAngular 2 Drag-and-Drop without dependencies.\r\n\r\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.\r\n\r\n[![Build Status](https://travis-ci.org/akserg/ng2-dnd.svg?branch=master)](https://travis-ci.org/akserg/ng2-dnd)\r\n[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\r\n[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) \r\n[![Dependency Status](https://david-dm.org/akserg/ng2-dnd.svg)](https://david-dm.org/akserg/ng2-dnd)\r\n[![devDependency Status](https://david-dm.org/akserg/ng2-dnd/dev-status.svg)](https://david-dm.org/akserg/ng2-dnd#info=devDependencies)\r\n[![Known Vulnerabilities](https://snyk.io/test/github/akserg/ng2-dnd/badge.svg)](https://snyk.io/test/github/akserg/ng2-dnd)\r\n\r\n_Some of these APIs and Components are not final and are subject to change!_\r\n\r\n## Installation\r\n```bash\r\nnpm install ng2-dnd --save\r\n```\r\n\r\n## Demo\r\nSimple examples using ng2-dnd:\r\n- with SystemJS in [ng2-systemjs-demo](https://github.com/akserg/ng2-systemjs-demo)\r\n- with Webpack in [ng2-webpack-demo](https://github.com/akserg/ng2-webpack-demo)\r\n\r\nOnline demo available [here](http://akserg.github.io/ng2-webpack-demo)\r\n\r\nPlunker demo available [here](http://embed.plnkr.co/JbG8Si)\r\n\r\n## Usage\r\nIf you use SystemJS to load your files, you might have to update your config:\r\n\r\n```js\r\nSystem.config({\r\n    map: {\r\n        'ng2-dnd': 'node_modules/ng2-dnd/bundles/index.umd.js'\r\n    }\r\n});\r\n```\r\n\r\n#### 1. Add the default styles\r\n- Import the `style.css` into your web page\r\n\r\n#### 2. Import the `DndModule`\r\nImport `DndModule.forRoot()` in the NgModule of your application. \r\nThe `forRoot` method is a convention for modules that provide a singleton service.\r\n\r\n```ts\r\nimport {BrowserModule} from \"@angular/platform-browser\";\r\nimport {NgModule} from '@angular/core';\r\nimport {DndModule} from 'ng2-dnd';\r\n\r\n@NgModule({\r\n    imports: [\r\n        BrowserModule,\r\n        DndModule.forRoot()\r\n    ],\r\n    bootstrap: [AppComponent]\r\n})\r\nexport class AppModule {\r\n}\r\n```\r\n\r\nIf you have multiple NgModules and you use one as a shared NgModule (that you import in all of your other NgModules), \r\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.\r\n\r\n```ts\r\n@NgModule({\r\n    imports: [\r\n        BrowserModule,\r\n        DndModule\r\n    ],\r\n    exports: [BrowserModule, DndModule],\r\n})\r\nexport class SharedModule {\r\n}\r\n```\r\n\r\n#### 3. Use Drag-and-Drop operations with no code\r\n\r\n```js\r\nimport {Component} from '@angular/core';\r\n\r\n@Component({\r\n    selector: 'simple-dnd',\r\n    template: `\r\n<h4>Simple Drag-and-Drop</h4>\r\n<div class=\"row\">\r\n    <div class=\"col-sm-3\">\r\n        <div class=\"panel panel-success\">\r\n            <div class=\"panel-heading\">Available to drag</div>\r\n            <div class=\"panel-body\">\r\n                <div class=\"panel panel-default\" dnd-draggable [dragEnabled]=\"true\">\r\n                    <div class=\"panel-body\">\r\n                        <div>Drag Me</div>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n    </div>\r\n    <div class=\"col-sm-3\">\r\n        <div dnd-droppable class=\"panel panel-info\" (onDropSuccess)=\"simpleDrop=$event\">\r\n            <div class=\"panel-heading\">Place to drop</div>\r\n            <div class=\"panel-body\">\r\n                <div *ngIf=\"simpleDrop\">Item was dropped here</div>\r\n            </div>\r\n        </div>\r\n    </div>\r\n</div>`\r\n})\r\nexport class SimpleDndComponent {\r\n    simpleDrop: any = null;\r\n}\r\n```\r\n\r\n#### 4. Add handle to restrict draggable zone of component\r\n\r\n```js\r\nimport {Component} from '@angular/core';\r\n\r\n@Component({\r\n    selector: 'simple-dnd-handle',\r\n    template: `\r\n<h4>Simple Drag-and-Drop with handle</h4>\r\n<div class=\"row\">\r\n    <div class=\"col-sm-3\">\r\n        <div class=\"panel panel-success\">\r\n            <div class=\"panel-heading\">Available to drag</div>\r\n            <div class=\"panel-body\">\r\n                <div class=\"panel panel-default\" dnd-draggable [dragEnabled]=\"true\">\r\n                    <div class=\"panel-body\">\r\n                        <div>\r\n                            <span dnd-draggable-handle>=</span>&nbsp;\r\n                            Drag Handle\r\n                        </div>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n    </div>\r\n    <div class=\"col-sm-3\">\r\n        <div dnd-droppable class=\"panel panel-info\" (onDropSuccess)=\"simpleDrop=$event\">\r\n            <div class=\"panel-heading\">Place to drop</div>\r\n            <div class=\"panel-body\">\r\n                <div *ngIf=\"simpleDrop\">Item was dropped here</div>\r\n            </div>\r\n        </div>\r\n    </div>\r\n</div>`\r\n})\r\nexport class SimpleDndHandleComponent {\r\n    simpleDrop: any = null;\r\n}\r\n```\r\n\r\n#### 5. Restriction Drag-and-Drop operations with drop zones\r\nYou can use property *dropZones* (actually an array) to specify in which place you would like to drop the draggable element:\r\n\r\n```js\r\nimport {Component} from '@angular/core';\r\n\r\n@Component({\r\n    selector: 'zone-dnd',\r\n    template: `\r\n<h4>Restricted Drag-and-Drop with zones</h4>\r\n<div class=\"row\">\r\n    <div class=\"col-sm-3\">\r\n        <div class=\"panel panel-primary\">\r\n            <div class=\"panel-heading\">Available to drag</div>\r\n            <div class=\"panel-body\">\r\n                <div class=\"panel panel-default\" dnd-draggable [dragEnabled]=\"true\" [dropZones]=\"['zone1']\">\r\n                    <div class=\"panel-body\">\r\n                        <div>Drag Me</div>\r\n                        <div>Zone 1 only</div>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n\r\n        <div class=\"panel panel-success\">\r\n            <div class=\"panel-heading\">Available to drag</div>\r\n            <div class=\"panel-body\">\r\n                <div class=\"panel panel-default\" dnd-draggable [dragEnabled]=\"true\" [dropZones]=\"['zone1', 'zone2']\">\r\n                    <div class=\"panel-body\">\r\n                        <div>Drag Me</div>\r\n                        <div>Zone 1 & 2</div>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n    </div>\r\n    <div class=\"col-sm-3\">\r\n        <div dnd-droppable class=\"panel panel-info\" [dropZones]=\"['zone1']\" (onDropSuccess)=\"restrictedDrop1=$event\">\r\n            <div class=\"panel-heading\">Zone 1</div>\r\n            <div class=\"panel-body\">\r\n                <div *ngIf=\"restrictedDrop1\">Item was dropped here</div>\r\n            </div>\r\n        </div>\r\n    </div>\r\n    <div class=\"col-sm-3\">\r\n        <div dnd-droppable class=\"panel panel-warning\" [dropZones]=\"['zone2']\" (onDropSuccess)=\"restrictedDrop2=$event\">\r\n            <div class=\"panel-heading\">Zone 2</div>\r\n            <div class=\"panel-body\">\r\n                <div *ngIf=\"restrictedDrop2\">Item was dropped here</div>\r\n            </div>\r\n        </div>\r\n    </div>\r\n</div>`\r\n})\r\nexport class ZoneDndComponent {\r\n    restrictedDrop1: any = null;\r\n    restrictedDrop2: any = null;\r\n}\r\n```\r\n\r\n#### 6. Transfer custom data via Drag-and-Drop\r\nYou can transfer data from draggable to droppable component via *dragData* property of Draggable component:\r\n\r\n```js\r\nimport {Component} from '@angular/core';\r\n\r\n@Component({\r\n    selector: 'custom-data-dnd',\r\n    template: `\r\n<h4>Transfer custom data in Drag-and-Drop</h4>\r\n<div class=\"row\">\r\n    <div class=\"col-sm-3\">\r\n        <div class=\"panel panel-success\">\r\n            <div class=\"panel-heading\">Available to drag</div>\r\n            <div class=\"panel-body\">\r\n                <div class=\"panel panel-default\" dnd-draggable [dragEnabled]=\"true\" [dragData]=\"transferData\">\r\n                    <div class=\"panel-body\">\r\n                        <div>Drag Me</div>\r\n                        <div>{{transferData | json}}</div>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n    </div>\r\n    <div class=\"col-sm-3\">\r\n        <div dnd-droppable class=\"panel panel-info\" (onDropSuccess)=\"transferDataSuccess($event)\">\r\n            <div class=\"panel-heading\">Place to drop (Items:{{receivedData.length}})</div>\r\n            <div class=\"panel-body\">\r\n                <div [hidden]=\"!receivedData.length > 0\" *ngFor=\"let data of receivedData\">{{data | json}}</div>\r\n            </div>\r\n        </div>\r\n    </div>\r\n</div>`\r\n})\r\nexport class CustomDataDndComponent {\r\n    transferData: Object = {id: 1, msg: 'Hello'};\r\n    receivedData: Array<any> = [];\r\n\r\n    transferDataSuccess($event: any) {\r\n        this.receivedData.push($event);\r\n    }\r\n}\r\n```\r\n\r\n#### 7. Use a custom function to determine where dropping is allowed\r\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.\r\n\r\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.\r\n\r\n```js\r\nimport { Component } from '@angular/core';\r\n\r\n@Component({\r\n    selector: 'custom-function-dnd',\r\n    template: `\r\n<h4>Use a custom function to determine where dropping is allowed</h4>\r\n<div class=\"row\">\r\n    <div class=\"col-sm-3\">\r\n        <div class=\"panel panel-success\">\r\n            <div class=\"panel-heading\">Available to drag</div>\r\n            <div class=\"panel-body\">\r\n                <div class=\"panel panel-default\" dnd-draggable [dragData]=\"6\">\r\n                    <div class=\"panel-body\">dragData = 6</div>\r\n                </div>\r\n                <div class=\"panel panel-default\" dnd-draggable [dragData]=\"10\">\r\n                    <div class=\"panel-body\">dragData = 10</div>\r\n                </div>\r\n                <div class=\"panel panel-default\" dnd-draggable [dragData]=\"30\">\r\n                    <div class=\"panel-body\">dragData = 30</div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n    </div>\r\n    <div class=\"col-sm-6\">\r\n        <pre>allowDropFunction(baseInteger: any): any {{ '{' }}\r\n  return (dragData: any) => dragData % baseInteger === 0;\r\n{{ '}' }}</pre>\r\n        <div class=\"row\">\r\n            <div class=\"col-sm-6\">\r\n                <div dnd-droppable class=\"panel panel-info\" [allowDrop]=\"allowDropFunction(box1Integer)\" (onDropSuccess)=\"addTobox1Items($event)\">\r\n                    <div class=\"panel-heading\">\r\n                        Multiples of\r\n                        <input type=\"number\" [(ngModel)]=\"box1Integer\" style=\"width: 4em\">\r\n                        only\r\n                    </div>\r\n                    <div class=\"panel-body\">\r\n                        <div *ngFor=\"let item of box1Items\">dragData = {{item}}</div>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n            <div class=\"col-sm-6\">\r\n                <div dnd-droppable class=\"panel panel-warning\" [allowDrop]=\"allowDropFunction(box2Integer)\" (onDropSuccess)=\"addTobox2Items($event)\">\r\n                    <div class=\"panel-heading\">\r\n                        Multiples of\r\n                        <input type=\"number\" [(ngModel)]=\"box2Integer\" style=\"width: 4em\">\r\n                        only\r\n                    </div>\r\n                    <div class=\"panel-body\">\r\n                        <div *ngFor=\"let item of box2Items\">dragData = {{item}}</div>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n    </div>\r\n</div>\r\n`\r\n})\r\nexport class CustomFunctionDndComponent {\r\n    box1Integer: number = 3;\r\n    box2Integer: number = 10;\r\n\r\n    box1Items: string[] = [];\r\n    box2Items: string[] = [];\r\n\r\n    allowDropFunction(baseInteger: number): any {\r\n        return (dragData: any) => dragData % baseInteger === 0;\r\n    }\r\n\r\n    addTobox1Items($event: any) {\r\n        this.box1Items.push($event.dragData);\r\n    }\r\n\r\n    addTobox2Items($event: any) {\r\n        this.box2Items.push($event.dragData);\r\n    }\r\n}\r\n```\r\n\r\n#### 8. Shopping basket with Drag-and-Drop\r\nHere is an example of shopping backet with products adding via drag and drop operation:\r\n\r\n```js\r\nimport { Component } from '@angular/core';\r\n\r\n@Component({\r\n    selector: 'shoping-basket-dnd',\r\n    template: `\r\n<h4>Drag-and-Drop - Shopping basket</h4>\r\n<div class=\"row\">\r\n\r\n    <div class=\"col-sm-3\">\r\n        <div class=\"panel panel-success\">\r\n            <div class=\"panel-heading\">Available products</div>\r\n            <div class=\"panel-body\">\r\n                <div *ngFor=\"let product of availableProducts\" class=\"panel panel-default\"\r\n                    dnd-draggable [dragEnabled]=\"product.quantity>0\" [dragData]=\"product\" (onDragSuccess)=\"orderedProduct($event)\" [dropZones]=\"['demo1']\">\r\n                    <div class=\"panel-body\">\r\n                        <div [hidden]=\"product.quantity===0\">{{product.name}} - \\${{product.cost}}<br>(available: {{product.quantity}})</div>\r\n                        <div [hidden]=\"product.quantity>0\"><del>{{product.name}}</del><br>(NOT available)</div>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n    </div>\r\n    <div class=\"col-sm-3\">\r\n        <div dnd-droppable (onDropSuccess)=\"addToBasket($event)\" [dropZones]=\"['demo1']\" class=\"panel panel-info\">\r\n            <div class=\"panel-heading\">Shopping Basket<br>(to pay: \\${{totalCost()}})</div>\r\n            <div class=\"panel-body\">\r\n                <div *ngFor=\"let product of shoppingBasket\" class=\"panel panel-default\">\r\n                    <div class=\"panel-body\">\r\n                    {{product.name}}<br>(ordered: {{product.quantity}}<br>cost: \\${{product.cost * product.quantity}})\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n    </div>\r\n</div>`\r\n})\r\nexport class ShoppingBasketDndComponent {\r\n    availableProducts: Array<Product> = [];\r\n    shoppingBasket: Array<Product> = [];\r\n\r\n    constructor() {\r\n        this.availableProducts.push(new Product('Blue Shoes', 3, 35));\r\n        this.availableProducts.push(new Product('Good Jacket', 1, 90));\r\n        this.availableProducts.push(new Product('Red Shirt', 5, 12));\r\n        this.availableProducts.push(new Product('Blue Jeans', 4, 60));\r\n    }\r\n\r\n    orderedProduct($event: any) {\r\n        let orderedProduct: Product = $event.dragData;\r\n        orderedProduct.quantity--;\r\n    }\r\n\r\n    addToBasket($event: any) {\r\n        let newProduct: Product = $event.dragData;\r\n        for (let indx in this.shoppingBasket) {\r\n            let product: Product = this.shoppingBasket[indx];\r\n            if (product.name === newProduct.name) {\r\n                product.quantity++;\r\n                return;\r\n            }\r\n        }\r\n        this.shoppingBasket.push(new Product(newProduct.name, 1, newProduct.cost));\r\n        this.shoppingBasket.sort((a: Product, b: Product) => {\r\n            return a.name.localeCompare(b.name);\r\n        });\r\n    }\r\n\r\n    totalCost(): number {\r\n        let cost: number = 0;\r\n        for (let indx in this.shoppingBasket) {\r\n            let product: Product = this.shoppingBasket[indx];\r\n            cost += (product.cost * product.quantity);\r\n        }\r\n        return cost;\r\n    }\r\n}\r\n\r\nclass Product {\r\n  constructor(public name: string, public quantity: number, public cost: number) {}\r\n}\r\n```\r\n\r\n#### 9. Simple sortable with Drag-and-Drop\r\nHere is an example of simple sortable of favorite drinks moving in container via drag and drop operation:\r\n\r\n```js\r\nimport {Component} from '@angular/core';\r\n\r\n@Component({\r\n    selector: 'simple-sortable',\r\n    template: `\r\n<h4>Simple sortable</h4>\r\n<div class=\"row\">\r\n    <div class=\"col-sm-3\">\r\n        <div class=\"panel panel-success\">\r\n            <div class=\"panel-heading\">\r\n                Favorite drinks\r\n            </div>\r\n            <div class=\"panel-body\">\r\n                <ul class=\"list-group\" dnd-sortable-container [sortableData]=\"listOne\">\r\n                    <li *ngFor=\"let item of listOne; let i = index\" class=\"list-group-item\" dnd-sortable [sortableIndex]=\"i\">{{item}}</li>\r\n                </ul>\r\n            </div>\r\n        </div>\r\n    </div>\r\n    <div class=\"col-sm-6\">\r\n        <div class=\"panel panel-default\">\r\n            <div class=\"panel-body\">\r\n                My prefences:<br/>\r\n                <span *ngFor=\"let item of listOne; let i = index\">{{i + 1}}) {{item}}<br/></span>\r\n            </div>\r\n        </div>\r\n    </div>\r\n</div>`\r\n})\r\nexport class SimpleSortableComponent {\r\n    listOne: Array<string> = ['Coffee', 'Orange Juice', 'Red Wine', 'Unhealty drink!', 'Water'];\r\n}\r\n```\r\n\r\n\r\n#### 10. Simple sortable with Drag-and-Drop handle\r\nAdd handle to restict grip zone of sortable component.\r\n\r\n```js\r\nimport {Component} from '@angular/core';\r\n\r\n@Component({\r\n    selector: 'simple-sortable-handle',\r\n    template: `\r\n<h4>Simple sortable handle</h4>\r\n<div class=\"row\">\r\n    <div class=\"col-sm-3\">\r\n        <div class=\"panel panel-success\">\r\n            <div class=\"panel-heading\">\r\n                Favorite drinks\r\n            </div>\r\n            <div class=\"panel-body\">\r\n                <ul class=\"list-group\" dnd-sortable-container [sortableData]=\"listOne\">\r\n                    <li *ngFor=\"let item of listOne; let i = index\" class=\"list-group-item\" dnd-sortable [sortableIndex]=\"i\">\r\n                      <span dnd-sortable-handle>=</span>&nbsp;\r\n                      {{item}}\r\n                    </li>\r\n                </ul>\r\n            </div>\r\n        </div>\r\n    </div>\r\n    <div class=\"col-sm-6\">\r\n        <div class=\"panel panel-default\">\r\n            <div class=\"panel-body\">\r\n                My prefences:<br/>\r\n                <span *ngFor=\"let item of listOne; let i = index\">{{i + 1}}) {{item}}<br/></span>\r\n            </div>\r\n        </div>\r\n    </div>\r\n</div>`\r\n})\r\nexport class SimpleSortableHandleComponent {\r\n    listOne: Array<string> = ['Coffee', 'Orange Juice', 'Red Wine', 'Unhealty drink!', 'Water'];\r\n}\r\n```\r\n\r\n#### 11. Simple sortable With Drop into recycle bin\r\nHere is an example of multi list sortable of boxers moving in container and between containers via drag and drop operation:\r\n\r\n```js\r\nimport {Component} from '@angular/core';\r\n\r\n@Component({\r\n    selector: 'recycle-multi-sortable',\r\n    template: `\r\n<h4>Simple sortable With Drop into recycle bin</h4>\r\n<div class=\"row\">\r\n    <div class=\"col-sm-3\">\r\n        <div class=\"panel panel-success\">\r\n            <div class=\"panel-heading\">\r\n                Favorite drinks\r\n            </div>\r\n            <div class=\"panel-body\" dnd-sortable-container [sortableData]=\"listOne\" [dropZones]=\"['delete-dropZone']\">\r\n                <ul class=\"list-group\">\r\n                    <li *ngFor=\"let item of listOne; let i = index\" class=\"list-group-item\"\r\n                    dnd-sortable [sortableIndex]=\"i\">{{item}}</li>\r\n                </ul>\r\n            </div>\r\n        </div>\r\n    </div>\r\n    <div class=\"col-sm-6\">\r\n        <div class=\"panel panel-default\">\r\n            <div class=\"panel-body\" dnd-sortable-container [dropZones]=\"['delete-dropZone']\" [sortableData]=\"listRecycled\">\r\n                Recycle bin: Drag into me to delete it<br/>\r\n            </div>\r\n        </div>\r\n        <div *ngIf=\"listRecycled.length\">\r\n        <b>Recycled:</b> <span>{{listRecycled.toString()}} </span>\r\n        </div>\r\n    </div>\r\n</div>`\r\n})\r\nexport class RecycleMultiSortableComponent {\r\n    listOne: Array<string> = ['Coffee', 'Orange Juice', 'Red Wine', 'Unhealty drink!', 'Water'];\r\n    listRecycled: Array<string> = [];\r\n}\r\n```\r\n\r\n#### 12. Simple sortable With Drop into something, without delete it\r\nHere is an example of simple sortable list of items copying in target container:\r\n\r\n```js\r\nimport {Component} from '@angular/core';\r\n\r\n@Component({\r\n    selector: 'simple-sortable-copy',\r\n    template: `\r\n<h4>Simple sortable With Drop into something, without delete it</h4>\r\n<div class=\"row\">\r\n    <div class=\"col-sm-3\">\r\n        <div class=\"panel panel-warning\"\r\n            dnd-sortable-container [sortableData]=\"sourceList\" [dropZones]=\"['source-dropZone']\">\r\n            <div class=\"panel-heading\">Source List</div>\r\n            <div class=\"panel-body\">\r\n                <ul class=\"list-group\">\r\n                    <li *ngFor=\"let source of sourceList; let x = index\" class=\"list-group-item\"\r\n                        dnd-sortable [sortableIndex]=\"x\" [dragEnabled]=\"true\"\r\n                        [dragData]=\"source\">{{source.name}}</li>\r\n                </ul>\r\n            </div>\r\n        </div>\r\n    </div>\r\n    <div class=\"col-sm-6\">\r\n        <div class=\"panel panel-info\">\r\n            <div class=\"panel-heading\">Target List</div>\r\n            <div class=\"panel-body\" dnd-droppable (onDropSuccess)=\"addTo($event)\" [dropZones]=\"['source-dropZone']\">\r\n                <ul class=\"list-group\">\r\n                    <li *ngFor=\"let target of targetList\" class=\"list-group-item\">\r\n                        {{target.name}}\r\n                    </li>\r\n                </ul>\r\n            </div>\r\n        </div>\r\n    </div>\r\n</div>`\r\n})\r\nexport class SimpleSortableCopyComponent {\r\n\r\n    sourceList: Widget[] = [\r\n        new Widget('1'), new Widget('2'),\r\n        new Widget('3'), new Widget('4'),\r\n        new Widget('5'), new Widget('6')\r\n    ];\r\n\r\n    targetList: Widget[] = [];\r\n    addTo($event: any) {\r\n        this.targetList.push($event.dragData);\r\n    }\r\n}\r\n\r\nclass Widget {\r\n  constructor(public name: string) {}\r\n}\r\n```\r\n\r\n#### 13. Multi list sortable between containers\r\nHere is an example of multi list sortable of boxers moving in container and between containers via drag and drop operation:\r\n\r\n```js\r\nimport {Component} from '@angular/core';\r\n\r\n@Component({\r\n    selector: 'embedded-sortable',\r\n    template: `\r\n<h4>Move items between multi list sortable containers</h4>\r\n<div class=\"row\">\r\n    <div class=\"col-sm-3\">\r\n        Drag Containers <input type=\"checkbox\" [(ngModel)]=\"dragOperation\"/>\r\n        <div dnd-sortable-container [sortableData]=\"containers\" [dropZones]=\"['container-dropZone']\">\r\n            <div class=\"col-sm3\"\r\n                    *ngFor=\"let container of containers; let i = index\"\r\n                    dnd-sortable [sortableIndex]=\"i\" [dragEnabled]=\"dragOperation\">\r\n                <div class=\"panel panel-warning\"\r\n                    dnd-sortable-container [sortableData]=\"container.widgets\" [dropZones]=\"['widget-dropZone']\">\r\n                    <div class=\"panel-heading\">\r\n                        {{container.id}} - {{container.name}}\r\n                    </div>\r\n                    <div class=\"panel-body\">\r\n                        <ul class=\"list-group\">\r\n                            <li *ngFor=\"let widget of container.widgets; let x = index\" class=\"list-group-item\"\r\n                                dnd-sortable [sortableIndex]=\"x\" [dragEnabled]=\"!dragOperation\"\r\n                                [dragData]=\"widget\">{{widget.name}}</li>\r\n                        </ul>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n    </div>\r\n    <div class=\"col-sm-6\">\r\n        <div class=\"panel panel-info\">\r\n            <div class=\"panel-heading\">Widgets</div>\r\n            <div class=\"panel-body\" dnd-droppable (onDropSuccess)=\"addTo($event)\" [dropZones]=\"['widget-dropZone']\">\r\n                <div *ngFor=\"let widget of widgets\" class=\"panel panel-default\">\r\n                    <div class=\"panel-body\">\r\n                        {{widget.name}}\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n    </div>\r\n</div>`\r\n})\r\nexport class EmbeddedSortableComponent {\r\n    dragOperation: boolean = false;\r\n\r\n    containers: Array<Container> = [\r\n        new Container(1, 'Container 1', [new Widget('1'), new Widget('2')]),\r\n        new Container(2, 'Container 2', [new Widget('3'), new Widget('4')]),\r\n        new Container(3, 'Container 3', [new Widget('5'), new Widget('6')])\r\n    ];\r\n\r\n    widgets: Array<Widget> = [];\r\n    addTo($event: any) {\r\n        if ($event) {\r\n            this.widgets.push($event.dragData);\r\n        }\r\n    }\r\n}\r\n\r\nclass Container {\r\n  constructor(public id: number, public name: string, public widgets: Array<Widget>) {}\r\n}\r\n\r\nclass Widget {\r\n  constructor(public name: string) {}\r\n}\r\n```\r\n\r\n#### 13. Retreiving files in a drop zone\r\n\r\nSince it is possible to drag and drop one or more files to a drop zone, you need to handle the incomming files.\r\n\r\n```js\r\nimport {Component} from '@angular/core';\r\nimport {Http, Headers} from '@angular/http';\r\nimport {DND_PROVIDERS, DND_DIRECTIVES} from 'ng2-dnd/ng2-dnd';\r\nimport {bootstrap} from '@angular/platform-browser-dynamic';\r\n\r\nbootstrap(AppComponent, [\r\n    DND_PROVIDERS // It is required to have 1 unique instance of your service\r\n]);\r\n\r\n@Component({\r\n    selector: 'app',\r\n    directives: [DND_DIRECTIVES],\r\n    template: `\r\n<h4>Simple Drag-and-Drop</h4>\r\n<div class=\"row\">\r\n   \r\n    <div class=\"col-sm-3\">\r\n        <div dnd-droppable class=\"panel panel-info\"\r\n            (onDropSuccess)=\"transferDataSuccess($event)\">>\r\n            <div class=\"panel-heading\">Place to drop</div>\r\n            <div class=\"panel-body\">\r\n            </div>\r\n        </div>\r\n    </div>\r\n</div>\r\n`\r\n})\r\nexport class AppComponent {\r\n\r\n  constructor(private _http: Http) { }\r\n\r\n   /**\r\n   * The $event is a structure:\r\n   * {\r\n   *   dragData: any,\r\n   *   mouseEvent: MouseEvent\r\n   * }\r\n   */\r\n  transferDataSuccess($event) {\r\n    // let attachmentUploadUrl = 'assets/data/offerspec/offerspec.json';\r\n    // loading the FileList from the dataTransfer\r\n    let dataTransfer: DataTransfer = $event.mouseEvent.dataTransfer;\r\n    if (dataTransfer && dataTransfer.files) {\r\n      \r\n      // needed to support posting binaries and usual form values\r\n      let headers = new Headers();\r\n      headers.append('Content-Type', 'multipart/form-data');\r\n\r\n      let files: FileList = dataTransfer.files;\r\n  \r\n      // uploading the files one by one asynchrounusly\r\n      for (let i = 0; i < files.length; i++) {\r\n        let file: File = files[i];\r\n  \r\n        // just for debugging\r\n        console.log('Name: ' + file.name + '\\n Type: ' + file.type + '\\n Size: ' + file.size + '\\n Date: ' + file.lastModifiedDate);\r\n  \r\n        // collecting the data to post\r\n        var data = new FormData();\r\n        data.append('file', file);\r\n        data.append('fileName', file.name);\r\n        data.append('fileSize', file.size);\r\n        data.append('fileType', file.type);\r\n        data.append('fileLastMod', file.lastModifiedDate);\r\n  \r\n        // posting the data\r\n        this._http\r\n          .post(attachmentUploadUrl, data, {\r\n            headers: headers\r\n          })\r\n          .toPromise()\r\n          .catch(reason => {\r\n            console.log(JSON.stringify(reason));\r\n          });\r\n      }\r\n    }\r\n  }\r\n```\r\n\r\n#### 15. Simple FormArray sortable with Drag-and-Drop\r\nHere is an example of simple sortable of favorite drinks moving in container via drag and drop operation but using FormArray instead of Array:\r\n\r\n```js\r\nimport {Component} from '@angular/core';\r\nimport {FormArray, FormControl} from '@angular/forms';\r\n\r\n@Component({\r\n    selector: 'simple-formarray-sortable',\r\n    template: `\r\n<h4>Simple FormArray sortable</h4>\r\n<div class=\"row\">\r\n    <div class=\"col-sm-3\">\r\n        <div class=\"panel panel-success\">\r\n            <div class=\"panel-heading\">\r\n                Favorite drinks\r\n            </div>\r\n            <div class=\"panel-body\">\r\n                <ul class=\"list-group\" dnd-sortable-container [sortableData]=\"listOne\">\r\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>\r\n                </ul>\r\n            </div>\r\n        </div>\r\n    </div>\r\n    <div class=\"col-sm-6\">\r\n        <div class=\"panel panel-default\">\r\n            <div class=\"panel-body\">\r\n                My prefences:<br/>\r\n                <span *ngFor=\"let item of listOne.controls; let i = index\">{{i + 1}}) {{item.value}}<br/></span>\r\n            </div>\r\n        </div>\r\n    </div>\r\n</div>`\r\n})\r\nexport class SimpleFormArraySortableComponent {\r\n    listOne: FormArray = new FormArray([\r\n      new FormControl('Coffee'),\r\n      new FormControl('Orange Juice'),\r\n      new FormControl('Red Wine'),\r\n      new FormControl('Unhealty drink!'),\r\n      new FormControl('Water')\r\n    ]);\r\n}\r\n```\r\n\r\n# Credits\r\n- [Francesco Cina](https://github.com/ufoscout)\r\n- [Valerii Kuznetsov](https://github.com/solival)\r\n- [Shane Oborn](https://github.com/obosha)\r\n- [Juergen Gutsch](https://github.com/JuergenGutsch)\r\n- [Damjan Cilenšek](https://github.com/loudandwicked)\r\n\r\n# License\r\n [MIT](/LICENSE)\r\n","maintainers":[{"name":"edcarroll","email":"ed@edcarroll.co.uk"}],"time":{"modified":"2022-04-05T06:40:51.424Z","created":"2017-07-21T23:38:30.931Z","1.0.0":"2017-07-21T23:38:30.931Z","1.0.1":"2017-07-21T23:56:19.811Z"},"homepage":"https://github.com/akserg/ng2-dnd#readme","keywords":["angular","angular2","angular 2","drag","drop","drag-and-drop"],"repository":{"type":"git","url":"git+https://github.com/akserg/ng2-dnd.git"},"author":{"name":"Sergey Akopkokhyants","email":"akserg@gmail.com"},"bugs":{"url":"https://github.com/akserg/ng2-dnd/issues"},"license":"MIT","readmeFilename":"README.md"}