Through my travels to many different Angular conferences this past year, I’ve been asked about using Kendo UI alongside things like Angular Material or the CDK. With the latest updates in Angular 7, I thought this would be a wonderful time to show the Angular CDK peacefully working side-by-side with Kendo UI in an Angular app.
A new feature in the CDK, as of version 7, is drag-and-drop that I keep hearing so much about. So I decided to return to the very snazzy Kendo UI Angular 7 todo app that we worked on earlier, and this is what we will include in it today.
Below I've included links to the full source code and a video walkthrough of the app - feel free to take a look and follow along, or just keep reading.
Check out the code on github!You can also watch this episode on Angular Air walking through this app.
LIVE NOW with @schwarty& @Brocco to talk about the wondrous @AngularAir CDK drag-and-drop!! https://t.co/Uelyh7Yj2x@AngularAirpic.twitter.com/CS0ab11Cz5
— Alyssa Nicoll (@AlyssaNicoll) January 16, 2019
Let's Begin
To get going with the drag-and-drop feature from the CDK, we’ll first need to install the Angular CDK with all of its wondrous features, including drag-and-drop.
Install CDK
npm i @angular/cdk
Now we need to import the DragDropModule
into our NgModule
.
Import CDK in Your NgModule
// app.module.ts
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { TodoComponent } from './todo/todo.component';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { ButtonsModule } from '@progress/kendo-angular-buttons';
import { InputsModule } from '@progress/kendo-angular-inputs';
import { DragDropModule } from '@angular/cdk/drag-drop';
@NgModule({
declarations: [
AppComponent,
TodoComponent,
],
imports: [
BrowserModule,
BrowserAnimationsModule,
ButtonsModule,
InputsModule,
DragDropModule,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
cdkDrag
Now we can start implementing the drag-and-drop, using the cdkDrag
directive that we can place on any element we’d like to drag! For our app, we want to drag the Kendo UI buttons around in the list:
<div *ngIf="todos" class="list-group">
<button kendoButton type="button" class="todo" @todoItem cdkDrag
*ngFor="let todo of todos; index as i" >
<span (click)="removeTodo(todo, i)">{{todo}}</span>
</button>
</div>
cdkDropList
So it is true, the buttons are now draggable. However, we’d like the list items to stay inside the list. Luckily, the CDK peeps have already thought of this. They have created a cdkDropList
directive that can be set around the cdkDrag
elements.
<div *ngIf="todos" class="list-group" cdkDropList>
<button kendoButton type="button" class="todo" @todoItem cdkDrag
*ngFor="let todo of todos; index as i" >
<span (click)="removeTodo(todo, i)">{{todo}}</span>
</button>
</div>
So now our draggable items are constrained inside the cdkDropList
area. However, if you’ll notice once you drop a to-do list item, our data model is not being updated, therefore we are never actually able to update our list. Luckily, the CDK team has thought of this as well!!
All we need to do is use this event to update our data model this.todos
! We will do this by creating a method that will call the CDK’s moveItemInArray
method. I called it reorderList
.
reorderList(event: CdkDragDrop<string[]>) {
moveItemInArray(this.todos, event.previousIndex, event.currentIndex);
}
</string[]>
We then call reorderList
on the div wrapping our list (that also has cdkDropList
) when the cdkDropListDropped
event is fired.
Our to-do list is now reordering when we drag and drop!
Note that we don’t have persistent data in this app, so on refresh the list will reset. Once we added calls to save our data to a database, we would need to ensure we also called save on the drop event cdkDropListDropped
.
Animating
As lovely as this is, we can add a bit of polish by transitioning our elements as we drag them. The drag-and-drop directives add classes and transforms to the elements allowing for animations to be possible!
.cdk-drag
- Adding transition
to this class will animate as the user is sorting through a list .
All we need to do to utilize them is add transitions:
/* Animate items as they're being sorted. */
.cdk-drop-list-dragging .cdk-drag {
transition: transform .5s cubic-bezier(0.88, -0.19, 0.26, 1.27);
}
So now look how wonderfully the list updates with this simple transition on the buttons as they drag and drop!
I’ve been really impressed with the well thought out decisions that the CDK team has made and how easy to use the drag-and-drop module is. There are even more things we didn’t cover, like attaching data, dragging from one list to another (like Trello), and customizing the drag area using a handle!
What About Mobile?
On the Angular Air podcast I linked to above, we went over this app and how I implemented the drag-and-drop. My good friend and co-panelist Mike Brocchi mentioned a great point, "what about mobile"? Again I’m astounded by the Angular CDK team’s thoughtfulness. I navigated to their docs and tried using it in my phone:
As you can see, I’m able to grab the item and drag it around using mobile touch events, by default, out-of-the-box!
If you’d like to learn more about how this app was created with Kendo UI for Angular or more about the Angular Animations being used, check out these resources:
A Snazzy To-Do App Using Kendo UI and Angular
Custom Angular Animations in Our Kendo UI To-Do App
As always, thanks for following along and happy coding everyone!!!