Search code examples
angulartypescriptangular-materialangular7

Problem with drag and drop and creating new element in html


im trying to implement a dinamic drag and drop (angular-material) in angular 7. The case is this: I have multiples objects in a expansion panel with "Priority", i want to move that objects between the priorities/expansion panels (actually work). But, the problem start when i try to add a new empty "Priority", then when i try to drag and drop a object to the new priority, it dosnt work:

this is the gif of the problem

This is the html code:

    <button (click)="createNewPrioridad()">Create new Priority</button>
    <br>
    <div cdkDropListGroup>
    <mat-expansion-panel *ngFor="let item of fleet" (opened)="panelOpenState = true"
                         (closed)="panelOpenState = false">
      <mat-expansion-panel-header>
        <mat-panel-title>
          Priority
        </mat-panel-title>
    
      </mat-expansion-panel-header>
      <div class="example-list" *ngIf="item.children"
      cdkDropList
      [cdkDropListData]="item.children"
      (cdkDropListDropped)="drop($event)">
        <div class="example-box" *ngFor="let item of item.children" cdkDrag>
          {{item.item}}
          <button (click)="checkIndex(item)">Checke Index</button>
        </div>
    </div>
    </mat-expansion-panel>
    </div>

This is the ts code:

  fleet: any[] = [
    {
      Item: 'Priority 1',
      children: [
        { item: 'Admiral Flankson', tipo: 'Mother' },
        { item: 'pvt. centeras',tipo: 'Son' },
        { item: 'pvt. leeft',tipo: 'Father' },
        { item: 'pvt. rijks',tipo: 'Son' },
      ],
    },
    {
      Item: 'Priority 2',
      children: [
        { item: 'Admiral Parkour', tipo: 'Mother' },
        { item: 'pvt. jumph', tipo: 'Brother' },
        { item: 'pvt. landts', tipo: 'Son' },
        { item: 'pvt. drobs', tipo: 'Son' },
      ],
    },
    {
      Item: 'Priority 3',
      children: [
        { item: 'Admiral Tombs', tipo: 'Father' },
        { item: 'pvt. zomboss', tipo: 'Son' },
        { item: 'pvt. digger', tipo: 'Son' },
        { item: 'pvt. skaari' , tipo: 'Son'},
      ],
    },
  ];



  panelOpenState:any
  drop(event: CdkDragDrop<{}[]>) {
    if (event.previousContainer == event.container) {
      moveItemInArray(
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );
    } else {
      transferArrayItem(
        event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );
    }
    console.log(this.fleet);
  }

  
  checkIndex(item:any){
    console.log(item, 'aca esta el item para editar')
  }

  createNewPrioridad(){
    this.fleet.push({Item: "",children: ""})
  }

Solution

  • When you add a new priority item, you are initializing the children property to an empty string.

    createNewPrioridad(){
      this.fleet.push({Item: "",children: ""})
    }
    

    So the div.example-list with the cdkDropList is not rendering in that case because the *ngIf clause evaluates to false

    <div class="example-list" *ngIf="item.children"
      cdkDropList
      [cdkDropListData]="item.children"
      (cdkDropListDropped)="drop($event)"
    >
    

    Initialize children to an empty array [] instead and give the div a minimum height with css, and the problem should be solved.

    cheers