diff --git a/docs/guides/dnd.md b/docs/guides/dnd.md
index c06bec7e..9b15666a 100644
--- a/docs/guides/dnd.md
+++ b/docs/guides/dnd.md
@@ -5,20 +5,17 @@ sidebar_label: "Dragging Tasks within the Timeline"
# Dragging Tasks within the Timeline
-Dragging allows users to quickly change the start (end) dates of the tasks, their duration.
-
-
+Dragging allows users to quickly change the start (end) dates of the tasks, their duration.
By default, the drag-and-drop is enabled and the user can drag a task along its row in the timeline.
To customize the drag-and-drop behavior, use the following events:
- [onBeforeTaskDrag](api/event/onbeforetaskdrag.md) - to deny dragging of specific tasks
-- [onTaskDrag](api/event/ontaskdrag.md) - to limit the area for dragging or to provide some other logic when the user drags a task
+- [onTaskDrag](api/event/ontaskdrag.md) - to limit the area for dragging or to provide some other logic when the user drags a task
- [onAfterTaskDrag](api/event/onaftertaskdrag.md) - to postprocess tasks after they have been dragged to a new place
Let's consider typical cases when the default drag behavior needs customization:
-
1. [Denying dragging specific tasks](#denying-dragging-of-specific-tasks).
2. [Denying dragging tasks out of specific dates](#denying-dragging-tasks-out-of-specific-dates).
3. [Dragging children together with the parent](#dragging-children-together-with-the-parent).
@@ -26,30 +23,28 @@ Let's consider typical cases when the default drag behavior needs customization:
5. [Setting minimal task duration](#setting-minimal-task-duration).
6. [Autoscroll during tasks' dragging](#autoscrollduringtasksdragging).
-
## Denying dragging of specific tasks
To deny dragging of specific tasks, use the [onBeforeTaskDrag](api/event/onbeforetaskdrag.md) event:
~~~js
-gantt.attachEvent("onBeforeTaskDrag", function(id, mode, e){
- if(gantt.getGlobalTaskIndex(id)%2==0){
- return false; //denies dragging if the global task index is odd
+gantt.attachEvent("onBeforeTaskDrag", (taskId, dragMode, event) => {
+ if (gantt.getGlobalTaskIndex(taskId) % 2 === 0) {
+ return false; // denies dragging if the global task index is even
}
- return true; //allows dragging if the global task index is even
+ return true; // allows dragging if the global task index is odd
});
~~~
-
## Denying dragging tasks out of specific dates
-To deny dragging tasks out of specific dates, use the [onTaskDrag](api/event/ontaskdrag.md) event.
+To deny dragging tasks out of specific dates, use the [onTaskDrag](api/event/ontaskdrag.md) event.
The onTaskDrag event:
- Fires each time the user makes a drag movement with the mouse in the timeline area: moves, resizes a task or changes the task's progress.
- - The type of a drag movement is passed as the 2nd argument - mode.
+ - The type of a drag movement is passed as the 2nd argument - mode.
- All available values of the drag movement's type are stored in the [drag_mode](api/config/drag_mode.md) property.
@@ -59,79 +54,87 @@ To deny dragging tasks out of specific dates, use the [onTaskDrag](api/event/ont
The user makes a move.
dhtmlxGantt recalculates the task's date according to the new position.
dhtmlxGantt fires the [onTaskDrag](api/event/ontaskdrag.md) event.
- dhtmlxGantt re-renders the task in the Gantt chart.
As the [](api/event/ontaskdrag.md) event fires after dhtmlxGantt makes recalculation,
+ dhtmlxGantt re-renders the task in the Gantt chart.
As the [onTaskDrag](api/event/ontaskdrag.md) event fires after dhtmlxGantt makes recalculation,
you can specify any custom values for the dragged task in the event's handler, without being afraid that these values will be overwritten. As a result, the task will be rendered in the desired position.
-Let's assume that you want to forbid users to drag tasks out of the **"31 March, 2020 - 11 April, 2020"** interval.
+Let's assume that you want to forbid users to drag tasks out of the **"31 March, 2028 - 11 April, 2028"** interval.

Then, you can use the code as in:
-[Denying dragging tasks out of interval - [31.03.2020, 11.04.2020]](Denying dragging tasks out of interval - [31.03.2020, 11.04.2020])
~~~js
-var leftLimit = new Date(2020, 2 ,31), rightLimit = new Date(2020, 3 ,12);
-
-gantt.attachEvent("onTaskDrag", function(id, mode, task, original){
- var modes = gantt.config.drag_mode;
- if(mode == modes.move || mode == modes.resize){
-
- var diff = original.duration*(1000*60*60*24);
-
- if(+task.end_date > +rightLimit){
+const leftLimit = new Date(2028, 2, 31);
+const rightLimit = new Date(2028, 3, 12);
+const millisecondsInDay = 24 * 60 * 60 * 1000;
+
+gantt.attachEvent("onTaskDrag", (taskId, dragMode, task, originalTask) => {
+ const dragModes = gantt.config.drag_mode;
+
+ if (dragMode === dragModes.move || dragMode === dragModes.resize) {
+ const taskDuration = originalTask.duration * millisecondsInDay;
+
+ if (+task.end_date > +rightLimit) {
task.end_date = new Date(rightLimit);
- if(mode == modes.move)
- task.start_date = new Date(task.end_date - diff);
+ if (dragMode === dragModes.move) {
+ task.start_date = new Date(task.end_date - taskDuration);
}
- if(+task.start_date < +leftLimit){
+ }
+
+ if (+task.start_date < +leftLimit) {
task.start_date = new Date(leftLimit);
- if(mode == modes.move)
- task.end_date = new Date(+task.start_date + diff);
+ if (dragMode === dragModes.move) {
+ task.end_date = new Date(+task.start_date + taskDuration);
+ }
}
}
});
~~~
-
-[Drag parent task with its children](https://docs.dhtmlx.com/gantt/samples/08_api/05_limit_drag_dates.html)
-
-
## Dragging children together with the parent
To allow dragging children when the user is dragging their parent's task, use the [onTaskDrag](api/event/ontaskdrag.md) event (see more on the event [above](guides/dnd.md#denying-dragging-tasks-out-of-specific-dates)):
~~~js
-gantt.attachEvent("onTaskDrag", function(id, mode, task, original){
- var modes = gantt.config.drag_mode;
- if(mode == modes.move){
- var diff = task.start_date - original.start_date;
- gantt.eachTask(function(child){
- child.start_date = new Date(+child.start_date + diff);
- child.end_date = new Date(+child.end_date + diff);
+gantt.attachEvent("onTaskDrag", (taskId, dragMode, task, originalTask) => {
+ const dragModes = gantt.config.drag_mode;
+
+ if (dragMode === dragModes.move) {
+ const dateShift = task.start_date - originalTask.start_date;
+ gantt.eachTask((child) => {
+ child.start_date = new Date(+child.start_date + dateShift);
+ child.end_date = new Date(+child.end_date + dateShift);
gantt.refreshTask(child.id, true);
- },id );
+ }, taskId);
}
});
-//rounds positions of the child items to scale
-gantt.attachEvent("onAfterTaskDrag", function(id, mode, e){
- var modes = gantt.config.drag_mode;
- if(mode == modes.move ){
- var state = gantt.getState();
- gantt.eachTask(function(child){
+
+// rounds positions of the child items to scale
+gantt.attachEvent("onAfterTaskDrag", (taskId, dragMode, event) => {
+ const dragModes = gantt.config.drag_mode;
+
+ if (dragMode === dragModes.move) {
+ const ganttState = gantt.getState();
+ gantt.eachTask((child) => {
child.start_date = gantt.roundDate({
- date:child.start_date,
- unit:state.scale_unit,
- step:state.scale_step
- });
- child.end_date = gantt.calculateEndDate(child.start_date,
- child.duration, gantt.config.duration_unit);
- gantt.updateTask(child.id);
- },id );
+ date: child.start_date,
+ unit: ganttState.scale_unit,
+ step: ganttState.scale_step
+ });
+ child.end_date = gantt.calculateEndDate(
+ child.start_date,
+ child.duration,
+ gantt.config.duration_unit
+ );
+ gantt.updateTask(child.id);
+ }, taskId);
}
});
~~~
+**Related sample**: [Drag parent task with its children](https://docs.dhtmlx.com/gantt/samples/08_api/05_limit_drag_dates.html)
+
## Dragging projects with subtasks {#draggingprojectswithsubtasks}
:::info
@@ -145,16 +148,13 @@ You can enable drag and drop of projects using the [drag_project](api/config/dra
gantt.config.drag_project = true;
~~~
-
-[Draggable projects](https://docs.dhtmlx.com/gantt/samples/08_api/19_draggable_projects.html)
-
+**Related sample**: [Draggable projects](https://docs.dhtmlx.com/gantt/samples/08_api/19_draggable_projects.html)
## Dragging dependent tasks together with independent tasks
There are several ways of implementing tasks moving with their dependent tasks.
You can read about all of them in a separate article [Dragging Tasks Together with Their Dependent Tasks](guides/dragging-dependent-tasks.md).
-
## Setting minimal task duration
Minimal task duration can be specified via the [min_duration](api/config/min_duration.md) setting.
@@ -164,19 +164,19 @@ The option defines the minimum size of the task that can be set during resizing
The value is set in milliseconds:
~~~js
// 1 day
-gantt.config.min_duration = 24*60*60*1000;
+gantt.config.min_duration = 24 * 60 * 60 * 1000;
-//OR
+// OR
// 1 hour
-gantt.config.min_duration = 60*60*1000;
+gantt.config.min_duration = 60 * 60 * 1000;
~~~
## Autoscroll during tasks' dragging {#autoscrollduringtasksdragging}
If you have a large dataset in the Gantt chart, you often need to drag a task to a new distant position or set links between tasks located at a significant distance.
-In this case the **autoscroll** functionality is of great help. It is enabled by default, but you can manage this behavior via
+In this case the **autoscroll** functionality is of great help. It is enabled by default, but you can manage this behavior via
the [autoscroll](api/config/autoscroll.md) configuration option.
~~~js
@@ -189,7 +189,7 @@ Besides, you can adjust the speed of autoscrolling in milliseconds with the help
~~~js
gantt.config.autoscroll = true;
gantt.config.autoscroll_speed = 50;
-
+
gantt.init("gantt_here");
~~~
@@ -201,18 +201,19 @@ If you want to prevent certain tasks from being resized, there are two things yo
In order to do this, you need to use the **task_class** template to add an extra CSS class to the required items so that you could locate them via the selector:
~~~js
-gantt.templates.task_class = function(start, end, task){
- if(task.no_resize) { // no_resize is a custom property used for the demonstration
+gantt.templates.task_class = (startDate, endDate, task) => {
+ if (task.no_resize) { // no_resize is a custom property used for the demonstration
return "no_resize";
}
return "";
+};
~~~
Then, you can hide the resize handles using the following CSS:
~~~css
-.no_resize .gantt_task_drag{
- display: none !important;
+.no_resize .gantt_task_drag {
+ display: none !important;
}
~~~
@@ -220,8 +221,8 @@ Then, you can hide the resize handles using the following CSS:
Returning *false* from the handler will prevent resizing:
~~~js
-gantt.attachEvent("onBeforeTaskDrag", function(id, mode, e){
- if(mode === "resize" && gantt.getTask(id).no_resize){
+gantt.attachEvent("onBeforeTaskDrag", (taskId, dragMode, event) => {
+ if (dragMode === "resize" && gantt.getTask(taskId).no_resize) {
return false;
}
return true;
@@ -235,9 +236,9 @@ The ["resize"](api/event/onbeforetaskdrag.md) mode of drag and drop means that t
If you need to find out which date the user is modifying by the resize, you can use the **gantt.getState().drag_from_start** flag:
~~~js
-gantt.attachEvent("onBeforeTaskDrag", function(id, mode, e){
- if(mode === "resize"){
- if(gantt.getState().drag_from_start === true) {
+gantt.attachEvent("onBeforeTaskDrag", (taskId, dragMode, event) => {
+ if (dragMode === "resize") {
+ if (gantt.getState().drag_from_start === true) {
// changing the start date of a task
} else {
// changing the end date of a task
@@ -251,22 +252,22 @@ gantt.attachEvent("onBeforeTaskDrag", function(id, mode, e){
You can locate resize handles using the following selectors:
-- .gantt_task_drag[data-bind-property="start_date"]
-- .gantt_task_drag[data-bind-property="end_date"]
+- `.gantt_task_drag[data-bind-property="start_date"]`
+- `.gantt_task_drag[data-bind-property="end_date"]`
The following CSS can be used for disabling resizing of start dates of tasks:
~~~css
-.gantt_task_drag[data-bind-property="start_date"]{
- display: none !important;
+.gantt_task_drag[data-bind-property="start_date"] {
+ display: none !important;
}
~~~
Similarly, preventing resizing of the end dates looks like this:
~~~css
-.gantt_task_drag[data-bind-property="end_date"]{
- display: none !important;
+.gantt_task_drag[data-bind-property="end_date"] {
+ display: none !important;
}
~~~
@@ -274,16 +275,14 @@ Another way to do this is use the [onBeforeTaskDrag](api/event/onbeforetaskdrag.
Returning *false* from the handler will prevent resizing:
~~~js
-gantt.attachEvent("onBeforeTaskDrag", function(id, mode, e){
- if(mode === "resize"){
- if(gantt.getState().drag_from_start === true) {
- return false;
+gantt.attachEvent("onBeforeTaskDrag", (taskId, dragMode, event) => {
+ if (dragMode === "resize") {
+ if (gantt.getState().drag_from_start === true) {
+ return false;
} else {
- // changing the end date of a task
+ // changing the end date of a task
}
}
return true;
});
~~~
-
-
diff --git a/static/img/custom_dnd.png b/static/img/custom_dnd.png
index 5c0c3b21..ed72db9f 100644
Binary files a/static/img/custom_dnd.png and b/static/img/custom_dnd.png differ