Angular — An extremely simple and easy implementation of drag and drop list reordering without library

Liu Ting Chun
4 min readApr 20, 2021

Drag and drop list reordering is a very common feature of webpages with lists of data, such as Trello, Jira, etc. It is also a frequently asked question during frontend developer interviews. It was once one of the most difficult features to implement due to huge amount of DOM manipulations and overlap calculations. Yet, with the help of the HTML drag and drop API and modern frontend frameworks, this feature now only needs tens of lines to implement.

Here I am going to go through an example on implementing the drag and drop reordering feature in an exiting page with a list of data.

Implementation

Say we have a list of data in our page:

@Component({
...
template: `
<div class="card" *ngFor="let row of data">
{{ row }}
</div>
`,
styles: [`
.card {
border: 1px solid black;
padding: 4px;
margin: 8px 0;
}
`]
})
export class ListComponent {
data: string[] = [...];
}

The first step is to connect the drag and drop API with the component.

@Component({
...
template: `
<div class="drag-wrapper"
*ngFor="let row of data; let index = index"
[draggable]="true" (dragstart)="onDragStart(index)"
(dragenter)="onDragEnter(index)" (dragend)="onDragEnd()">
<div class="card">{{ row }}</div>
</div>
`,
styles: [`
.drag-wrapper {
padding: 4px 0;
}

.card {
border: 1px solid black;
padding: 4px;
}
`]
})
export class ListComponent {
data: string[] = [...];
...
}

First, we enable the drag and drop API on the given items via binding true to [draggable]. For the three events, dragstart and dragend are pretty self-descriptive which fire when the drag starts and ends, while dragenter refers to the moment when the bound items collide with the item that is currently being dragged. Besides, the reason to wrap the items with wrappers is to get rid of the margin, which make the detection of collision unsmooth.

Liu Ting Chun

Web developer from Hong Kong. Most interested in Angular and Vue. Currently working on a Nuxt.js + NestJS project.

Recommended from Medium

Lists

See more recommendations