I am trying to implement a drag-and-drop feature in my Angular 14 Application where I have nested sections and subsections. I want to move each section up or down and subsections will be moved between sections. The section is moving fine and the subsection is also moving into its own section but the problem is when I am trying to move the subsection from one section to another section but it's not moving one section to another section. Here is my code below and can you please help me to solve the issues?
HTML
<div cdkDropListGroup>
<div cdkDropList [cdkDropListData]="demoData" (cdkDropListDropped)="dropSection($event)" class="section-list">
<div *ngFor="let section of demoData; let i = index" class="section" cdkDrag>
<h2>{{ section.title }}</h2>
<div cdkDropList [id]="'sec'+i" [cdkDropListData]="section.subsections" class="subsection-list"
(cdkDropListDropped)="dropSubsection($event, section)">
<div *ngFor="let subsection of section.subsections" class="subsection-item" cdkDrag>
<div *ngIf="subsection.type === 'lecture'">{{ subsection.lecture?.title }}</div>
<div *ngIf="subsection.type === 'assignment'">{{ subsection.assignment?.title }}</div>
</div>
</div>
</div>
</div>
</div>
TS
dropSubsection(event: CdkDragDrop<any[]>, section: any) {
console.log('Event:', event);
console.log('Section:', section);
console.log('Previous Container ID:', event.previousContainer.id);
console.log('Current Container ID:', event.container.id);
if (event.previousContainer === event.container) {
console.log('Moving within the same container');
moveItemInArray(section.subsections, event.previousIndex, event.currentIndex);
} else {
console.log('Moving to a different container');
const previousSection = this.demoData.find((sec) => sec.subsections === event.previousContainer.data);
if (previousSection) {
console.log('Previous Section:', previousSection);
transferArrayItem(previousSection.subsections, section.subsections, event.previousIndex, event.currentIndex);
} else {
console.error('Previous section not found');
}
}
}
Data structure:
demoData = [
{
id: '614ea6e9-ff17-4794-a751-47e27124ff21',
course: '3d285c13-0dc5-4e03-954d-5d5cfb244b07',
title: 'Section 2',
position: 0,
duration: 0,
subsections: [
{
id: '57f58b19-4ce7-4381-873f-85d4175b4839',
type: 'lecture',
position: 1,
lecture: {
id: 'e66eb256-6f6a-43bc-b652-0720c172f4c7',
video_url: null,
date_created: '2024-07-17T09:38:23.995000Z',
date_updated: '2024-07-17T09:44:22.790109Z',
chain_id: 'd4ad01e2-aec1-4a76-ba07-a10690865ab8',
title: 'Article 1',
video: null,
transcoded_video: null,
transcoded_info: {},
video_info: {},
article:
'### Overview\n\n* The descriptions below will be available to the public on your Course Landing PThe descriptions below will be available to the public on your Course Landing PThe descriptions below will be available to the public on your Course Landing PThe descriptions below will be available to the public on your Course Landing PThe descriptions below will be available to the public on your Course Landing PThe descriptions below will be available to the public on your Course Landing PThe descriptions below will be available to the public on your Course Landing P\n',
type: 'Article',
position: 0,
preview: false,
published: false,
source: null,
current_version: null,
section: '614ea6e9-ff17-4794-a751-47e27124ff21',
},
section: '614ea6e9-ff17-4794-a751-47e27124ff21',
date_created: '2024-07-17T09:38:25.379276Z',
date_updated: '2024-07-17T09:38:25.379292Z',
},
{
id: 'b33968c5-3606-4196-a1d4-fe15e5c596cb',
type: 'assignment',
position: 1,
assignment: {
id: 'a120ee88-ea44-42d2-b240-8e7ab4d4d501',
date_created: '2024-07-17T09:44:55.050000Z',
date_updated: '2024-07-17T09:45:07.033183Z',
chain_id: 'bb8862af-0732-4afb-9197-dd5624c13ca8',
title: 'Assignments 1',
source: null,
current_version: null,
lecture: null,
section: '614ea6e9-ff17-4794-a751-47e27124ff21',
questions: [
{
id: '87883251-de9a-4c73-8cf6-45fafefacc22',
question: 'Question 1',
date_created: '2024-07-17T09:45:07.870466Z',
date_updated: '2024-07-17T09:45:07.870482Z',
chain_id: 'a42b0d0e-0735-4128-8bb3-006e64047b66',
expected: null,
source: null,
current_version: null,
assignment: 'a120ee88-ea44-42d2-b240-8e7ab4d4d501',
},
{
id: 'd1bfca3b-4d53-4bd8-97ba-d7b30cc04e85',
question: 'Question 2',
date_created: '2024-07-17T09:45:08.217948Z',
date_updated: '2024-07-17T09:45:08.217964Z',
chain_id: 'd9054b3b-3683-49cf-8fe9-168f1896b6ec',
expected: null,
source: null,
current_version: null,
assignment: 'a120ee88-ea44-42d2-b240-8e7ab4d4d501',
},
],
},
section: '614ea6e9-ff17-4794-a751-47e27124ff21',
date_created: '2024-07-17T09:44:55.654222Z',
date_updated: '2024-07-17T09:44:56.943395Z',
},
],
date_created: '2024-07-17T09:37:18.210964Z',
date_updated: '2024-07-17T09:37:18.210981Z',
source: null,
article_count: 0,
quiz_count: 0,
total: 0,
video_count: 0,
},
{
id: '2fedd3a8-2286-4219-91e4-057b416b6b4d',
course: '3d285c13-0dc5-4e03-954d-5d5cfb244b07',
title: 'Section 3',
position: 0,
duration: 0,
subsections: [
{
id: 'fb7308b7-5a4f-414c-add3-2a236d4a6165',
type: 'lecture',
position: 1,
lecture: {
id: '0b15d0c8-581e-4c64-b5f6-c1176ab1d27e',
video_url: null,
date_created: '2024-07-17T09:47:29.032000Z',
date_updated: '2024-07-17T09:48:06.639444Z',
chain_id: '539dbebf-8040-4906-987e-33eb97c12f50',
title: 'Article 11',
video: null,
transcoded_video: null,
transcoded_info: {},
video_info: {},
article:
'### Overview\n\n* The descriptions below will be available to the public on your Course Landing PThe descriptions below will be available to the public on your Course Landing PThe descriptions below will be available to the public on your Course Landing PThe descriptions below will be available to the public on your Course Landing PThe descriptions below will be available to the public on your Course Landing PThe descriptions below will be available to the public on your Course Landing PThe descriptions below will be available to the public on your Course Landing P\n',
type: 'Article',
position: 0,
preview: false,
published: false,
source: null,
current_version: null,
section: '2fedd3a8-2286-4219-91e4-057b416b6b4d',
},
section: '2fedd3a8-2286-4219-91e4-057b416b6b4d',
date_created: '2024-07-17T09:47:30.610005Z',
date_updated: '2024-07-17T09:47:30.610022Z',
},
],
date_created: '2024-07-17T09:46:22.365769Z',
date_updated: '2024-07-17T09:46:52.524447Z',
source: null,
article_count: 0,
quiz_count: 0,
total: 0,
video_count: 0,
},
];[![enter image description here][1]][1]
As stated here:
If you have an unknown number of connected drop lists, you can use the cdkDropListGroup directive to set up the connection automatically. Note that any new cdkDropList that is added under a group will be connected to all other lists automatically.
<div cdkDropListGroup>
<!-- All lists in here will be connected. -->
<div cdkDropList *ngFor="let list of lists"></div>
</div>
so, in you HTML, just move this line <div cdkDropListGroup>
one line down:
<div cdkDropList [cdkDropListData]="demoData" (cdkDropListDropped)="dropSection($event)" class="section-list">
<div cdkDropListGroup>
<div *ngFor="let section of demoData; let i = index" class="section" cdkDrag>
...
...
...
</div>
</div>
</div>
I created a STACKBLITZ with your code to demonstrate it. In the example I paid attention only to the subsection is not moving from one section to another section issue.
Hope it will help you :)