Angular Drag Drop CDK cannot drag between brothers and nested

74 views Asked by At

I want drag drop nested List but it only can work under root level 4, and it seem can't drag between brothers

I spend alot of times to find out resolving this problem I have an recursive template that can add a form array

enter image description here

<ng-template #recursiveTemplate  let-parent="parent" let-form="form">
  <div [formGroup]="form" cdkDropListGroup>
    <div class="row" class="drag-box">
      <div class="cell">
        <ng-select (change)="changeDimension(form)" [clearable]="false" formControlName="Dimension" appendTo="#condition-form" 
        class="c-input" [items]="schemaDetailList" bindLabel="Name" bindValue="Code" placeholder="Lọc theo"></ng-select>
      </div>
      <div class="cell" >
        <ng-select [clearable]="false" formControlName="Operator" appendTo="#condition-form"  
        class="c-input" [items]="form.get('Dimension')?.value == 'logical'?logicalOperators:transformOperators" bindLabel="name" bindValue="name"placeholder="So sánh"></ng-select>
      </div>
      <div class="cell" *ngIf="form.get('Dimension')?.value != 'logical'">
        <input type="text" formControlName="Value" class="c-input" placeholder="Value">
      </div>
      <div class="ion-float-right" *ngIf="parent">
        <ion-button color="danger" (click)="removeForm(form,parent)" fill="outline" slot="end" size="small">
          <ion-icon name="trash-outline"></ion-icon>
        </ion-button>
      </div>
    </div>
  
    <!-- Recursively render child forms -->
    <ng-container style="margin-bottom:10px">
      <div class="drag-list" [id]="form.controls.UniqueId.value" [cdkDropListConnectedTo]="connectionList" cdkDropList [cdkDropListData]="form.controls.Logicals" (cdkDropListDropped)="drop($event)" *ngIf="form.controls.Logicals && form.controls.Logicals.controls.length">
        <div cdkDrag style="padding-left:10px"*ngFor="let c of form.controls.Logicals.controls; let i = index" >
            <ng-container [ngTemplateOutlet]="recursiveTemplate" [ngTemplateOutletContext]="{ form: c,parent:form }"> </ng-container>
        </div>
      </div>
    </ng-container>
    <div class="row ion-justify-content-end" *ngIf="form.get('Dimension')?.value=='logical'">
      <ion-button size="small" style="margin-bottom:20px;"  (click)="addNewForm(form.controls.Logicals)">
        <ion-icon slot="icon-only" name="add-outline"></ion-icon>
      </ion-button>
    </div>
  </div>
</ng-template>

in my Ts ,I update ConnectionList every time add new Form, and then I can drag child to parent, but cant from parent to child if I have than more 4 array above

ngOninit: {
 this.formGroup = this.formBuilder.group({
      Dimension: [this.filter.Dimension,Validators.required],
      Operator: [this.filter.Operator,Validators.required],     
      Value: [this.filter.Dimension !== 'logical' ? this.filter.Value : null, this.filter.Dimension !== 'logical' ? [Validators.required] : []],
      Logicals: this.pathValueCondition(this.filter.Logicals),
      UniqueId : [ this.generateUniqueId()]
      });
      this.updateConnectionList(this.formGroup.controls.UniqueId.value);
}
 pathValueCondition(array) {
    var formArray:FormArray = this.formBuilder.array([])
    array.forEach(i => {
      let group = this.formBuilder.group({
        Dimension: [i.Dimension, Validators.required],
        Operator: [i.Operator, Validators.required],
        Logicals: (i.Logicals!=undefined && i.Logicals.length>0)?this.pathValueCondition(i.Logicals):this.formBuilder.array([]),
        Value:[i.Dimension != 'logical'?i.Value:null,(i.Dimension != 'logical')?[Validators.required]:[]],  
        UniqueId : [ this.generateUniqueId()]
      });
      formArray.push(group);
      this.updateConnectionList(group.controls.UniqueId.value);
    })
    
    return formArray;
  }
addNewForm(formArray: FormArray) {
    if(formArray == undefined){
      formArray = this.formBuilder.array([]);
    }
    var fg  = this.formBuilder.group({ 
      Dimension :  [null,[Validators.required]],
      Operator : [null,[Validators.required]],
      Logicals:this.formBuilder.array([]),
      Value: [null,[Validators.required]],  
      UniqueId : [ this.generateUniqueId()]
    })
    formArray.push(fg);
    this.updateConnectionList(fg.controls.UniqueId.value);
   }

  removeForm(form: FormGroup, parentForm: FormGroup): void {
    if (parentForm && parentForm.controls?.Logicals instanceof FormArray) {
      const index = parentForm.controls.Logicals?.controls.indexOf(form);
      if (index !== -1) {
        parentForm.controls.Logicals.removeAt(index);
        [...this.connectionList.filter( x=>x!=this.connectionList.indexOf(form.controls.UniqueId.value))];
      }
    }
  }

  applyData(formGroup){
    if (!this.formGroup.valid) {
        this.env.showTranslateMessage('erp.app.app-component.page-bage.check-red-above','warning');
        return;
    }
    this.submbit.emit(formGroup.getRawValue());
  }
  drop(event: CdkDragDrop<FormArray>) {
    if (event.previousContainer === event.container) {
      moveItemInArray(event.container.data.controls, event.previousIndex, event.currentIndex);
    } else {
      transferArrayItem(event.previousContainer.data.controls,
                        event.container.data.controls,
                        event.previousIndex,
                        event.currentIndex);
    }
  }
  generateUniqueId(): string {
    return Math.random().toString(36).slice(2, 5);
  }
  updateConnectionList(uniqueId) {
    this.connectionList = [...this.connectionList, uniqueId];
  }
0

There are 0 answers