Drag and Drop in Vue Gantt component
11 Jun 202424 minutes to read
Drag and drop
You can dynamically rearrange the rows in the Gantt control by using the allowRowDragAndDrop
property. Using this property, row drag and drop can be enabled or disabled in Gantt. Using this feature, rows can be dropped at above and below as a sibling or child to the existing rows
To use row drag and drop feature, inject the RowDD
and Edit
modules in the provide
section.
<template>
<div>
<ejs-gantt :dataSource="data" :allowRowDragAndDrop='true' :taskFields = "taskFields" :height = "height"></ejs-gantt>
</div>
</template>
<script setup>
import { provide } from "vue";
import { GanttComponent as EjsGantt, RowDD, Edit, Selection } from "@syncfusion/ej2-vue-gantt";
import { ganttData } from "./data-source.js";
const data = ganttData;
const height = '450px';
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
child: 'subtasks'
};
provide('gantt', [ RowDD, Edit, Selection ]);
</script>
<template>
<div>
<ejs-gantt :dataSource="data" :allowRowDragAndDrop='true' :taskFields = "taskFields" :height = "height"></ejs-gantt>
</div>
</template>
<script>
import { GanttComponent, RowDD, Edit, Selection } from "@syncfusion/ej2-vue-gantt";
import { ganttData } from "./data-source.js";
export default {
name: "App",
components: {
"ejs-gantt":GanttComponent
},
data: function() {
return{
data: ganttData,
height: '450px',
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
child: 'subtasks'
}
};
},
provide: {
gantt: [ RowDD, Edit, Selection ]
}
};
</script>
Multiple row drag and drop
Gantt also supports dragging multiple rows at a time and drop them on any rows above, below, or at child positions. In Gantt, you can enable the multiple drag and drop by setting the selectionSettings.type
to Multiple
and you should enable the allowRowDragAndDrop
property.
<template>
<div>
<ejs-gantt :dataSource="data" :allowRowDragAndDrop='true' :selectionSettings="selectionSettings" :taskFields = "taskFields" :height = "height"></ejs-gantt>
</div>
</template>
<script setup>
import { provide } from "vue";
import { GanttComponent as EjsGantt, RowDD, Edit, Selection } from "@syncfusion/ej2-vue-gantt";
import { ganttData } from "./data-source.js";
const data = ganttData;
const height = '450px';
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
child: 'subtasks'
};
const selectionSettings = {
type: 'Multiple'
};
provide('gantt', [ RowDD, Edit, Selection ]);
</script>
<template>
<div>
<ejs-gantt :dataSource="data" :allowRowDragAndDrop='true' :selectionSettings="selectionSettings" :taskFields = "taskFields" :height = "height"></ejs-gantt>
</div>
</template>
<script>
import { GanttComponent, RowDD, Edit, Selection } from "@syncfusion/ej2-vue-gantt";
import { ganttData } from "./data-source.js";
export default {
name: "App",
components: {
"ejs-gantt":GanttComponent
},
data: function() {
return{
data: ganttData,
height: '450px',
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
child: 'subtasks'
},
selectionSettings: {
type: 'Multiple'
}
};
},
provide: {
gantt: [ RowDD, Edit, Selection ]
}
};
</script>
Taskbar drag and drop between rows
The Gantt feature empowers users to efficiently reorganize records by seamlessly moving taskbar and rearranging their positions through a simple drag-and-drop action. Using this feature, rows can be dropped at above and below as a sibling or child to the existing rows.
This mode can be enable by setting the allowTaskbarDragAndDrop property to true
.
To use row drag and drop feature, inject the RowDD
and Edit
module in Gantt.
<template>
<div>
<ejs-gantt ref='gantt' id="GanttContainer" :dataSource="data" :taskFields = "taskFields" :height = "height" :allowRowDragAndDrop="true" :allowTaskbarDragAndDrop="true" :editSettings="editSettings"></ejs-gantt>
</div>
</template>
<script setup>
import { provide } from "vue";
import { GanttComponent as EjsGantt, Edit, RowDD } from "@syncfusion/ej2-vue-gantt";
const data = [
{
TaskID: 1,
TaskName: 'Project Initiation',
StartDate: new Date('04/02/2019'),
EndDate: new Date('04/21/2019'),
isParent:true,
subtasks: [
{ TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 0, Progress: 50,isParent:false },
{ TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, Progress: 70, resources: [2, 3, 5],isParent:false },
{ TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4,Predecessor:"2FS", Progress: 50,isParent:false },
]
},
{
TaskID: 5,
TaskName: 'Project Estimation',
StartDate: new Date('04/02/2019'),
EndDate: new Date('04/21/2019'),
isParent:true,
subtasks: [
{ TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 50, resources: [4],isParent:false },
{ TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 80, resources: [4, 8],isParent:false },
{ TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 0,Predecessor:"6SS", Progress: 70, resources: [12, 5],isParent:false }
]
},
];
const height = '450px';
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
child: 'subtasks'
};
const editSettings = {
allowAdding: true,
allowEditing: true,
allowDeleting: true,
allowTaskbarEditing: true,
showDeleteConfirmDialog: true
}
provide('gantt', [ Edit, RowDD]);
</script>
<template>
<div>
<ejs-gantt ref='gantt' id="GanttContainer" :dataSource="data" :taskFields = "taskFields" :height = "height" :allowRowDragAndDrop="true" :allowTaskbarDragAndDrop="true" :editSettings="editSettings"></ejs-gantt>
</div>
</template>
<script>
import { GanttComponent, Edit, RowDD } from "@syncfusion/ej2-vue-gantt";
export default {
name: "App",
components: {
"ejs-gantt":GanttComponent
},
data: function() {
return{
data: [
{
TaskID: 1,
TaskName: 'Project Initiation',
StartDate: new Date('04/02/2019'),
EndDate: new Date('04/21/2019'),
isParent:true,
subtasks: [
{ TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 0, Progress: 50,isParent:false },
{ TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, Progress: 70, resources: [2, 3, 5],isParent:false },
{ TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4,Predecessor:"2FS", Progress: 50,isParent:false },
]
},
{
TaskID: 5,
TaskName: 'Project Estimation',
StartDate: new Date('04/02/2019'),
EndDate: new Date('04/21/2019'),
isParent:true,
subtasks: [
{ TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 50, resources: [4],isParent:false },
{ TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 80, resources: [4, 8],isParent:false },
{ TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 0,Predecessor:"6SS", Progress: 70, resources: [12, 5],isParent:false }
]
},
],
height: '450px',
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
child: 'subtasks'
},
editSettings : {
allowAdding: true,
allowEditing: true,
allowDeleting: true,
allowTaskbarEditing: true,
showDeleteConfirmDialog: true
}
};
},
provide: {
gantt: [ Edit, RowDD]
}
};
</script>
Drag and drop events
We provide various events to customize the row drag and drop action, the following table explains about the available events and its details.
Event Name | Description |
---|---|
rowDragStartHelper |
Triggers when clicking the drag icon or Gantt row. |
rowDragStart |
Triggers when drag action starts in Gantt. |
rowDrag |
Triggers while dragging the Gantt row. |
rowDrop |
Triggers when a drag row was dropped on the target row. |
Customize row drag and drop action
In Gantt, the rowDragStartHelper
and rowDrop
events are triggered on row drag and drop action. Using this event, you can prevent dragging of particular record, validate the drop position, and cancel the drop action based on the target record and dragged record. The following topics explains about this.
Prevent dragging of particular record
You can prevent drag action of the particular record by setting the cancel
property to true
, which is available in the rowDragStartHelper
event argument based on our requirement. In the following sample, drag action was restricted for first parent record and its child records.
<template>
<div>
<ejs-gantt :dataSource="data" :allowRowDragAndDrop='true' :taskFields = "taskFields" :height = "height" :rowDragStartHelper="rowDragStartHelper"></ejs-gantt>
</div>
</template>
<script setup>
import { provide } from "vue";
import { GanttComponent as EjsGantt, RowDD, Edit, Selection } from "@syncfusion/ej2-vue-gantt";
import { ganttData } from "./data-source.js";
const data = ganttData;
const height = '450px';
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
child: 'subtasks'
};
const rowDragStartHelper = function(args) {
var record = args.data[0] ? args.data[0] : args.data;
var taskId = record.ganttProperties.taskId;
if (taskId <= 4) {
args.cancel = true;
}
};
provide('gantt', [ RowDD, Edit, Selection ]);
</script>
<template>
<div>
<ejs-gantt :dataSource="data" :allowRowDragAndDrop='true' :taskFields = "taskFields" :height = "height" :rowDragStartHelper="rowDragStartHelper"></ejs-gantt>
</div>
</template>
<script>
import { GanttComponent, RowDD, Edit, Selection } from "@syncfusion/ej2-vue-gantt";
import { ganttData } from "./data-source.js";
export default {
name: "App",
components: {
"ejs-gantt":GanttComponent
},
data: function() {
return{
data: ganttData,
height: '450px',
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
child: 'subtasks'
},
rowDragStartHelper: function(args) {
var record = args.data[0] ? args.data[0] : args.data;
var taskId = record.ganttProperties.taskId;
if (taskId <= 4) {
args.cancel = true;
}
}
};
},
provide: {
gantt: [ RowDD, Edit, Selection ]
}
};
</script>
Validating drop position
You can prevent drop action based on the drop position and target record, by this, you can prevent dropping particular task on a specific task or specific position. This can be achieved by setting the cancel
property to true
, which is available in the rowDrop
event argument.
In the following sample, we have prevented the drop action based on the position. In this sample, you cannot drop row as child in any of the available rows.
<template>
<div>
<ejs-gantt :dataSource="data" :allowRowDragAndDrop='true' :taskFields = "taskFields" :height = "height" :rowDrop="rowDrop"></ejs-gantt>
</div>
</template>
<script setup>
import { provide } from "vue";
import { GanttComponent as EjsGantt, RowDD, Edit, Selection } from "@syncfusion/ej2-vue-gantt";
import { ganttData } from "./data-source.js";
const data = ganttData;
const height = '450px';
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
child: 'subtasks'
};
const rowDrop = function(args) {
if (args.dropPosition == "middleSegment") {
args.cancel = true;
}
};
provide('gantt', [ RowDD, Edit, Selection ]);
</script>
<template>
<div>
<ejs-gantt :dataSource="data" :allowRowDragAndDrop='true' :taskFields = "taskFields" :height = "height" :rowDrop="rowDrop"></ejs-gantt>
</div>
</template>
<script>
import { GanttComponent, RowDD, Edit, Selection } from "@syncfusion/ej2-vue-gantt";
import { ganttData } from "./data-source.js";
export default {
name: "App",
components: {
"ejs-gantt":GanttComponent
},
data: function() {
return{
data: ganttData,
height: '450px',
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
child: 'subtasks'
},
rowDrop: function(args) {
if (args.dropPosition == "middleSegment") {
args.cancel = true;
}
}
};
},
provide: {
gantt: [ RowDD, Edit, Selection ]
}
};
</script>
Prevent reordering a row as child to another row
You can prevent the default behavior of dropping rows as children to the target by setting the cancel
property to true
in rowDrop event argument. You can also change the drop position after cancelling using reorderRows method.
In the below example drop action is cancelled and dropped above to target row.
<template>
<div>
<ejs-gantt ref='gantt' :dataSource="data" :allowRowDragAndDrop='true' :taskFields = "taskFields" :height = "height" :rowDrop="rowDrop"></ejs-gantt>
</div>
</template>
<script setup>
import { provide } from "vue";
import { GanttComponent as EjsGantt, RowDD, Edit, Selection } from "@syncfusion/ej2-vue-gantt";
import { ganttData } from "./data-source.js";
const data = ganttData;
const height = '450px';
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
child: 'subtasks'
};
const rowDrop = function(args) {
if (args.dropPosition == "middleSegment") {
args.cancel = true;
}
};
provide('gantt', [ RowDD, Edit, Selection ]);
</script>
<template>
<div>
<ejs-gantt ref='gantt' :dataSource="data" :allowRowDragAndDrop='true' :taskFields = "taskFields" :height = "height" :rowDrop="rowDrop"></ejs-gantt>
</div>
</template>
<script>
import { GanttComponent, RowDD, Edit, Selection } from "@syncfusion/ej2-vue-gantt";
import { ganttData } from "./data-source.js";
export default {
name: "App",
components: {
"ejs-gantt":GanttComponent
},
data: function() {
return{
data: ganttData,
height: '450px',
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
child: 'subtasks'
}
};
},
provide: {
gantt: [ RowDD, Edit, Selection ]
},
methods: {
rowDrop: function(args) {
if (args.dropPosition == 'middleSegment') {
args.cancel = true;
this.$refs.gantt.reorderRows([args.fromIndex], args.dropIndex, 'above');
}
}
}
};
</script>
Perform row drag and drop action programmatically
Gantt provides option to perform row drag and drop action programmatically by using the reorderRows
method, this method can be used for any external actions like button click.
The following arguments are used to specify the positions to drag and drop a row:
-
fromIndexes
: Index value of source(dragging) row. -
toIndex
: Value of target index. -
position
: Drop positions such as above, below, or child.
The following code example shows how to drag and drop a row on button click action.
<template>
<div>
<ejs-button id="dynamicDrag" cssClass="e-info" v-on:click="dynamicDrag">Drop records as child</ejs-button>
<br><br>
<ejs-gantt ref='gantt' :dataSource="data" :allowRowDragAndDrop='true' :taskFields = "taskFields" :height = "height"></ejs-gantt>
</div>
</template>
<script setup>
import { provide, ref } from "vue";
import { GanttComponent as EjsGantt, RowDD, Edit, Selection } from "@syncfusion/ej2-vue-gantt";
import { ButtonComponent as EjsButton } from "@syncfusion/ej2-vue-buttons";
import { ganttData } from "./data-source.js";
const gantt = ref(null);
const data = ganttData;
const height = '450px';
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
child: 'subtasks'
};
const dynamicDrag = function(e) {
gantt.value.reorderRows([1,2,3], 4, 'child');
};
provide('gantt', [ RowDD, Edit, Selection ]);
</script>
<template>
<div>
<ejs-button id="dynamicDrag" cssClass="e-info" v-on:click="dynamicDrag">Drop records as child</ejs-button>
<br><br>
<ejs-gantt ref='gantt' :dataSource="data" :allowRowDragAndDrop='true' :taskFields = "taskFields" :height = "height"></ejs-gantt>
</div>
</template>
<script>
import { GanttComponent, RowDD, Edit, Selection } from "@syncfusion/ej2-vue-gantt";
import { ButtonComponent } from "@syncfusion/ej2-vue-buttons";
import { ganttData } from "./data-source.js";
export default {
name: "App",
components: {
"ejs-button":ButtonComponent,
"ejs-gantt":GanttComponent
},
data: function() {
return{
data: ganttData,
height: '450px',
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
child: 'subtasks'
}
};
},
provide: {
gantt: [ RowDD, Edit, Selection ]
},
methods: {
dynamicDrag: function(e) {
this.$refs.gantt.reorderRows([1,2,3], 4, 'child');
}
}
};
</script>