Drag and drop in React Kanban component
27 Jan 202324 minutes to read
All cards can be dragged and dropped across the columns or within the columns or swimlane row or kanban to an external source and vice versa.
The following drag and drop types are available in the Kanban board.
- Internal drag and drop
- Column drag and drop
- Swimlane drag and drop
- External drag and drop
- Kanban to Kanban
- Kanban to External source and vice versa.
Dropped card position varies based on the
sortSettings
property.
Internal drag and drop
Allows the user to drag and drop the cards within the kanban board. Based on this, we can categorize into two ways.
- Column drag and drop
- Swimlane drag and drop
Column drag and drop
By default, all cards can be dragged and dropped across the columns and within the columns. You cannot drag and drop the cards when disabling the allowDragAndDrop
property.
You can prevent the drag or drop behavior of the particular column by disabling the
allowDrag
orallowDrop
property.
You can also control the flow of transition cards between the columns by using thetransitionColumns
property.
In the following example, disable the drag and drop behavior on the Kanban board.
[Class-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
class App extends React.Component {
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
}
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings={{ contentField: "Summary", headerField: "Id" }} allowDragAndDrop={false}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="In Progress" keyField="InProgress"/>
<ColumnDirective headerText="Testing" keyField="Testing"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>;
}
}
;
ReactDOM.render(<App />, document.getElementById('kanban'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
class App extends React.Component<{}, {}>{
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
}
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings={{ contentField: "Summary", headerField: "Id" }} allowDragAndDrop={false}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
}
};
ReactDOM.render(<App />, document.getElementById('kanban'));
<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban Cards</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban Cards" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>
[Functional-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
function App() {
let data = extend([], kanbanData, null, true);
return (<KanbanComponent id="kanban" keyField="Status" dataSource={data} cardSettings={{ contentField: "Summary", headerField: "Id" }} allowDragAndDrop={false}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="In Progress" keyField="InProgress"/>
<ColumnDirective headerText="Testing" keyField="Testing"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>);
}
ReactDOM.render(<App />, document.getElementById('kanban'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
function App(){
let data = extend([], kanbanData, null, true);
return(
<KanbanComponent id="kanban" keyField="Status" dataSource={data} cardSettings={{ contentField: "Summary", headerField: "Id" }} allowDragAndDrop={false}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
);
}
ReactDOM.render(<App />, document.getElementById('kanban'));
<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban Cards</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban Cards" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>
Swimlane drag and drop
By default, Swimlane allows drag and drop across the columns within the swimlane row. Kanban does not allow dragging the cards across the swimlane rows.
Enabling the dragAndDrop
property allows you to drag the cards across the swimlane rows, which is specified inside the swimlaneSettings
property.
[Class-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
class App extends React.Component {
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
}
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings={{ contentField: "Summary", headerField: "Id" }} swimlaneSettings={{ keyField: "Assignee", allowDragAndDrop: true }}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="In Progress" keyField="InProgress"/>
<ColumnDirective headerText="Testing" keyField="Testing"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>;
}
}
;
ReactDOM.render(<App />, document.getElementById('kanban'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
class App extends React.Component<{}, {}>{
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
}
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings={{ contentField: "Summary", headerField: "Id" }} swimlaneSettings={{ keyField: "Assignee",allowDragAndDrop: true }}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
}
};
ReactDOM.render(<App />, document.getElementById('kanban'));
<!DOCTYPE html>
<html lang="en">
<head>
<title>Across Swimlane Drag and Drop</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Swimlane drag and drop" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>
[Functional-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
function App() {
let data = extend([], kanbanData, null, true);
return (<KanbanComponent id="kanban" keyField="Status" dataSource={data} cardSettings={{ contentField: "Summary", headerField: "Id" }} swimlaneSettings={{ keyField: "Assignee", allowDragAndDrop: true }}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="In Progress" keyField="InProgress"/>
<ColumnDirective headerText="Testing" keyField="Testing"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>);
}
ReactDOM.render(<App />, document.getElementById('kanban'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
function App(){
let data = extend([], kanbanData, null, true);
return(
<KanbanComponent id="kanban" keyField="Status" dataSource={data} cardSettings={{ contentField: "Summary", headerField: "Id" }} swimlaneSettings={{ keyField: "Assignee",allowDragAndDrop: true }}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
);
}
ReactDOM.render(<App />, document.getElementById('kanban'));
<!DOCTYPE html>
<html lang="en">
<head>
<title>Across Swimlane Drag and Drop</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Swimlane drag and drop" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>
External drag and drop
Allows the user to drag and drop the cards from one kanban to another kanban or Kanban to an external source and vice versa.
Kanban to kanban
Drag and drop the card from one kanban to another kanban and vice versa. This can be achieved by specifying the externalDropId
property which is used to specify the id of the dropped kanban element and the dragStop
event which is used to delete the card on dragged Kanban and add the card on dropped Kanban using the deleteCard
and addCard
public methods.
Before adding a card to dropped kanban, you can manually change the card data
headerField
when the same card dataheaderField
is dropped to another Kanban.
In the following example, Drag the card from one Kanban and drop it into another kanban using the dragStop
event. In this event, remove the card from the dragged Kanban by using the deleteCard
public method and add the card to the dropped Kanban by using the addCard
public method.
[Class-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend, closest } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanAData, kanbanBData } from './datasource';
class App extends React.Component {
kanbanA;
kanbanB;
constructor() {
super(...arguments);
this.dataA = extend([], kanbanAData, null, true);
this.dataB = extend([], kanbanBData, null, true);
this.externalKanbanADropId = ["#KanbanB"];
this.externalKanbanBDropId = ["#KanbanA"];
}
onKanbanADragStop(args) {
let kanbanBElement = closest(args.event.target, '#KanbanB');
if (kanbanBElement) {
this.kanbanA.deleteCard(args.data);
args.data.forEach((card, i) => {
const index = this.kanbanB.kanbanData.findIndex((colData) => colData[this.kanbanB.cardSettings.headerField] === card[this.kanbanB.cardSettings.headerField]);
if (index !== -1) {
card[this.kanbanB.cardSettings.headerField] = Math.max(...this.kanbanB.kanbanData.map((obj) => parseInt(obj[this.kanbanB.cardSettings.headerField], 10))) + ++i;
}
});
this.kanbanB.addCard(args.data, args.dropIndex);
args.cancel = true;
}
}
onKanbanBDragStop(args) {
let kanbanAElement = closest(args.event.target, '#KanbanA');
if (kanbanAElement) {
this.kanbanB.deleteCard(args.data);
args.data.forEach((card, i) => {
const index = this.kanbanA.kanbanData.findIndex((colData) => colData[this.kanbanA.cardSettings.headerField] === card[this.kanbanA.cardSettings.headerField]);
if (index !== -1) {
card[this.kanbanA.cardSettings.headerField] = Math.max(...this.kanbanA.kanbanData.map((obj) => parseInt(obj[this.kanbanA.cardSettings.headerField], 10))) + ++i;
}
});
this.kanbanA.addCard(args.data, args.dropIndex);
args.cancel = true;
}
}
render() {
return <div>
<div className="container-fluid">
<div className="row">
<div className="col-sm-6">
<h4>Kanban A</h4>
<KanbanComponent id="KanbanA" ref={kanbanA => this.kanbanA = kanbanA} keyField="Status" dataSource={this.dataA} cardSettings={{ contentField: "Summary", headerField: "Id" }} dragStop={this.onKanbanADragStop.bind(this)} externalDropId={this.externalKanbanADropId}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>
</div>
<div className="col-sm-6">
<h4>Kanban B</h4>
<KanbanComponent id="KanbanB" ref={kanbanB => this.kanbanB = kanbanB} keyField="Status" dataSource={this.dataB} cardSettings={{ contentField: "Summary", headerField: "Id" }} dragStop={this.onKanbanBDragStop.bind(this)} externalDropId={this.externalKanbanBDropId}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>
</div>
</div>
</div>
</div>;
}
}
;
ReactDOM.render(<App />, document.getElementById('kanban'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend, closest } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective, DragEventArgs, Kanban } from "@syncfusion/ej2-react-kanban";
import { kanbanAData, kanbanBData } from './datasource';
class App extends React.Component<{}, {}>{
public kanbanA: Kanban | null;
public kanbanB: Kanban | null;
constructor() {
super(...arguments);
this.dataA = extend([], kanbanAData, null, true);
this.dataB = extend([], kanbanBData, null, true);
this.externalKanbanADropId = ["#KanbanB"];
this.externalKanbanBDropId = ["#KanbanA"];
}
private onKanbanADragStop(args: DragEventArgs): void {
let kanbanBElement: Element = closest(args.event.target as Element, '#KanbanB');
if (kanbanBElement) {
this.kanbanA.deleteCard(args.data);
args.data.forEach((card: Record<string, any>, i: number) => {
const index: number = this.kanbanB.kanbanData.findIndex((colData: Record<string, any>) =>
colData[this.kanbanB.cardSettings.headerField] === card[this.kanbanB.cardSettings.headerField]);
if (index !== -1) {
card[this.kanbanB.cardSettings.headerField] = Math.max(...this.kanbanB.kanbanData.map(
(obj: Record<string, string>) => parseInt(obj[this.kanbanB.cardSettings.headerField], 10))) + ++i;
}
});
this.kanbanB.addCard(args.data, args.dropIndex);
args.cancel = true;
}
}
private onKanbanBDragStop(args: DragEventArgs): void {
let kanbanAElement: Element = closest(args.event.target as Element, '#KanbanA');
if (kanbanAElement) {
this.kanbanB.deleteCard(args.data);
args.data.forEach((card: Record<string, any>, i: number) => {
const index: number = this.kanbanA.kanbanData.findIndex((colData: Record<string, any>) =>
colData[this.kanbanA.cardSettings.headerField] === card[this.kanbanA.cardSettings.headerField]);
if (index !== -1) {
card[this.kanbanA.cardSettings.headerField] = Math.max(...this.kanbanA.kanbanData.map(
(obj: Record<string, string>) => parseInt(obj[this.kanbanA.cardSettings.headerField], 10))) + ++i;
}
});
this.kanbanA.addCard(args.data, args.dropIndex);
args.cancel = true;
}
}
render() {
return <div>
<div className="container-fluid">
<div className="row">
<div className="col-sm-6">
<h4>Kanban A</h4>
<KanbanComponent id="KanbanA" ref={kanbanA => this.kanbanA = kanbanA} keyField="Status" dataSource={this.dataA} cardSettings={{ contentField: "Summary", headerField: "Id" }} dragStop={this.onKanbanADragStop.bind(this)} externalDropId={this.externalKanbanADropId}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
</div>
<div className="col-sm-6">
<h4>Kanban B</h4>
<KanbanComponent id="KanbanB" ref={kanbanB => this.kanbanB = kanbanB} keyField="Status" dataSource={this.dataB} cardSettings={{ contentField: "Summary", headerField: "Id" }} dragStop={this.onKanbanBDragStop.bind(this)} externalDropId={this.externalKanbanBDropId}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
</div>
</div>
</div>
</div>
}
};
ReactDOM.render(<App />, document.getElementById('kanban'));
<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban to Kanban drag and drop</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban to Kanban drag and drop" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
.row {
display: flex;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>
[Functional-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend, closest } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanAData, kanbanBData } from './datasource';
function App() {
let kanbanA;
let kanbanB;
let dataA = extend([], kanbanAData, null, true);
let dataB = extend([], kanbanBData, null, true);
let externalKanbanADropId = ["#KanbanB"];
let externalKanbanBDropId = ["#KanbanA"];
function onKanbanADragStop(args) {
let kanbanBElement = closest(args.event.target, '#KanbanB');
if (kanbanBElement) {
kanbanA.deleteCard(args.data);
args.data.forEach((card, i) => {
const index = kanbanB.kanbanData.findIndex((colData) => colData[kanbanB.cardSettings.headerField] === card[kanbanB.cardSettings.headerField]);
if (index !== -1) {
card[kanbanB.cardSettings.headerField] = Math.max(...kanbanB.kanbanData.map((obj) => parseInt(obj[kanbanB.cardSettings.headerField], 10))) + ++i;
}
});
kanbanB.addCard(args.data, args.dropIndex);
args.cancel = true;
}
}
function onKanbanBDragStop(args) {
let kanbanAElement = closest(args.event.target, '#KanbanA');
if (kanbanAElement) {
kanbanB.deleteCard(args.data);
args.data.forEach((card, i) => {
const index = kanbanA.kanbanData.findIndex((colData) => colData[kanbanA.cardSettings.headerField] === card[kanbanA.cardSettings.headerField]);
if (index !== -1) {
card[kanbanA.cardSettings.headerField] = Math.max(...kanbanA.kanbanData.map((obj) => parseInt(obj[kanbanA.cardSettings.headerField], 10))) + ++i;
}
});
kanbanA.addCard(args.data, args.dropIndex);
args.cancel = true;
}
}
return (<div>
<div className="container-fluid">
<div className="row">
<div className="col-sm-6">
<h4>Kanban A</h4>
<KanbanComponent id="KanbanA" ref={kanbanA => kanbanA = kanbanA} keyField="Status" dataSource={dataA} cardSettings={{ contentField: "Summary", headerField: "Id" }} dragStop={onKanbanADragStop.bind(this)} externalDropId={externalKanbanADropId}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>
</div>
<div className="col-sm-6">
<h4>Kanban B</h4>
<KanbanComponent id="KanbanB" ref={kanbanB => kanbanB = kanbanB} keyField="Status" dataSource={dataB} cardSettings={{ contentField: "Summary", headerField: "Id" }} dragStop={onKanbanBDragStop.bind(this)} externalDropId={externalKanbanBDropId}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>
</div>
</div>
</div>
</div>);
}
ReactDOM.render(<App />, document.getElementById('kanban'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend, closest } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective, DragEventArgs, Kanban } from "@syncfusion/ej2-react-kanban";
import { kanbanAData, kanbanBData } from './datasource';
function App(){
let kanbanA: Kanban | null;
let kanbanB: Kanban | null;
let dataA = extend([], kanbanAData, null, true);
let dataB = extend([], kanbanBData, null, true);
let externalKanbanADropId = ["#KanbanB"];
let externalKanbanBDropId = ["#KanbanA"];
function onKanbanADragStop(args: DragEventArgs): void {
let kanbanBElement: Element = closest(args.event.target as Element, '#KanbanB');
if (kanbanBElement) {
kanbanA.deleteCard(args.data);
args.data.forEach((card: Record<string, any>, i: number) => {
const index: number = kanbanB.kanbanData.findIndex((colData: Record<string, any>) =>
colData[kanbanB.cardSettings.headerField] === card[kanbanB.cardSettings.headerField]);
if (index !== -1) {
card[kanbanB.cardSettings.headerField] = Math.max(...kanbanB.kanbanData.map(
(obj: Record<string, string>) => parseInt(obj[kanbanB.cardSettings.headerField], 10))) + ++i;
}
});
kanbanB.addCard(args.data, args.dropIndex);
args.cancel = true;
}
}
function onKanbanBDragStop(args: DragEventArgs): void {
let kanbanAElement: Element = closest(args.event.target as Element, '#KanbanA');
if (kanbanAElement) {
kanbanB.deleteCard(args.data);
args.data.forEach((card: Record<string, any>, i: number) => {
const index: number = kanbanA.kanbanData.findIndex((colData: Record<string, any>) =>
colData[kanbanA.cardSettings.headerField] === card[kanbanA.cardSettings.headerField]);
if (index !== -1) {
card[kanbanA.cardSettings.headerField] = Math.max(...kanbanA.kanbanData.map(
(obj: Record<string, string>) => parseInt(obj[kanbanA.cardSettings.headerField], 10))) + ++i;
}
});
kanbanA.addCard(args.data, args.dropIndex);
args.cancel = true;
}
}
return(
<div>
<div className="container-fluid">
<div className="row">
<div className="col-sm-6">
<h4>Kanban A</h4>
<KanbanComponent id="KanbanA" ref={kanbanA => kanbanA = kanbanA} keyField="Status" dataSource={dataA} cardSettings={{ contentField: "Summary", headerField: "Id" }} dragStop={onKanbanADragStop.bind(this)} externalDropId={externalKanbanADropId}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
</div>
<div className="col-sm-6">
<h4>Kanban B</h4>
<KanbanComponent id="KanbanB" ref={kanbanB => kanbanB = kanbanB} keyField="Status" dataSource={dataB} cardSettings={{ contentField: "Summary", headerField: "Id" }} dragStop={onKanbanBDragStop.bind(this)} externalDropId={externalKanbanBDropId}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
</div>
</div>
</div>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('kanban'));
<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban to Kanban drag and drop</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban to Kanban drag and drop" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
.row {
display: flex;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>
Treeview to Kanban
Drag the card from the Kanban board and drop it to the Treeview component and vice versa.
In the following sample, remove the data from the Kanban board using the deleteCard
public method and add to the Treeview component using the addNodes
public method at Kanban dragStop
event when dragging the card and dropping it to the Treeview component. Remove the data from Treeview using the removeNodes
public method and add to Kanban board using the openDialog
public method when dragging the list from the Treeview component and dropping it to the kanban board.
[Class-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend, closest } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { TreeViewComponent } from '@syncfusion/ej2-react-navigations';
import { kanbanData, treeViewData } from './datasource';
class App extends React.Component {
kanbanObj;
treeViewObj;
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
this.treeData = extend([], treeViewData, null, true);
this.fields = { dataSource: this.treeData, id: 'Id', text: 'Status' };
this.allowDragAndDrops = true;
this.externalKanbanDropId = ["#treeView"];
}
treeTemplate(props) {
return (<div><div id="treelist"><div id="treeviewlist">{props.Id} - {props.Status}</div>
</div></div>);
}
onKanbanADragStop(args) {
let treeViewElement = closest(args.event.target, '#treeView');
if (treeViewElement) {
this.kanbanObj.deleteCard(args.data);
this.treeViewObj.addNodes(args.data);
args.cancel = true;
}
}
onTreeDragStop(args) {
let kanbanElement = closest(args.event.target, '#Kanban');
if (kanbanElement) {
let treeData = this.treeViewObj.fields.dataSource;
const filteredData = treeData.filter((item) => item.Id === parseInt(args.draggedNodeData.id, 10));
this.treeViewObj.removeNodes([args.draggedNodeData.id]);
this.kanbanObj.openDialog('Add', filteredData[0]);
args.cancel = true;
}
}
render() {
return <div>
<div className="container-fluid">
<div className="row">
<div className="col-sm-6">
<h4>Kanban</h4>
<KanbanComponent id="Kanban" ref={kanban => this.kanbanObj = kanban} keyField="Status" dataSource={this.data} cardSettings={{ contentField: "Summary", headerField: "Id" }} dragStop={this.onKanbanADragStop.bind(this)} externalDropId={this.externalKanbanDropId}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>
</div>
<div className="col-sm-6">
<h4>TreeView</h4>
<TreeViewComponent id="treeView" ref={treeView => this.treeViewObj = treeView} nodeTemplate={this.treeTemplate.bind(this)} fields={this.fields} nodeDragStop={this.onTreeDragStop.bind(this)} allowDragAndDrop={this.allowDragAndDrops}/>
</div>
</div>
</div>
</div>;
}
}
;
ReactDOM.render(<App />, document.getElementById('kanban'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend, closest } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective, DragEventArgs, Kanban } from "@syncfusion/ej2-react-kanban";
import { DragAndDropEventArgs } from '@syncfusion/ej2-navigations';
import { TreeViewComponent } from '@syncfusion/ej2-react-navigations';
import { kanbanData, treeViewData } from './datasource';
class App extends React.Component<{}, {}>{
public kanbanObj: Kanban | null;
public treeViewObj: TreeViewComponent | null;
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
this.treeData = extend([], treeViewData, null, true);
this.fields = { dataSource: this.treeData, id: 'Id', text: 'Status' };
this.allowDragAndDrops = true;
this.externalKanbanDropId = ["#treeView"];
}
private treeTemplate(props: KanbanDataModel): JSX.Element {
return (<div><div id="treelist"><div id="treeviewlist">{props.Id} - {props.Status}</div>
</div></div>);
}
private onKanbanADragStop(args: DragEventArgs): void {
let treeViewElement: Element = closest(args.event.target as Element, '#treeView');
if (treeViewElement) {
this.kanbanObj.deleteCard(args.data);
this.treeViewObj.addNodes(args.data);
args.cancel = true;
}
}
private onTreeDragStop(args: DragAndDropEventArgs): void {
let kanbanElement: Element = closest(args.event.target as Element, '#Kanban');
if (kanbanElement) {
let treeData = this.treeViewObj.fields.dataSource as { [key: string]: Object }[];
const filteredData =
treeData.filter((item: any) => item.Id === parseInt(args.draggedNodeData.id as string, 10));
this.treeViewObj.removeNodes([args.draggedNodeData.id] as string[]);
this.kanbanObj.openDialog('Add', filteredData[0]);
args.cancel = true;
}
}
render() {
return <div>
<div className="container-fluid">
<div className="row">
<div className="col-sm-6">
<h4>Kanban</h4>
<KanbanComponent id="Kanban" ref={kanban => this.kanbanObj = kanban} keyField="Status" dataSource={this.data} cardSettings={{ contentField: "Summary", headerField: "Id" }} dragStop={this.onKanbanADragStop.bind(this)} externalDropId={this.externalKanbanDropId} >
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
</div>
<div className="col-sm-6">
<h4>TreeView</h4>
<TreeViewComponent id="treeView" ref={treeView => this.treeViewObj = treeView} nodeTemplate={this.treeTemplate.bind(this)} fields={this.fields} nodeDragStop={this.onTreeDragStop.bind(this)} allowDragAndDrop={this.allowDragAndDrops} />
</div>
</div>
</div>
</div>
}
};
ReactDOM.render(<App />, document.getElementById('kanban'));
<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban to treeview drag and drop</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban to treeview drag and drop" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
.row {
display: flex;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>
[Functional-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend, closest } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { TreeViewComponent } from '@syncfusion/ej2-react-navigations';
import { kanbanData, treeViewData } from './datasource';
function App() {
let kanbanObj;
let treeViewObj;
let data = extend([], kanbanData, null, true);
let treeData = extend([], treeViewData, null, true);
let fields = { dataSource: treeData, id: 'Id', text: 'Status' };
let allowDragAndDrops = true;
let externalKanbanDropId = ["#treeView"];
function treeTemplate(props) {
return (<div><div id="treelist"><div id="treeviewlist">{props.Id} - {props.Status}</div></div></div>);
}
function onKanbanADragStop(args) {
let treeViewElement = closest(args.event.target, '#treeView');
if (treeViewElement) {
kanbanObj.deleteCard(args.data);
treeViewObj.addNodes(args.data);
args.cancel = true;
}
}
function onTreeDragStop(args) {
let kanbanElement = closest(args.event.target, '#Kanban');
if (kanbanElement) {
let treeData = treeViewObj.fields.dataSource;
const filteredData = treeData.filter((item) => item.Id === parseInt(args.draggedNodeData.id, 10));
treeViewObj.removeNodes([args.draggedNodeData.id]);
kanbanObj.openDialog('Add', filteredData[0]);
args.cancel = true;
}
}
return (<div>
<div className="container-fluid">
<div className="row">
<div className="col-sm-6">
<h4>Kanban</h4>
<KanbanComponent id="Kanban" ref={kanban => kanbanObj = kanban} keyField="Status" dataSource={data} cardSettings={{ contentField: "Summary", headerField: "Id" }} dragStop={onKanbanADragStop.bind(this)} externalDropId={externalKanbanDropId}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>
</div>
<div className="col-sm-6">
<h4>TreeView</h4>
<TreeViewComponent id="treeView" ref={treeView => treeViewObj = treeView} nodeTemplate={treeTemplate.bind(this)} fields={fields} nodeDragStop={onTreeDragStop.bind(this)} allowDragAndDrop={allowDragAndDrops}/>
</div>
</div>
</div>
</div>);
}
ReactDOM.render(<App />, document.getElementById('kanban'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend, closest } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective, DragEventArgs, Kanban } from "@syncfusion/ej2-react-kanban";
import { DragAndDropEventArgs } from '@syncfusion/ej2-navigations';
import { TreeViewComponent } from '@syncfusion/ej2-react-navigations';
import { kanbanData, treeViewData } from './datasource';
function App(){
let kanbanObj: Kanban | null;
let treeViewObj: TreeViewComponent | null;
let data = extend([], kanbanData, null, true);
let treeData = extend([], treeViewData, null, true);
let fields = { dataSource: treeData, id: 'Id', text: 'Status' };
let allowDragAndDrops = true;
let externalKanbanDropId = ["#treeView"];
function treeTemplate(props: KanbanDataModel): JSX.Element {
return (<div><div id="treelist"><div id="treeviewlist">{props.Id} - {props.Status}</div></div></div>);
}
function onKanbanADragStop(args: DragEventArgs): void {
let treeViewElement: Element = closest(args.event.target as Element, '#treeView');
if (treeViewElement) {
kanbanObj.deleteCard(args.data);
treeViewObj.addNodes(args.data);
args.cancel = true;
}
}
function onTreeDragStop(args: DragAndDropEventArgs): void {
let kanbanElement: Element = closest(args.event.target as Element, '#Kanban');
if (kanbanElement) {
let treeData = treeViewObj.fields.dataSource as { [key: string]: Object }[];
const filteredData =
treeData.filter((item: any) => item.Id === parseInt(args.draggedNodeData.id as string, 10));
treeViewObj.removeNodes([args.draggedNodeData.id] as string[]);
kanbanObj.openDialog('Add', filteredData[0]);
args.cancel = true;
}
}
return(
<div>
<div className="container-fluid">
<div className="row">
<div className="col-sm-6">
<h4>Kanban</h4>
<KanbanComponent id="Kanban" ref={kanban => kanbanObj = kanban} keyField="Status" dataSource={data} cardSettings={{ contentField: "Summary", headerField: "Id" }} dragStop={onKanbanADragStop.bind(this)} externalDropId={externalKanbanDropId} >
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
</div>
<div className="col-sm-6">
<h4>TreeView</h4>
<TreeViewComponent id="treeView" ref={treeView => treeViewObj = treeView} nodeTemplate={treeTemplate.bind(this)} fields={fields} nodeDragStop={onTreeDragStop.bind(this)} allowDragAndDrop={allowDragAndDrops} />
</div>
</div>
</div>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('kanban'));
<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban to treeview drag and drop</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban to treeview drag and drop" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
.row {
display: flex;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>
Schedule to Kanban
Drag the card from the Kanban board and drop it to the Schedule component and vice versa.
In the following sample, remove the data from the Kanban board using the deleteCard
public method and add to the schedule component using the addNodes
public method at Kanban dragStop
event when dragging the card and dropping it to the Treeview component. Remove the data from Treeview using the removeNodes
public method and add to Kanban board using the addCard
public method when dragging the list from the Treeview component and dropping it to the kanban board.
[Class-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend, closest, removeClass } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { ScheduleComponent, ResourcesDirective, ResourceDirective, ViewsDirective, ViewDirective, Inject, TimelineViews, Resize, DragAndDrop, TimelineMonth } from '@syncfusion/ej2-react-schedule';
import { kanbanData, scheduleData } from './datasource';
class App extends React.Component {
kanbanObj;
scheduleObj;
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
this.scheduleDataSource = extend([], scheduleData, null, true);
this.externalKanbanDropId = ["#Schedule"];
}
departmentData = [
{ Text: 'GENERAL', Id: 1, Color: '#bbdc00' },
{ Text: 'DENTAL', Id: 2, Color: '#9e5fff' }
];
consultantData = [
{ Text: 'Alice', Id: 1, GroupId: 1, Color: '#bbdc00', Designation: 'Cardiologist' },
{ Text: 'Nancy', Id: 2, GroupId: 2, Color: '#9e5fff', Designation: 'Orthodontist' },
{ Text: 'Robert', Id: 3, GroupId: 1, Color: '#bbdc00', Designation: 'Optometrist' },
{ Text: 'Robson', Id: 4, GroupId: 2, Color: '#9e5fff', Designation: 'Periodontist' },
{ Text: 'Laura', Id: 5, GroupId: 1, Color: '#bbdc00', Designation: 'Orthopedic' },
{ Text: 'Margaret', Id: 6, GroupId: 2, Color: '#9e5fff', Designation: 'Endodontist' }
];
getConsultantName(value) {
return value.resourceData[value.resource.textField];
}
getConsultantDesignation(value) {
return value.resourceData.Designation;
}
resourceHeaderTemplate(props) {
return (<div className="template-wrap"><div className="specialist-category"><div className="specialist-name">
{this.getConsultantName(props)}</div><div className="specialist-designation">{this.getConsultantDesignation(props)}</div></div></div>);
}
onKanbanDragStop(args) {
let scheduleElement = closest(args.event.target, '#Schedule');
if (scheduleElement) {
this.kanbanObj.deleteCard(args.data);
this.scheduleObj.openEditor(args.data[0], 'Add', true);
args.cancel = true;
}
}
scheduleDragStop(args) {
let kanbanElement = closest(args.event.target, '#Kanban');
if (kanbanElement) {
this.scheduleObj.deleteEvent(args.data.Id);
removeClass([this.scheduleObj.element.querySelector('.e-selected-cell')], 'e-selected-cell');
this.kanbanObj.openDialog('Add', args.data);
args.cancel = true;
}
}
render() {
return <div>
<div className="container-fluid">
<div className="row">
<div className="col-sm-6">
<h4>Kanban</h4>
<KanbanComponent id="Kanban" ref={kanban => this.kanbanObj = kanban} keyField="DepartmentName" dataSource={this.data} cardSettings={{ contentField: "Name", headerField: "Id" }} dragStop={this.onKanbanDragStop.bind(this)} externalDropId={this.externalKanbanDropId}>
<ColumnsDirective>
<ColumnDirective headerText="GENERAL" keyField="GENERAL"/>
</ColumnsDirective>
</KanbanComponent>
</div>
<div className="col-sm-6">
<h4>Schedule</h4>
<ScheduleComponent id="Schedule" ref={schedule => this.scheduleObj = schedule} cssClass='schedule-drag-drop' width='100%' height='650px' selectedDate={new Date(2018, 7, 1)} currentView='TimelineDay' resourceHeaderTemplate={this.resourceHeaderTemplate.bind(this)} eventSettings={{
dataSource: this.scheduleDataSource,
fields: {
subject: { title: 'Patient Name', name: 'Name' },
startTime: { title: "From", name: "StartTime" },
endTime: { title: "To", name: "EndTime" },
description: { title: 'Reason', name: 'Description' }
}
}} group={{ enableCompactView: false, resources: ['Departments', 'Consultants'] }} dragStop={this.scheduleDragStop.bind(this)}>
<ResourcesDirective>
<ResourceDirective field='DepartmentID' title='Department' name='Departments' allowMultiple={false} dataSource={this.departmentData} textField='Text' idField='Id' colorField='Color'>
</ResourceDirective>
<ResourceDirective field='ConsultantID' title='Consultant' name='Consultants' allowMultiple={false} dataSource={this.consultantData} textField='Text' idField='Id' groupIDField="GroupId" colorField='Color'>
</ResourceDirective>
</ResourcesDirective>
<ViewsDirective>
<ViewDirective option='TimelineDay'/>
<ViewDirective option='TimelineMonth'/>
</ViewsDirective>
<Inject services={[TimelineViews, TimelineMonth, Resize, DragAndDrop]}/>
</ScheduleComponent>
</div>
</div>
</div>
</div>;
}
}
;
ReactDOM.render(<App />, document.getElementById('kanban'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend, closest, removeClass } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective, DragEventArgs, Kanban } from "@syncfusion/ej2-react-kanban";
import {
ScheduleComponent, ResourcesDirective, ResourceDirective,
ViewsDirective, ViewDirective, Inject, TimelineViews,
Resize, DragAndDrop, TimelineMonth
} from '@syncfusion/ej2-react-schedule';
import { kanbanData, scheduleData } from './datasource';
class App extends React.Component<{}, {}>{
public kanbanObj: Kanban | null;
public scheduleObj: ScheduleComponent | null;
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
this.scheduleDataSource = extend([], scheduleData, null, true);
this.externalKanbanDropId = ["#Schedule"];
}
private departmentData: Object[] = [
{ Text: 'GENERAL', Id: 1, Color: '#bbdc00' },
{ Text: 'DENTAL', Id: 2, Color: '#9e5fff' }
];
private consultantData: Object[] = [
{ Text: 'Alice', Id: 1, GroupId: 1, Color: '#bbdc00', Designation: 'Cardiologist' },
{ Text: 'Nancy', Id: 2, GroupId: 2, Color: '#9e5fff', Designation: 'Orthodontist' },
{ Text: 'Robert', Id: 3, GroupId: 1, Color: '#bbdc00', Designation: 'Optometrist' },
{ Text: 'Robson', Id: 4, GroupId: 2, Color: '#9e5fff', Designation: 'Periodontist' },
{ Text: 'Laura', Id: 5, GroupId: 1, Color: '#bbdc00', Designation: 'Orthopedic' },
{ Text: 'Margaret', Id: 6, GroupId: 2, Color: '#9e5fff', Designation: 'Endodontist' }
];
private getConsultantName(value: ResourceDetails | TreeViewArgs): string {
return (value as ResourceDetails).resourceData[(value as ResourceDetails).resource.textField] as string;
}
private getConsultantDesignation(value: ResourceDetails): string {
return (value as ResourceDetails).resourceData.Designation as string;
}
private resourceHeaderTemplate(props: any): JSX.Element {
return (<div className="template-wrap"><div className="specialist-category"><div className="specialist-name">
{this.getConsultantName(props)}</div><div className="specialist-designation">{this.getConsultantDesignation(props)}</div></div></div>);
}
private onKanbanDragStop(args: DragEventArgs): void {
let scheduleElement: Element = closest(args.event.target as Element, '#Schedule');
if (scheduleElement) {
this.kanbanObj.deleteCard(args.data);
this.scheduleObj.openEditor(args.data[0], 'Add', true);
args.cancel = true;
}
}
private scheduleDragStop(args: ScheduleDragEventArgs): void {
let kanbanElement: Element = closest(args.event.target as Element, '#Kanban');
if (kanbanElement) {
this.scheduleObj.deleteEvent(args.data.Id);
removeClass([this.scheduleObj.element.querySelector('.e-selected-cell')], 'e-selected-cell');
this.kanbanObj.openDialog('Add', args.data);
args.cancel = true;
}
}
render() {
return <div>
<div className="container-fluid">
<div className="row">
<div className="col-sm-6">
<h4>Kanban</h4>
<KanbanComponent id="Kanban" ref={kanban => this.kanbanObj = kanban} keyField="DepartmentName" dataSource={this.data} cardSettings={{ contentField: "Name", headerField: "Id" }} dragStop={this.onKanbanDragStop.bind(this)} externalDropId={this.externalKanbanDropId}>
<ColumnsDirective>
<ColumnDirective headerText="GENERAL" keyField="GENERAL" />
</ColumnsDirective>
</KanbanComponent>
</div>
<div className="col-sm-6">
<h4>Schedule</h4>
<ScheduleComponent id="Schedule" ref={schedule => this.scheduleObj = schedule} cssClass='schedule-drag-drop' width='100%' height='650px' selectedDate={new Date(2018, 7, 1)}
currentView='TimelineDay' resourceHeaderTemplate={this.resourceHeaderTemplate.bind(this)}
eventSettings={{
dataSource: this.scheduleDataSource,
fields: {
subject: { title: 'Patient Name', name: 'Name' },
startTime: { title: "From", name: "StartTime" },
endTime: { title: "To", name: "EndTime" },
description: { title: 'Reason', name: 'Description' }
}
}}
group={{ enableCompactView: false, resources: ['Departments', 'Consultants'] }}
dragStop={this.scheduleDragStop.bind(this)} >
<ResourcesDirective>
<ResourceDirective field='DepartmentID' title='Department' name='Departments' allowMultiple={false}
dataSource={this.departmentData} textField='Text' idField='Id' colorField='Color'>
</ResourceDirective>
<ResourceDirective field='ConsultantID' title='Consultant' name='Consultants' allowMultiple={false}
dataSource={this.consultantData} textField='Text' idField='Id' groupIDField="GroupId" colorField='Color'>
</ResourceDirective>
</ResourcesDirective>
<ViewsDirective>
<ViewDirective option='TimelineDay' />
<ViewDirective option='TimelineMonth' />
</ViewsDirective>
<Inject services={[TimelineViews, TimelineMonth, Resize, DragAndDrop]} />
</ScheduleComponent>
</div>
</div>
</div>
</div>
}
};
ReactDOM.render(<App />, document.getElementById('kanban'));
<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban to schedule drag and drop</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban to schedule drag and drop" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-calendars/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-excel-export/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-file-utils/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-schedule/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-compression/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
.row {
display: flex;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>
[Functional-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend, closest, removeClass } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { ScheduleComponent, ResourcesDirective, ResourceDirective, ViewsDirective, ViewDirective, Inject, TimelineViews, Resize, DragAndDrop, TimelineMonth } from '@syncfusion/ej2-react-schedule';
import { kanbanData, scheduleData } from './datasource';
function App() {
let kanbanObj;
let scheduleObj;
let data = extend([], kanbanData, null, true);
let scheduleDataSource = extend([], scheduleData, null, true);
let externalKanbanDropId = ["#Schedule"];
let departmentData = [
{ Text: 'GENERAL', Id: 1, Color: '#bbdc00' },
{ Text: 'DENTAL', Id: 2, Color: '#9e5fff' }
];
let consultantData = [
{ Text: 'Alice', Id: 1, GroupId: 1, Color: '#bbdc00', Designation: 'Cardiologist' },
{ Text: 'Nancy', Id: 2, GroupId: 2, Color: '#9e5fff', Designation: 'Orthodontist' },
{ Text: 'Robert', Id: 3, GroupId: 1, Color: '#bbdc00', Designation: 'Optometrist' },
{ Text: 'Robson', Id: 4, GroupId: 2, Color: '#9e5fff', Designation: 'Periodontist' },
{ Text: 'Laura', Id: 5, GroupId: 1, Color: '#bbdc00', Designation: 'Orthopedic' },
{ Text: 'Margaret', Id: 6, GroupId: 2, Color: '#9e5fff', Designation: 'Endodontist' }
];
function getConsultantName(value) {
return value.resourceData[value.resource.textField];
}
function getConsultantDesignation(value) {
return value.resourceData.Designation;
}
function resourceHeaderTemplate(props) {
return (<div className="template-wrap"><div className="specialist-category"><div className="specialist-name">
{getConsultantName(props)}</div><div className="specialist-designation">{getConsultantDesignation(props)}</div></div></div>);
}
function onKanbanDragStop(args) {
let scheduleElement = closest(args.event.target, '#Schedule');
if (scheduleElement) {
kanbanObj.deleteCard(args.data);
scheduleObj.openEditor(args.data[0], 'Add', true);
args.cancel = true;
}
}
function scheduleDragStop(args) {
let kanbanElement = closest(args.event.target, '#Kanban');
if (kanbanElement) {
scheduleObj.deleteEvent(args.data.Id);
removeClass([scheduleObj.element.querySelector('.e-selected-cell')], 'e-selected-cell');
kanbanObj.openDialog('Add', args.data);
args.cancel = true;
}
}
return (<div>
<div className="container-fluid">
<div className="row">
<div className="col-sm-6">
<h4>Kanban</h4>
<KanbanComponent id="Kanban" ref={kanban => kanbanObj = kanban} keyField="DepartmentName" dataSource={data} cardSettings={{ contentField: "Name", headerField: "Id" }} dragStop={onKanbanDragStop.bind(this)} externalDropId={externalKanbanDropId}>
<ColumnsDirective>
<ColumnDirective headerText="GENERAL" keyField="GENERAL"/>
</ColumnsDirective>
</KanbanComponent>
</div>
<div className="col-sm-6">
<h4>Schedule</h4>
<ScheduleComponent id="Schedule" ref={schedule => scheduleObj = schedule} cssClass='schedule-drag-drop' width='100%' height='650px' selectedDate={new Date(2018, 7, 1)} currentView='TimelineDay' resourceHeaderTemplate={resourceHeaderTemplate.bind(this)} eventSettings={{
dataSource: scheduleDataSource,
fields: {
subject: { title: 'Patient Name', name: 'Name' },
startTime: { title: "From", name: "StartTime" },
endTime: { title: "To", name: "EndTime" },
description: { title: 'Reason', name: 'Description' }
}
}} group={{ enableCompactView: false, resources: ['Departments', 'Consultants'] }} dragStop={scheduleDragStop.bind(this)}>
<ResourcesDirective>
<ResourceDirective field='DepartmentID' title='Department' name='Departments' allowMultiple={false} dataSource={departmentData} textField='Text' idField='Id' colorField='Color'>
</ResourceDirective>
<ResourceDirective field='ConsultantID' title='Consultant' name='Consultants' allowMultiple={false} dataSource={consultantData} textField='Text' idField='Id' groupIDField="GroupId" colorField='Color'>
</ResourceDirective>
</ResourcesDirective>
<ViewsDirective>
<ViewDirective option='TimelineDay'/>
<ViewDirective option='TimelineMonth'/>
</ViewsDirective>
<Inject services={[TimelineViews, TimelineMonth, Resize, DragAndDrop]}/>
</ScheduleComponent>
</div>
</div>
</div>
</div>);
}
ReactDOM.render(<App />, document.getElementById('kanban'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend, closest, removeClass } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective, DragEventArgs, Kanban } from "@syncfusion/ej2-react-kanban";
import {
ScheduleComponent, ResourcesDirective, ResourceDirective,
ViewsDirective, ViewDirective, Inject, TimelineViews,
Resize, DragAndDrop, TimelineMonth
} from '@syncfusion/ej2-react-schedule';
import { kanbanData, scheduleData } from './datasource';
function App(){
let kanbanObj: Kanban | null;
let scheduleObj: ScheduleComponent | null;
let data = extend([], kanbanData, null, true);
let scheduleDataSource = extend([], scheduleData, null, true);
let externalKanbanDropId = ["#Schedule"];
let departmentData: Object[] = [
{ Text: 'GENERAL', Id: 1, Color: '#bbdc00' },
{ Text: 'DENTAL', Id: 2, Color: '#9e5fff' }
];
let consultantData: Object[] = [
{ Text: 'Alice', Id: 1, GroupId: 1, Color: '#bbdc00', Designation: 'Cardiologist' },
{ Text: 'Nancy', Id: 2, GroupId: 2, Color: '#9e5fff', Designation: 'Orthodontist' },
{ Text: 'Robert', Id: 3, GroupId: 1, Color: '#bbdc00', Designation: 'Optometrist' },
{ Text: 'Robson', Id: 4, GroupId: 2, Color: '#9e5fff', Designation: 'Periodontist' },
{ Text: 'Laura', Id: 5, GroupId: 1, Color: '#bbdc00', Designation: 'Orthopedic' },
{ Text: 'Margaret', Id: 6, GroupId: 2, Color: '#9e5fff', Designation: 'Endodontist' }
];
function getConsultantName(value: ResourceDetails | TreeViewArgs): string {
return (value as ResourceDetails).resourceData[(value as ResourceDetails).resource.textField] as string;
}
function getConsultantDesignation(value: ResourceDetails): string {
return (value as ResourceDetails).resourceData.Designation as string;
}
function resourceHeaderTemplate(props: any): JSX.Element {
return (<div className="template-wrap"><div className="specialist-category"><div className="specialist-name">
{getConsultantName(props)}</div><div className="specialist-designation">{getConsultantDesignation(props)}</div></div></div>);
}
function onKanbanDragStop(args: DragEventArgs): void {
let scheduleElement: Element = closest(args.event.target as Element, '#Schedule');
if (scheduleElement) {
kanbanObj.deleteCard(args.data);
scheduleObj.openEditor(args.data[0], 'Add', true);
args.cancel = true;
}
}
function scheduleDragStop(args: ScheduleDragEventArgs): void {
let kanbanElement: Element = closest(args.event.target as Element, '#Kanban');
if (kanbanElement) {
scheduleObj.deleteEvent(args.data.Id);
removeClass([scheduleObj.element.querySelector('.e-selected-cell')], 'e-selected-cell');
kanbanObj.openDialog('Add', args.data);
args.cancel = true;
}
}
return (
<div>
<div className="container-fluid">
<div className="row">
<div className="col-sm-6">
<h4>Kanban</h4>
<KanbanComponent id="Kanban" ref={kanban => kanbanObj = kanban} keyField="DepartmentName" dataSource={data} cardSettings={{ contentField: "Name", headerField: "Id" }} dragStop={onKanbanDragStop.bind(this)} externalDropId={externalKanbanDropId}>
<ColumnsDirective>
<ColumnDirective headerText="GENERAL" keyField="GENERAL" />
</ColumnsDirective>
</KanbanComponent>
</div>
<div className="col-sm-6">
<h4>Schedule</h4>
<ScheduleComponent id="Schedule" ref={schedule => scheduleObj = schedule} cssClass='schedule-drag-drop' width='100%' height='650px' selectedDate={new Date(2018, 7, 1)}
currentView='TimelineDay' resourceHeaderTemplate={resourceHeaderTemplate.bind(this)}
eventSettings={{
dataSource: scheduleDataSource,
fields: {
subject: { title: 'Patient Name', name: 'Name' },
startTime: { title: "From", name: "StartTime" },
endTime: { title: "To", name: "EndTime" },
description: { title: 'Reason', name: 'Description' }
}
}}
group={{ enableCompactView: false, resources: ['Departments', 'Consultants'] }}
dragStop={scheduleDragStop.bind(this)} >
<ResourcesDirective>
<ResourceDirective field='DepartmentID' title='Department' name='Departments' allowMultiple={false}
dataSource={departmentData} textField='Text' idField='Id' colorField='Color'>
</ResourceDirective>
<ResourceDirective field='ConsultantID' title='Consultant' name='Consultants' allowMultiple={false}
dataSource={consultantData} textField='Text' idField='Id' groupIDField="GroupId" colorField='Color'>
</ResourceDirective>
</ResourcesDirective>
<ViewsDirective>
<ViewDirective option='TimelineDay' />
<ViewDirective option='TimelineMonth' />
</ViewsDirective>
<Inject services={[TimelineViews, TimelineMonth, Resize, DragAndDrop]} />
</ScheduleComponent>
</div>
</div>
</div>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('kanban'));
<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban to schedule drag and drop</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban to schedule drag and drop" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-calendars/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-excel-export/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-file-utils/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-schedule/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-react-compression/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
.row {
display: flex;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>