All Components

Sortable Overview

The Sortable provides a sortable drag-and-drop functionality to elements within a list.

Basic Usage

The following example demonstrates the Sortable in action.

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <div class="example-config">
        <h6>Items: {{items | json}}</h6>
    </div>
    <div class="container-fluid">
        <kendo-sortable
            [kendoSortableBinding]="items"
            [navigatable]="true"
            [animation] = "true"
            class="row"
            itemClass="item col-xs-6 col-sm-3"
            activeItemClass="item col-xs-6 col-sm-3 active"
        >
        </kendo-sortable>
    </div>
  `,
  encapsulation: ViewEncapsulation.None,
  styleUrls: ['styles.css']
})
export class AppComponent {
  public items: string[] = [
    'Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6', 'Item 7', 'Item 8'
  ];
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { SortableModule } from '@progress/kendo-angular-sortable';
import { AppComponent } from './app.component';

@NgModule({
    bootstrap:    [AppComponent],
    declarations: [AppComponent],
    imports:      [BrowserModule, BrowserAnimationsModule, SortableModule]
})
export class AppModule {}

.item {
    background-color: #bfe7f9;
    color: #1494d0;
    border: 1px solid #fff;
    height: 70px;
    line-height: 68px;
    font-size: 16px;
    text-align: center;
    outline: none;
    cursor: move;
}

.item:hover,
.employee:hover {
    opacity: 0.8;
}

.item.active,
.employee.active {
    background-color: #27aceb;
    color: #fff;
    border-color: #27aceb;
    z-index: 10;
}

.item.disabled {
    opacity: 0.5;
    cursor: default;
}

.team {
    min-height: 240px;
    padding-top: 15px;
    padding-bottom: 15px;
    border: 1px solid #fff;
    background-color: #dff3fc;
}

.team-b {
    background-color: #fbe0e7;
}

.employee {
    background-color: #bfe7f9;
    color: #1494d0;
    margin: 1px;
    padding: 5px;
    cursor: move;
}

.team-b .employee {
    background-color: #f3b9c9;
    color: #dd4672;
}

.team-b .employee.active {
    background-color: #dd4672;
    color: #fff;
}

.empty {
    height: 150px;
}
import { AppModule } from './app.module';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Installation

Either use the quick setup (Angular CLI v6 or later) or manually add the package (Angular CLI v5 or earlier).

Quick Setup with Angular CLI v6 or Later

Angular CLI v6 supports the addition of packages through the ng add command which executes in one step the set of otherwise individually needed commands.

ng add @progress/kendo-angular-sortable        

Manual Setup

  1. Download and install the package.

    npm install --save @progress/kendo-angular-sortable @progress/kendo-angular-l10n
  2. For Angular 6, install the rxjs-compat package. For more information, refer to the article on upgrading to Angular 6.

    npm install --save rxjs-compat@6

    For Angular 5 or earlier, install RxJS v5.5+.

    npm install --save rxjs@^5.5
  3. Once installed, import the SortableModule in your application root or feature module.

    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
    import { SortableModule } from '@progress/kendo-angular-sortable';
    import { AppComponent } from './app.component';
    
    @NgModule({
       bootstrap:    [AppComponent],
       declarations: [AppComponent],
       imports:      [BrowserModule, BrowserAnimationsModule, SortableModule]
    })
    export class AppModule {
    }
  4. You are required to install one of the Kendo UI themes for Angular to style your component. For more information on how to add the styles, refer to the section on styling.

Dependencies

The Sortable package requires the following peer dependencies that have to be installed by your application:

  • @angular/common
  • @angular/core
  • @progress/kendo-angular-l10n
  • rxjs

The Sortable package utilizes the Angular animation system, which supports a specific set of browsers.

Functionality and Features

Events

The following example demonstrates basic Sortable events.

import { Component, ViewEncapsulation } from '@angular/core';
import { DataEvent, DragDropEvent } from '@progress/kendo-angular-sortable';

@Component({
  selector: 'my-app',
  template: `
    <div class="container-fluid" *ngFor="let group of items; let i = index">
        <kendo-sortable
            zone="default"
            [navigatable]="true"
            [animation] = "true"
            [kendoSortableBinding]="items[i]"
            class="row"
            itemClass="item col-xs-6 col-sm-3"
            activeItemClass="item col-xs-6 col-sm-3 active"
            (dataAdd)="onDataAdd(i, $event)"
            (dataRemove)="onDataRemove(i, $event)"
            (dataMove)="onDataMove(i, $event)"
            (dragEnd)="onDragEnd(i, $event)"
            (dragOver)="onDragOver(i, $event)"
            (dragStart)="onDragStart(i, $event)"
            (navigate)="onNavigate(i, $event)"
        >
        </kendo-sortable>
        <event-log title="Event log" [events]="events[i]">
        </event-log>
    </div>
  `,
  encapsulation: ViewEncapsulation.None,
  styleUrls: ['styles.css']
})
export class AppComponent {
  public items: string[][] = [
    ['Item 1', 'Item 2', 'Item 3', 'Item 4'],
    ['Item 5', 'Item 6', 'Item 7', 'Item 8']
  ];

  public events: string[][] = [[], []];

  public onDataAdd(src: number, e: DataEvent): void {
      this.log(src, 'dataAdd', e.dataItem);
  }

  public onDataMove(src: number, e: DataEvent): void {
      this.log(src, 'dataMove', e.dataItem);
  }

  public onDataRemove(src: number, e: DataEvent): void {
    this.log(src, 'dataRemove', e.dataItem);
  }

  public onDragEnd(src: number, e: DragDropEvent): void {
    this.log(src, 'dragEnd', this.items[src][e.index]);
  }

  public onDragOver(src: number, e: DragDropEvent): void {
    this.log(src, 'dragOver', this.items[src][e.index]);
  }

  public onDragStart(src: number, e: DragDropEvent): void {
    this.log(src, 'dragStart', this.items[src][e.index]);
  }

  public onNavigate(src: number, e: DragDropEvent): void {
    this.log(src, 'navigate', this.items[src][e.index]);
  }
    private log(src: number, event: string, item: any): void {
      this.events[src].push(`${event} - ${item}`);
  }
}

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { SortableModule } from '@progress/kendo-angular-sortable';
import { AppComponent } from './app.component';
import { EventLogComponent } from './event-log.component';

@NgModule({
    bootstrap:    [AppComponent],
    declarations: [AppComponent, EventLogComponent],
    imports:      [BrowserModule, BrowserAnimationsModule, SortableModule]
})
export class AppModule {}

import { Component, Input } from '@angular/core';

@Component({
  selector: 'event-log',
  template: `
    <div class="example-config">
      <h5>{{ title }}</h5>
      <ul class="event-log">
        <li *ngFor="let event of events.reverse()">{{ event }}</li>
      </ul>
    </div>
  `
})
export class EventLogComponent {
  @Input() title: string;
  @Input() events: string[];
}

.item {
    background-color: #bfe7f9;
    color: #1494d0;
    border: 1px solid #fff;
    height: 70px;
    line-height: 68px;
    font-size: 16px;
    text-align: center;
    outline: none;
    cursor: move;
}

.item:hover,
.employee:hover {
    opacity: 0.8;
}

.item.active,
.employee.active {
    background-color: #27aceb;
    color: #fff;
    border-color: #27aceb;
    z-index: 10;
}

.item.disabled {
    opacity: 0.5;
    cursor: default;
}

.team {
    min-height: 240px;
    padding-top: 15px;
    padding-bottom: 15px;
    border: 1px solid #fff;
    background-color: #dff3fc;
}

.team-b {
    background-color: #fbe0e7;
}

.employee {
    background-color: #bfe7f9;
    color: #1494d0;
    margin: 1px;
    padding: 5px;
    cursor: move;
}

.team-b .employee {
    background-color: #f3b9c9;
    color: #dd4672;
}

.team-b .employee.active {
    background-color: #dd4672;
    color: #fff;
}

.empty {
    height: 150px;
}
import { AppModule } from './app.module';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Known Limitations

To enable the reordering of items, mark some of the elements in the item template as draggable—for example, button and a.

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <kendo-sortable [kendoSortableBinding]="items">
      <ng-template let-item="item">
        <button draggable="true">
          {{item}}
        </button>
      </ng-template>
    </kendo-sortable>
  `
})
export class AppComponent {
  public items: string[] = [
    'Item 1', 'Item 2', 'Item 3', 'Item 4'
  ];
}
In this article