Drag and drop in Vue Kanban component
11 Jun 202424 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.
<template>
<div id="app">
<ejs-kanban id="kanban" keyField="Status" :dataSource="kanbanData"
:cardSettings="cardSettings" :allowDragAndDrop="false">
<e-columns>
<e-column headerText="To Do" keyField="Open"></e-column>
<e-column headerText="In Progress" keyField="InProgress"></e-column>
<e-column headerText="Testing" keyField="Testing"></e-column>
<e-column headerText="Done" keyField="Close"></e-column>
</e-columns>
</ejs-kanban>
</div>
</template>
<script setup>
import { KanbanComponent as EjsKanban, ColumnsDirective as EColumns, ColumnDirective as EColumn } from '@syncfusion/ej2-vue-kanban';
import { extend } from '@syncfusion/ej2-base';
import { kanbanData } from './datasource.js';
kanbanData = extend([], kanbanData, null, true);
const cardSettings = {
contentField: "Summary",
headerField: "Id"
};
</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-layouts/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-kanban/styles/material.css';
</style>
<template>
<div id="app">
<ejs-kanban id="kanban" keyField="Status" :dataSource="kanbanData"
:cardSettings="cardSettings" :allowDragAndDrop="false">
<e-columns>
<e-column headerText="To Do" keyField="Open"></e-column>
<e-column headerText="In Progress" keyField="InProgress"></e-column>
<e-column headerText="Testing" keyField="Testing"></e-column>
<e-column headerText="Done" keyField="Close"></e-column>
</e-columns>
</ejs-kanban>
</div>
</template>
<script>
import { KanbanComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-vue-kanban';
import { extend } from '@syncfusion/ej2-base';
import { kanbanData } from './datasource.js';
export default {
name: "App",
components: {
"ejs-kanban":KanbanComponent,
"e-columns":ColumnsDirective,
"e-column":ColumnDirective
},
data: function() {
return {
kanbanData: extend([], kanbanData, null, true),
cardSettings: {
contentField: "Summary",
headerField: "Id"
}
};
},
}
</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-layouts/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-kanban/styles/material.css';
</style>
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.
<template>
<div id="app">
<ejs-kanban id="kanban" keyField="Status" :dataSource="kanbanData"
:cardSettings="cardSettings" :swimlaneSettings="swimlaneSettings">
<e-columns>
<e-column headerText="To Do" keyField="Open"></e-column>
<e-column headerText="In Progress" keyField="InProgress"></e-column>
<e-column headerText="Testing" keyField="Testing"></e-column>
<e-column headerText="Done" keyField="Close"></e-column>
</e-columns>
</ejs-kanban>
</div>
</template>
<script setup>
import { KanbanComponent as EjsKanban, ColumnsDirective as EColumns, ColumnDirective as EColumn} from '@syncfusion/ej2-vue-kanban';
import { extend } from '@syncfusion/ej2-base';
import { kanbanData } from './datasource.js';
kanbanData = extend([], kanbanData, null, true);
const cardSettings = {
contentField: "Summary",
headerField: "Id"
};
const swimlaneSettings = {
keyField: 'Assignee',
allowDragAndDrop: true
};
</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-layouts/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-kanban/styles/material.css';
</style>
<template>
<div id="app">
<ejs-kanban id="kanban" keyField="Status" :dataSource="kanbanData"
:cardSettings="cardSettings" :swimlaneSettings="swimlaneSettings">
<e-columns>
<e-column headerText="To Do" keyField="Open"></e-column>
<e-column headerText="In Progress" keyField="InProgress"></e-column>
<e-column headerText="Testing" keyField="Testing"></e-column>
<e-column headerText="Done" keyField="Close"></e-column>
</e-columns>
</ejs-kanban>
</div>
</template>
<script>
import { KanbanComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-vue-kanban';
import { extend } from '@syncfusion/ej2-base';
import { kanbanData } from './datasource.js';
export default {
name: "App",
components: {
"ejs-kanban":KanbanComponent,
"e-columns":ColumnsDirective,
"e-column":ColumnDirective
},
data: function() {
return {
kanbanData: extend([], kanbanData, null, true),
cardSettings: {
contentField: "Summary",
headerField: "Id",
},
swimlaneSettings: {
keyField: 'Assignee',
allowDragAndDrop: true
}
};
},
}
</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-layouts/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-kanban/styles/material.css';
</style>
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.
<template>
<div id="app">
<div class="container-fluid">
<div class="row">
<div class="col-sm-6">
<h4>Kanban A</h4>
<ejs-kanban id="kanbanA" ref="kanbanObjA" keyField="Status" :dataSource="kanbanData"
:cardSettings="cardSettings" :externalDropId='externalKanbanADropId' :dragStop="kanbanDragStopA">
<e-columns>
<e-column headerText="To Do" keyField="Open"></e-column>
<e-column headerText="Done" keyField="Close"></e-column>
</e-columns>
</ejs-kanban>
</div>
<div class="col-sm-6">
<h4>Kanban B</h4>
<ejs-kanban id="kanbanB" ref="kanbanObjB" keyField="Status" :dataSource="kanbanData"
:cardSettings="cardSettings" :externalDropId='externalKanbanBDropId' :dragStop="kanbanDragStopB">
<e-columns>
<e-column headerText="To Do" keyField="Open"></e-column>
<e-column headerText="Done" keyField="Close"></e-column>
</e-columns>
</ejs-kanban>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { KanbanComponent as EjsKanban, ColumnDirective as EColumn, ColumnsDirective as EColumns } from '@syncfusion/ej2-vue-kanban';
import { extend, closest } from '@syncfusion/ej2-base';
import { kanbanData } from './datasource.js';
import {ref} from 'vue';
const kanbanObjA = ref(null);
const kanbanObjB = ref(null);
const cardSettings = {
contentField: "Summary",
headerField: "Id"
};
const externalKanbanADropId = ['#kanbanB'];
const externalKanbanBDropId = ['#kanbanA'];
const kanbanDragStopA = function (args) {
let kanbanBElement = closest(args.event.target, '#kanbanB');
let kanbanObjA = kanbanObjA.value.ej2Instances;
let kanbanObjB = kanbanObjB.value.ej2Instances;
if (kanbanBElement) {
kanbanObjA.deleteCard(args.data);
args.data.forEach((card, i) => {
const index = kanbanObjB.kanbanData.findIndex((colData) =>
colData[kanbanObjB.cardSettings.headerField] === card[kanbanObjB.cardSettings.headerField]);
if (index !== -1) {
card[kanbanObjB.cardSettings.headerField] = Math.max(...kanbanObjB.kanbanData.map(
(obj) => parseInt(obj[kanbanObjB.cardSettings.headerField], 10))) + ++i;
}
});
kanbanObjB.addCard(args.data, args.dropIndex);
args.cancel = true;
}
};
const kanbanDragStopB = function (args) {
let kanbanAElement = closest(args.event.target, '#kanbanA');
let kanbanObjA = kanbanObjA.value.ej2Instances;
let kanbanObjB = kanbanObjB.value.ej2Instances;
if (kanbanAElement) {
kanbanObjB.deleteCard(args.data);
args.data.forEach((card, i) => {
const index = kanbanObjA.kanbanData.findIndex((colData) =>
colData[kanbanObjA.cardSettings.headerField] === card[kanbanObjA.cardSettings.headerField]);
if (index !== -1) {
card[kanbanObjA.cardSettings.headerField] = Math.max(...kanbanObjA.kanbanData.map(
(obj) => parseInt(obj[kanbanObjA.cardSettings.headerField], 10))) + ++i;
}
});
kanbanObjA.addCard(args.data, args.dropIndex);
args.cancel = true;
}
};
</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-layouts/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-kanban/styles/material.css';
.row {
display: flex;
}
</style>
<template>
<div id="app">
<div class="container-fluid">
<div class="row">
<div class="col-sm-6">
<h4>Kanban A</h4>
<ejs-kanban id="kanbanA" ref="kanbanObjA" keyField="Status" :dataSource="kanbanData"
:cardSettings="cardSettings" :externalDropId='externalKanbanADropId' :dragStop="kanbanDragStopA">
<e-columns>
<e-column headerText="To Do" keyField="Open"></e-column>
<e-column headerText="Done" keyField="Close"></e-column>
</e-columns>
</ejs-kanban>
</div>
<div class="col-sm-6">
<h4>Kanban B</h4>
<ejs-kanban id="kanbanB" ref="kanbanObjB" keyField="Status" :dataSource="kanbanData"
:cardSettings="cardSettings" :externalDropId='externalKanbanBDropId' :dragStop="kanbanDragStopB">
<e-columns>
<e-column headerText="To Do" keyField="Open"></e-column>
<e-column headerText="Done" keyField="Close"></e-column>
</e-columns>
</ejs-kanban>
</div>
</div>
</div>
</div>
</template>
<script>
import { KanbanComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-vue-kanban';
import { extend, closest } from '@syncfusion/ej2-base';
import { kanbanData } from './datasource.js';
export default {
name: "App",
components: {
"ejs-kanban":KanbanComponent,
"e-columns":ColumnsDirective,
"e-column":ColumnDirective
},
data: function() {
return {
kanbanData: extend([], kanbanData, null, true),
cardSettings: {
contentField: "Summary",
headerField: "Id"
},
externalKanbanADropId: ['#kanbanB'],
externalKanbanBDropId: ['#kanbanA']
};
},
methods: {
kanbanDragStopA: function (args) {
let kanbanBElement = closest(args.event.target, '#kanbanB');
let kanbanObjA = this.$refs.kanbanObjA.ej2Instances;
let kanbanObjB = this.$refs.kanbanObjB.ej2Instances;
if (kanbanBElement) {
kanbanObjA.deleteCard(args.data);
args.data.forEach((card, i) => {
const index = kanbanObjB.kanbanData.findIndex((colData) =>
colData[kanbanObjB.cardSettings.headerField] === card[kanbanObjB.cardSettings.headerField]);
if (index !== -1) {
card[kanbanObjB.cardSettings.headerField] = Math.max(...kanbanObjB.kanbanData.map(
(obj) => parseInt(obj[kanbanObjB.cardSettings.headerField], 10))) + ++i;
}
});
kanbanObjB.addCard(args.data, args.dropIndex);
args.cancel = true;
}
},
kanbanDragStopB: function (args) {
let kanbanAElement = closest(args.event.target, '#kanbanA');
let kanbanObjA = this.$refs.kanbanObjA.ej2Instances;
let kanbanObjB = this.$refs.kanbanObjB.ej2Instances;
if (kanbanAElement) {
kanbanObjB.deleteCard(args.data);
args.data.forEach((card, i) => {
const index = kanbanObjA.kanbanData.findIndex((colData) =>
colData[kanbanObjA.cardSettings.headerField] === card[kanbanObjA.cardSettings.headerField]);
if (index !== -1) {
card[kanbanObjA.cardSettings.headerField] = Math.max(...kanbanObjA.kanbanData.map(
(obj) => parseInt(obj[kanbanObjA.cardSettings.headerField], 10))) + ++i;
}
});
kanbanObjA.addCard(args.data, args.dropIndex);
args.cancel = true;
}
}
}
}
</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-layouts/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-kanban/styles/material.css';
.row {
display: flex;
}
</style>
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.
<template>
<div id="app">
<div class="container-fluid">
<div class="row">
<div class="col-sm-6">
<h4>Kanban</h4>
<ejs-kanban id="kanban" ref="kanbanObj" keyField="Status" :dataSource="kanbanData"
:cardSettings="cardSettings" :externalDropId='externalKanbanDropId' :dragStop="kanbanDragStop">
<e-columns>
<e-column headerText="To Do" keyField="Open"></e-column>
<e-column headerText="Done" keyField="Close"></e-column>
</e-columns>
</ejs-kanban>
</div>
<div class="col-sm-6">
<h4>TreeView</h4>
<ejs-treeview id='treeView' ref="treeViewObj" :nodeTemplate="treeTemplate" :fields='treeViewFields' :allowDragAndDrop=true :nodeDragStop="onItemDragStop"></ejs-treeview>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { KanbanComponent as EjsKanban, ColumnsDirective as EColumns, ColumnDirective as EColumn } from '@syncfusion/ej2-vue-kanban';
import { extend, closest } from '@syncfusion/ej2-base';
import { kanbanData, treeViewData } from './datasource.js';
import { TreeViewComponent as EjsTreeview} from "@syncfusion/ej2-vue-navigations";
import { createApp, ref } from "vue";
const app = createApp();
const treeViewObj = ref(null);
const kanbanObj = ref(null);
var treeVue = app.component("tree-template", {
data: () => ({}),
template: '<div id="treelist"><div id="treeviewlist"> - </div></div>'
});
kanbanData = extend([], kanbanData, null, true);
const cardSettings = {
contentField: "Summary",
headerField: "Id"
};
const externalKanbanDropId = ['#treeView'];
const treeViewFields = { dataSource: treeViewData, id: 'Id', text: 'Status' };
const treeTemplate = function(e) {
return { template: treeVue }
}
const kanbanDragStop = function (args) {
let treeViewElement = closest(args.event.target, '#treeView');
let kanbanObj = kanbanObj.value.ej2Instances;
let treeObj = treeViewObj.value.ej2Instances;
if (treeViewElement) {
kanbanObj.deleteCard(args.data);
treeObj.addNodes(args.data);
args.cancel = true;
}
};
const onItemDragStop = function (args) {
let kanbanElement = closest(args.event.target, '#kanban');
let kanbanObj = kanbanObj.value.ej2Instances;
let treeObj = treeViewObj.value.ej2Instances;
if (kanbanElement) {
let treeData =
treeObj.fields.dataSource;
const filteredData =
treeData.filter((item) => item.Id === parseInt(args.draggedNodeData.id, 10));
treeObj.removeNodes([args.draggedNodeData.id]);
kanbanObj.openDialog('Add', filteredData[0]);
args.cancel = true;
}
};
</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-layouts/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-kanban/styles/material.css';
.row {
display: flex;
}
</style>
<template>
<div id="app">
<div class="container-fluid">
<div class="row">
<div class="col-sm-6">
<h4>Kanban</h4>
<ejs-kanban id="kanban" ref="kanbanObj" keyField="Status" :dataSource="kanbanData"
:cardSettings="cardSettings" :externalDropId='externalKanbanDropId' :dragStop="kanbanDragStop">
<e-columns>
<e-column headerText="To Do" keyField="Open"></e-column>
<e-column headerText="Done" keyField="Close"></e-column>
</e-columns>
</ejs-kanban>
</div>
<div class="col-sm-6">
<h4>TreeView</h4>
<ejs-treeview id='treeView' ref="treeViewObj" :nodeTemplate="treeTemplate" :fields='treeViewFields' :allowDragAndDrop=true :nodeDragStop="onItemDragStop"></ejs-treeview>
</div>
</div>
</div>
</div>
</template>
<script>
import { KanbanComponent, ColumnDirective, ColumnsDirective } from '@syncfusion/ej2-vue-kanban';
import { extend, closest } from '@syncfusion/ej2-base';
import { kanbanData, treeViewData } from './datasource.js';
import { TreeViewComponent } from "@syncfusion/ej2-vue-navigations";
import { createApp } from "vue";
const app = createApp();
var treeVue = app.component("tree-template", {
template: '<div id="treelist"><div id="treeviewlist"> - </div></div>',
data() {
return {
data: {}
};
}
});
export default {
name: "App",
components: {
"ejs-kanban":KanbanComponent,
"e-columns":ColumnsDirective,
"e-column":ColumnDirective,
"ejs-treeview":TreeViewComponent
},
data: function() {
return {
kanbanData: extend([], kanbanData, null, true),
cardSettings: {
contentField: "Summary",
headerField: "Id"
},
externalKanbanDropId: ['#treeView'],
treeViewFields: { dataSource: treeViewData, id: 'Id', text: 'Status' },
treeTemplate: function() {
return { template: treeVue }
}
};
},
methods: {
kanbanDragStop: function (args) {
let treeViewElement = closest(args.event.target, '#treeView');
let kanbanObj = this.$refs.kanbanObj.ej2Instances;
let treeObj = this.$refs.treeViewObj.ej2Instances;
if (treeViewElement) {
kanbanObj.deleteCard(args.data);
treeObj.addNodes(args.data);
args.cancel = true;
}
},
onItemDragStop: function (args) {
let kanbanElement = closest(args.event.target, '#kanban');
let kanbanObj = this.$refs.kanbanObj.ej2Instances;
let treeObj = this.$refs.treeViewObj.ej2Instances;
if (kanbanElement) {
let treeData =
treeObj.fields.dataSource;
const filteredData =
treeData.filter((item) => item.Id === parseInt(args.draggedNodeData.id, 10));
treeObj.removeNodes([args.draggedNodeData.id]);
kanbanObj.openDialog('Add', filteredData[0]);
args.cancel = true;
}
}
}
}
</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-layouts/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-kanban/styles/material.css';
.row {
display: flex;
}
</style>
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.
<template>
<div id="app">
<div class="container-fluid">
<div class="row">
<div class="col-sm-6" style="width: 30%">
<h4>Kanban</h4>
<ejs-kanban id="kanban" ref="kanbanObj" keyField="DepartmentName" :dataSource="kanbanData"
:cardSettings="cardSettings" :externalDropId='externalKanbanDropId' :dragStop="kanbanDragStop">
<e-columns>
<e-column headerText="GENERAL" keyField="GENERAL"></e-column>
</e-columns>
</ejs-kanban>
</div>
<div class="col-sm-6" style="width: 70%">
<h4>TreeView</h4>
<ejs-schedule id='schedule' ref="scheduleObj" height="650px" :cssClass='cssClass' :selectedDate='selectedDate' :eventSettings='eventSettings'
:group='group' :currentView='currentView' :resourceHeaderTemplate='resourceHeaderTemplate' :dragStop="onItemDragStop">
<e-views>
<e-view option="TimelineDay"></e-view>
<e-view option="TimelineMonth"></e-view>
</e-views>
<e-resources>
<e-resource field='DepartmentID' title='Department' name='Departments' :dataSource='departmentDataSource'
textField='Text' idField='Id' colorField='Color'>
</e-resource>
<e-resource field='ConsultantID' title='Consultant' name='Consultants' :dataSource='consultantDataSource'
textField='Text' idField='Id' groupIDField='GroupId' colorField='Color'>
</e-resource>
</e-resources>
</ejs-schedule>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { provide, createApp } from "vue";
import { KanbanComponent as EjsKanban, ColumnsDirective as EColumns, ColumnDirective as EColumn } from '@syncfusion/ej2-vue-kanban';
import { extend, closest } from '@syncfusion/ej2-base';
import { kanbanData, scheduleData } from './datasource.js';
import { ScheduleComponent as EjsSchedule, TimelineViews, TimelineMonth, Resize, DragAndDrop, ViewDirective as EView, ViewsDirective as EViews, ResourceDirective as EResource, ResourcesDirective as EResources } from "@syncfusion/ej2-vue-schedule";
const kanbanObj = ref(null);
const scheduleObj = ref(null);
const app = createApp({});
var resourceHeaderVue = app.component("resource-headerTemplate", {
data: () => ({}),
template: '<div className="template-wrap"><div class="specialist-category"><div v-if=getConsultantImageName(data)></div><div class="specialist-name">' +
'</div><div class="specialist-designation"></div></div></div>',
methods: {
getConsultantName: function (data) {
let value = JSON.parse(JSON.stringify(data));
return (value.resourceData) ? value.resourceData[value.resource.textField] : value.resourceName;
},
getConsultantImageName: function (data) {
let value = JSON.parse(JSON.stringify(data));
let resourceName = (value.resourceData) ? value.resourceData[value.resource.textField] : value.resourceName;
if (resourceName === 'GENERAL' || resourceName === 'DENTAL') {
return false;
} else {
return true;
}
},
getConsultantDesignation: function (data) {
let value = JSON.parse(JSON.stringify(data));
var resourceName = value.resourceData[value.resource.textField];
if (resourceName === "GENERAL" || resourceName === "DENTAL") {
return '';
} else {
return value.resourceData.Designation;
}
}
}
});
kanbanData = extend([], kanbanData, null, true);
const cardSettings = {
contentField: "Name",
headerField: "Id"
};
const externalKanbanDropId = ['#schedule'];
const eventSettings = {
dataSource: extend([], scheduleData, null, true),
fields: {
subject: { title: 'Patient Name', name: 'Name' },
startTime: { title: "From", name: "StartTime" },
endTime: { title: "To", name: "EndTime" },
description: { title: 'Reason', name: 'Description' }
},
};
const selectedDate = new Date(2018, 7, 1);
const currentView = 'TimelineDay';
const cssClass = 'schedule-drag-drop';
const group = {
enableCompactView: false,
resources: ['Departments', 'Consultants']
};
const departmentDataSource = [
{ Text: 'GENERAL', Id: 1, Color: '#bbdc00' },
{ Text: 'DENTAL', Id: 2, Color: '#9e5fff' }
];
const consultantDataSource = [
{ 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' }
];
const resourceHeaderTemplate = function () {
return { template: resourceHeaderVue }
};
const kanbanDragStop = function (args) {
let scheduleElement = closest(args.event.target, '#schedule');
let kanbanObj = kanbanObj.value.ej2Instances;
let scheduleObj = scheduleObj.value.ej2Instances;
if (scheduleElement) {
kanbanObj.deleteCard(args.data);
scheduleObj.openEditor(args.data[0], 'Add', true);
args.cancel = true;
}
};
const onItemDragStop = function (args) {
let kanbanElement = closest(args.event.target, '#kanban');
let kanbanObj = kanbanObj.value.ej2Instances;
let scheduleObj = scheduleObj.value.ej2Instances;
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;
}
};
provide('schedule', [TimelineViews, TimelineMonth, Resize, DragAndDrop]);
</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-layouts/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material.css';
@import '../node_modules/@syncfusion/ej2-excel-export/styles/material.css';
@import '../node_modules/@syncfusion/ej2-file-utils/styles/material.css';
@import '../node_modules/@syncfusion/ej2-schedule/styles/material.css';
@import '../node_modules/@syncfusion/ej2-compression/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-kanban/styles/material.css';
.row {
display: flex;
}
</style>
<template>
<div id="app">
<div class="container-fluid">
<div class="row">
<div class="col-sm-6" style="width: 30%">
<h4>Kanban</h4>
<ejs-kanban id="kanban" ref="kanbanObj" keyField="DepartmentName" :dataSource="kanbanData"
:cardSettings="cardSettings" :externalDropId='externalKanbanDropId' :dragStop="kanbanDragStop">
<e-columns>
<e-column headerText="GENERAL" keyField="GENERAL"></e-column>
</e-columns>
</ejs-kanban>
</div>
<div class="col-sm-6" style="width: 70%">
<h4>TreeView</h4>
<ejs-schedule id='schedule' ref="scheduleObj" height="650px" :cssClass='cssClass' :selectedDate='selectedDate' :eventSettings='eventSettings'
:group='group' :currentView='currentView' :resourceHeaderTemplate='resourceHeaderTemplate' :dragStop="onItemDragStop">
<e-views>
<e-view option="TimelineDay"></e-view>
<e-view option="TimelineMonth"></e-view>
</e-views>
<e-resources>
<e-resource field='DepartmentID' title='Department' name='Departments' :dataSource='departmentDataSource'
textField='Text' idField='Id' colorField='Color'>
</e-resource>
<e-resource field='ConsultantID' title='Consultant' name='Consultants' :dataSource='consultantDataSource'
textField='Text' idField='Id' groupIDField='GroupId' colorField='Color'>
</e-resource>
</e-resources>
</ejs-schedule>
</div>
</div>
</div>
</div>
</template>
<script>
import { KanbanComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-vue-kanban';
import { extend, closest } from '@syncfusion/ej2-base';
import { kanbanData, scheduleData } from './datasource.js';
import { ScheduleComponent, TimelineViews, TimelineMonth, Resize, DragAndDrop, ViewDirective, ViewsDirective, ResourceDirective, ResourcesDirective } from "@syncfusion/ej2-vue-schedule";
import {createApp} from 'vue';
const app = createApp({});
var resourceHeaderVue = app.component("resource-headerTemplate", {
data: () => ({}),
template: '<div className="template-wrap"><div class="specialist-category"><div v-if=getConsultantImageName(data)></div><div class="specialist-name">' +
'</div><div class="specialist-designation"></div></div></div>',
methods: {
getConsultantName: function (data) {
let value = JSON.parse(JSON.stringify(data));
return (value.resourceData) ? value.resourceData[value.resource.textField] : value.resourceName;
},
getConsultantImageName: function (data) {
let value = JSON.parse(JSON.stringify(data));
let resourceName = (value.resourceData) ? value.resourceData[value.resource.textField] : value.resourceName;
if (resourceName === 'GENERAL' || resourceName === 'DENTAL') {
return false;
} else {
return true;
}
},
getConsultantDesignation: function (data) {
let value = JSON.parse(JSON.stringify(data));
var resourceName = value.resourceData[value.resource.textField];
if (resourceName === "GENERAL" || resourceName === "DENTAL") {
return '';
} else {
return value.resourceData.Designation;
}
}
}
});
export default {
name: "App",
components: {
"ejs-kanban":KanbanComponent,
"e-columns":ColumnsDirective,
"e-column":ColumnDirective,
"ejs-schedule":ScheduleComponent,
"e-views":ViewsDirective,
"e-view":ViewDirective,
"e-resources":ResourcesDirective,
"e-resource":ResourceDirective
},
data: function() {
return {
kanbanData: extend([], kanbanData, null, true),
cardSettings: {
contentField: "Name",
headerField: "Id"
},
externalKanbanDropId: ['#schedule'],
eventSettings: {
dataSource: extend([], scheduleData, null, true),
fields: {
subject: { title: 'Patient Name', name: 'Name' },
startTime: { title: "From", name: "StartTime" },
endTime: { title: "To", name: "EndTime" },
description: { title: 'Reason', name: 'Description' }
},
},
selectedDate: new Date(2018, 7, 1),
currentView: 'TimelineDay',
cssClass: 'schedule-drag-drop',
group: {
enableCompactView: false,
resources: ['Departments', 'Consultants']
},
departmentDataSource: [
{ Text: 'GENERAL', Id: 1, Color: '#bbdc00' },
{ Text: 'DENTAL', Id: 2, Color: '#9e5fff' }
],
consultantDataSource: [
{ 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' }
],
resourceHeaderTemplate: function () {
return { template: resourceHeaderVue }
}
};
},
methods: {
kanbanDragStop: function (args) {
let scheduleElement = closest(args.event.target, '#schedule');
let kanbanObj = this.$refs.kanbanObj.ej2Instances;
let scheduleObj = this.$refs.scheduleObj.ej2Instances;
if (scheduleElement) {
kanbanObj.deleteCard(args.data);
scheduleObj.openEditor(args.data[0], 'Add', true);
args.cancel = true;
}
},
onItemDragStop: function (args) {
let kanbanElement = closest(args.event.target, '#kanban');
let kanbanObj = this.$refs.kanbanObj.ej2Instances;
let scheduleObj = this.$refs.scheduleObj.ej2Instances;
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;
}
}
},
provide: {
schedule: [TimelineViews, TimelineMonth, Resize, DragAndDrop]
}
}
</script>
<style>
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-layouts/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material.css';
@import '../node_modules/@syncfusion/ej2-excel-export/styles/material.css';
@import '../node_modules/@syncfusion/ej2-file-utils/styles/material.css';
@import '../node_modules/@syncfusion/ej2-schedule/styles/material.css';
@import '../node_modules/@syncfusion/ej2-compression/styles/material.css';
@import '../node_modules/@syncfusion/ej2-vue-kanban/styles/material.css';
.row {
display: flex;
}
</style>