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
<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];
}