Search code examples
angularmaterial-uiangular-materiallifecycleangular-cdk

Angular cdk drag and drop into Material dialog


I am implementing a Drag and Drop using Angular cdk and am getting stuck trying to drag the element into a Dialog which is a child container of the container that contains the cdkDropListGroup. To demonstrate the hierarchy graphically:

enter image description here

All the white boxes are components. The final goal is to be able to drag and drop elements between all Child components of WorkbenchComponent, including the ones that are generated programmatically.

Obviously since they are not part of the "template tree" at compile time however, the WorkbenchComponent cdkDropListGroup does not include the dialogs.

Now I am struggling to find any way how to make the drag and drop into the SubwindowComponents work (using Material).

HTML5 drag and drop as well as primeng drag and drop does not work unfortunately, due to security restrictions with certain browsers in the deployment context.

Edit: Maybe something along the lines of ComponentFactoryResolver or ViewContainerRef could work?


Solution

  • Providing more information about (what I believe to be) the approach suggested by @TotallyNewb. (And what I would choose as the accepted answer)

    The solution is rather simple. In the component that generates the materials DialogComponent instances (here: the SidebarSubwindowComponent), we need to add the ViewContainerRef to the MatDialogConfig object that is passed to the open method of the dialog. This ViewContainerRef can be passed on to all grandchildren. In code:

    1. Parent component (member of cdkDropListGroup)
    import { Component, OnInit, ViewContainerRef } from '@angular/core';
    
    export class ParentComponent implements OnInit {
    
      constructor (private viewContainerRef: ViewContainerRef) { }
    
      openDialog() {
        const dialogConfig = new MatDialogConfig();
        dialogConfig.viewContainerRef = this.viewContainerRef;
    
        let childDialogComponent = ChildDialogComponent;
    
        const dialogRef = this.dialog.open(childDialogComponent , dialogConfig);
        
        dialogRef.afterClosed().subscribe();
      }
    }
    
    1. Child Component (with Dialog)
    import { Component, OnInit, Inject, ViewContainerRef } from '@angular/core';
    
    export class SubwindowTableComponent implements OnInit {
    
      constructor (private viewContainerRef: ViewContainerRef) {}
    
      showGrandChild() {
        const dialogConfig = new MatDialogConfig();
        dialogConfig.viewContainerRef = this.viewContainerRef;
        const dialogRef = this.dialog.open(GrandChildDialogComponent, dialogConfig);
        // and so on and so forth
      }
    }