{"metadata":{"image":[],"title":"","description":""},"api":{"url":"","auth":"required","results":{"codes":[]},"settings":"","params":[]},"next":{"description":"","pages":[]},"title":"Drag & Drop","type":"basic","slug":"drag-drop","excerpt":"","body":"[Demo](#demo)\n[Options](#options)\n[Event](#event)\n[Override default behaviour](#override-default-behaviour)\n[Drag a node outside of the tree](#drag-a-node-outside-of-the-tree)\n[Drag an external element into the tree](#drag-an-external-element-into-the-tree)\n[Drag to an empty tree](#drag-to-an-empty-tree)\n[Mobile](#mobile)\n[Styling](#styling)\n[block:api-header]\n{\n \"title\": \"Demo\"\n}\n[/block]\n\n[block:html]\n{\n \"html\": \"<iframe src=\\\"https://angular-tree-component.azurewebsites.net/#/drag\\\" width=\\\"100%\\\" height=\\\"300px\\\"></iframe>\\n\"\n}\n[/block]\n\n[block:html]\n{\n \"html\": \"<a href=\\\"https://github.com/CirclonGroup/angular-tree-component/blob/master/projects/example-app/src/app/drag/drag.component.ts\\\" target=\\\"_blank\\\">Source code for this demo</a>\"\n}\n[/block]\n\n[block:api-header]\n{\n \"type\": \"basic\",\n \"title\": \"Options\"\n}\n[/block]\n\n[block:code]\n{\n \"codes\": [\n {\n \"code\": \"options = {\\n allowDrag: (node) => node.isLeaf,\\n allowDrop: (element, { parent, index }) {\\n // return true / false based on element, to.parent, to.index. e.g.\\n return parent.hasChildren;\\n },\\n getNodeClone: (node) => ({\\n ...node.data,\\n id: uuid.v4(),\\n name: `copy of ${node.data.name}`\\n })\\n};\\n\\noptions2 = {\\n allowDrag: true,\\n allowDrop: false\\n};\\n\\n<tree-root\\n\\t\\t[nodes]=\\\"nodes\\\"\\n\\t\\t[options]=\\\"options\\\"></tree-root>\",\n \"language\": \"javascript\",\n \"name\": \"Allow drag & drop using `allowDrag` flag in tree options\"\n }\n ]\n}\n[/block]\nDragging:\nEnable dragging with `allowDrag` option (default false) accepts either a boolean or a function:\n* Boolean value - decides if drop is allowed or not on the tree\n* Function - decides on a per node basis if drop is allowed. The function receives:\n * node - the dragged TreeNode\n\nDropping:\nEnable selective dropping with the `allowDrop` option (default true) accepts either a boolean or a function:\n* Boolean value - decides if drop is allowed or not on the tree\n* Function - decides on a per node basis if drop is allowed. The function receives:\n * element - the dragged element\n * to - drop location structure\n * parent - the parent node\n * index - the index inside the parent's children where the element is dropped\n\nCopying:\nThe default behaviour of the tree is to copy the node when `ctrl` is pressed while dropping the node\n* By default the tree will shallow-clone the node data and generates a random ID\n* if `getNodeClone` option is supplied, it will be called to get a copy of the node. It receives a TreeNode object, and should return a node object (only the data).\n[block:api-header]\n{\n \"type\": \"basic\",\n \"title\": \"Event\"\n}\n[/block]\nYou can listen to `moveNode` events and get the moved node, and its new location in the tree\n[block:code]\n{\n \"codes\": [\n {\n \"code\": \"options = {\\n allowDrag: true\\n}\\n\\nonMoveNode($event) {\\n console.log(\\n \\t\\\"Moved\\\",\\n \\t$event.node.name,\\n \\t\\\"to\\\",\\n \\t$event.to.parent.name,\\n \\t\\\"at index\\\",\\n \\t$event.to.index);\\n}\\n\\n<tree-root\\n\\t\\t(moveNode)=\\\"onMoveNode($event)\\\"\\n\\t\\t[nodes]=\\\"nodes\\\"\\n\\t\\t[options]=\\\"options\\\"></tree-root>\",\n \"language\": \"javascript\",\n \"name\": \"listen to moveNode events\"\n }\n ]\n}\n[/block]\n\n[block:api-header]\n{\n \"type\": \"basic\",\n \"title\": \"Override default behaviour\"\n}\n[/block]\nuse `actionMapping.mouse.drop` to override the default drag behaviour.\nYou can also listen to all other drag events like dragEnd, dragLeave etc.:\n[block:code]\n{\n \"codes\": [\n {\n \"code\": \"options = {\\n allowDrag: true,\\n actionMapping: {\\n \\tmouse: {\\n drop: (tree:TreeModel, node:TreeNode, $event:any, {from, to}) => {\\n // use from to get the dragged node.\\n // use to.parent and to.index to get the drop location\\n // use TREE_ACTIONS.MOVE_NODE to invoke the original action\\n },\\n dragStart?: IActionHandler,\\n drag?: IActionHandler,\\n dragEnd?: IActionHandler,\\n dragOver?: IActionHandler,\\n dragLeave?: IActionHandler,\\n dragEnter?: IActionHandler \\n }\\n }\\n}\\n\\n<tree-root\\n\\t\\t[nodes]=\\\"nodes\\\"\\n\\t\\t[options]=\\\"options\\\"></tree-root>\",\n \"language\": \"javascript\",\n \"name\": \"Override drag & drop action in actionMapping\"\n }\n ]\n}\n[/block]\nIn the drop callback, you get a 'from' and 'to' objects:\n- from:\n - If dragging a node, then from === the dragged node\n - If dragging something else, it is the draggedElement (see treeDrag directive below)\n\n- to:\n - parent: the parent node\n - index: the index inside the parent's children where the node should be dropped\n - dropOnNode: distinguish between dropping on the node itself or the drop slot\n\n[block:api-header]\n{\n \"title\": \"Drag and drop between trees\"\n}\n[/block]\nThis is enabled by default when dragging is enabled\n[block:api-header]\n{\n \"type\": \"basic\",\n \"title\": \"Drag a node outside of the tree\"\n}\n[/block]\nYou can use the (treeDrop) directive to allow dragging nodes to an external element.\nFor example:\n[block:code]\n{\n \"codes\": [\n {\n \"code\": \"<div (treeDrop)=\\\"onDrop($event)\\\"\\n [treeAllowDrop]=\\\"allowDrop.bind(this)\\\"></div>\\n\\n onDrop($event) {\\n // Dropped $event.element\\n }\\n\\n allowDrop(element) {\\n // Return true/false based on element\\n }\\n\",\n \"language\": \"javascript\",\n \"name\": \"use (treeDrop) to drag an external element to the tree\"\n }\n ]\n}\n[/block]\nUse `$event.element` inside the callback.\nUse `[treeAllowDrop]` Input to specify a function that runs onDragOver, and decides if the dropping is allowed or not.\n\n[block:api-header]\n{\n \"type\": \"basic\",\n \"title\": \"Drag an external element into the tree\"\n}\n[/block]\nYou can use the `[treeDrag]` directive to allow dragging external elements into the tree.\nThen use a custom action to handle the drop (see [Action Mapping](doc:action-mapping) section).\n\nFor example:\n[block:code]\n{\n \"codes\": [\n {\n \"code\": \"options = {\\n actionMapping: {\\n mouse: {\\n drop: (tree, node, $event, {from, to}) => {\\n console.log('drag', from, to); // from === {name: 'first'}\\n // Add a node to `to.parent` at `to.index` based on the data in `from`\\n // Then call tree.update()\\n }\\n }\\n }\\n}\\n\\n<p [treeDrag]=\\\"{name: 'first'}\\\" [treeDragEnabled]=\\\"true\\\">Drag me!</p>\\n<p [treeDrag]=\\\"{name: 'second'}\\\">Drag me as well!</p>\",\n \"language\": \"javascript\"\n }\n ]\n}\n[/block]\nThe data that you pass to `[treeDrag]` will be passed to the handler in the `from` parameter.\n\nUse `to.parent` and `to.index` to get the drop location.\nUse `to.dropOnNode` to distinguish between dropping on the node itself or the drop slot.\nIf you add a new node to the tree, you'll need to call `tree.update()` afterwards.\n\nUse `[treeDragEnabled]` boolean Input to decide if the drag is enabled or not.\n\n[block:api-header]\n{\n \"type\": \"basic\",\n \"title\": \"Drag to an empty tree\"\n}\n[/block]\nTo drag to an empty tree, set your nodes to an empty array.\nIf nodes is undefined or null, the drop slot will not appear.\n[block:api-header]\n{\n \"title\": \"Mobile\"\n}\n[/block]\nTo support drag and drop on mobile, you can use DragDropTouch polyfill in your project to enable it.\nDownload the code from here: [https://github.com/Bernardo-Castilho/dragdroptouch](https://github.com/Bernardo-Castilho/dragdroptouch)\nPlace it somewhere in your code, and import it from polyfills.ts, or just place a script tag to include it.\n[block:api-header]\n{\n \"type\": \"basic\",\n \"title\": \"Styling\"\n}\n[/block]\nThe following classes are available for dragging over elements, based on allowDrop:\n* is-dragging-over\n* is-dragging-over-disabled\n\nYou can disable those classes completely by setting the `allowDragoverStyling` option to false.\n[block:api-header]\n{\n \"title\": \"Performance Issues\"\n}\n[/block]\nIt there are performance issues on large trees while drag and drop it's possible to detach change detection during the drag.\n\n[block:code]\n{\n \"codes\": [\n {\n \"code\": \"// use private cdr: ChangeDetectorRef in constructor\\n\\nlet treeOptions: ITreeOptions = {\\n actionMapping: {\\n mouse: {\\n dragStart: () => { this.cdr.detach(); },\\n dragEnd: () => { this.cdr.reattach(); },\\n }\\n }\\n};\",\n \"language\": \"javascript\"\n }\n ]\n}\n[/block]","updates":["58877ea023d3cc3100e73ebd","58877ea18c43372500b05474","58877ef8e5ef250f00cb9049","5888628be7c13a2d00751e73","58a5a520d498872f0022e400","5ab46d87c0cef5007e1da3bc","5f479ca093519d0018410d88"],"order":3,"isReference":false,"hidden":false,"sync_unique":"","link_url":"","link_external":false,"_id":"5c27be9e2b75bd0045dc7469","category":{"sync":{"isSync":false,"url":""},"pages":[],"title":"Guides","slug":"documentation","order":1,"from_sync":false,"reference":false,"_id":"5c27be9e2b75bd0045dc7459","version":"5c27be9e2b75bd0045dc7476","project":"5707c6875309d117006948d4","createdAt":"2016-04-08T14:56:07.661Z","__v":0},"parentDoc":null,"user":"54d742a80771980d0052f4b5","project":"5707c6875309d117006948d4","version":{"version":"8.2.0","version_clean":"8.2.0","codename":"","is_stable":true,"is_beta":false,"is_hidden":false,"is_deprecated":false,"categories":["5c27be9e2b75bd0045dc7458","5c27be9e2b75bd0045dc7459","5c27be9e2b75bd0045dc745a"],"_id":"5c27be9e2b75bd0045dc7476","project":"5707c6875309d117006948d4","__v":0,"forked_from":"5b65b08eb1906e000319f872","createdAt":"2018-03-23T13:06:33.352Z","releaseDate":"2018-03-23T13:06:33.352Z"},"createdAt":"2016-10-04T10:39:38.807Z","githubsync":"","__v":1}