Angular 5: Drag and Drop for ListGroup

0
1576

I recently wrote an angular 5 app at work and ran into a problem where I needed to sort a list via drag and drop. In my special case, I wanted my users to be able to order the columns of a table in any way they wanted to (and also hide them).

Installing the NPM-Package

As a basis I used the npm-package ng2-drag-drop. Just type

npm install ng2-dnd --save

in your console to install it.

This package comes with a lot of diffrent possibilies for drag and drop in angular apps. If you want to check out the demos, you will find them here.

Creating a HTML list with angular

The next step is to create your list with the *ngFor statement of angular.

<ul class="list-group list-group-flush">
   <li *ngFor="let h of headerColumns" class="list-group-item">
     <i class="fas fa-bars mr-2"></i>
     {{h.name}}
   </li>
 </ul>

The list I’m going to sort is headerColumns. The *ngFor will create a list-entry for every item in that array. Please ignore the <i>-Tag. It is used to create the icons you can see in the picture above.

You will see that I used bootstrap for my app. This is not mandatory. The drag and drop functionality will also work with any other list.

Adding the angular sort-directive

<ul class="list-group list-group-flush" dnd-sortable-container [sortableData]="headerColumns" >
   <li *ngFor="let h of headerColumns; let i = index" dnd-sortable [sortableIndex]="i" class="list-group-item">
     <i class="fas fa-bars mr-2"></i>
     {{h.name}}
   </li>
 </ul>

To add the directive for sorting you have to

    1. add the dnd-sortable-container directive to the container (in this case the <ul>-tag).
    2. add the attributeĀ sortableData to the container to make angular aware which array to sort.
    3. add the dnd-sortable directive to the items
    4. tell angular by which attribute to sort by adding theĀ sortableIndex-attribute to the items

Make it clickable

In my special case I want to also toggle the deactivated attribute on click to allow my users to hide table-columns.

I added a click-action and a ngClass-attribute to the items.

<li *ngFor="let h of headerColumns; let i = index" dnd-sortable [sortableIndex]="i" class="list-group-item" [ngClass]="{'active': !h.deactivated}" (click)="h.deactivated=!h.deactivated">

The ngClass will add a class to activated items, so that I can style them diffrently. The click-action will toggle the deactivated-value of the item.

If you have a diffrent project or need help building on top if this, please feel free to ask your questions in the comments.

LEAVE A REPLY

Please enter your comment!
Please enter your name here