Skip to content

Commit 99a18ab

Browse files
Merge pull request #34 from mlakatkou/GS-3197
[dev] update Dragging Tasks within the Timeline article
2 parents e8dd0dc + ec26f4c commit 99a18ab

2 files changed

Lines changed: 86 additions & 87 deletions

File tree

docs/guides/dnd.md

Lines changed: 86 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -5,51 +5,46 @@ sidebar_label: "Dragging Tasks within the Timeline"
55

66
# Dragging Tasks within the Timeline
77

8-
Dragging allows users to quickly change the start (end) dates of the tasks, their duration.
9-
10-
8+
Dragging allows users to quickly change the start (end) dates of the tasks, their duration.
119
By default, the drag-and-drop is enabled and the user can drag a task along its row in the timeline.
1210

1311
To customize the drag-and-drop behavior, use the following events:
1412

1513
- [onBeforeTaskDrag](api/event/onbeforetaskdrag.md) - to deny dragging of specific tasks
16-
- [onTaskDrag](api/event/ontaskdrag.md) - to limit the area for dragging or to provide some other logic when the user drags a task
14+
- [onTaskDrag](api/event/ontaskdrag.md) - to limit the area for dragging or to provide some other logic when the user drags a task
1715
- [onAfterTaskDrag](api/event/onaftertaskdrag.md) - to postprocess tasks after they have been dragged to a new place
1816

1917
Let's consider typical cases when the default drag behavior needs customization:
2018

21-
2219
1. [Denying dragging specific tasks](#denying-dragging-of-specific-tasks).
2320
2. [Denying dragging tasks out of specific dates](#denying-dragging-tasks-out-of-specific-dates).
2421
3. [Dragging children together with the parent](#dragging-children-together-with-the-parent).
2522
4. [Dragging projects with subtasks](#draggingprojectswithsubtasks).
2623
5. [Setting minimal task duration](#setting-minimal-task-duration).
2724
6. [Autoscroll during tasks' dragging](#autoscrollduringtasksdragging).
2825

29-
3026
## Denying dragging of specific tasks
3127

3228
To deny dragging of specific tasks, use the [onBeforeTaskDrag](api/event/onbeforetaskdrag.md) event:
3329

3430
~~~js
35-
gantt.attachEvent("onBeforeTaskDrag", function(id, mode, e){
36-
if(gantt.getGlobalTaskIndex(id)%2==0){
37-
return false; //denies dragging if the global task index is odd
31+
gantt.attachEvent("onBeforeTaskDrag", (taskId, dragMode, event) => {
32+
if (gantt.getGlobalTaskIndex(taskId) % 2 === 0) {
33+
return false; // denies dragging if the global task index is even
3834
}
39-
return true; //allows dragging if the global task index is even
35+
return true; // allows dragging if the global task index is odd
4036
});
4137
~~~
4238

43-
4439
## Denying dragging tasks out of specific dates
4540

46-
To deny dragging tasks out of specific dates, use the [onTaskDrag](api/event/ontaskdrag.md) event.
41+
To deny dragging tasks out of specific dates, use the [onTaskDrag](api/event/ontaskdrag.md) event.
4742

4843
<p style="margin-top: 20px; font-weight: bold;"> The onTaskDrag event: </p>
4944

5045
<ul style="margin-top:5px;">
5146
<li>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.</li>
52-
<li>The type of a drag movement is passed as the 2nd argument - <b>mode</b>.</li>
47+
<li>The type of a drag movement is passed as the 2nd argument - <b>mode</b>.</li>
5348
<li>All available values of the drag movement's type are stored in the [drag_mode](api/config/drag_mode.md) property.</li>
5449
</ul>
5550

@@ -59,79 +54,87 @@ To deny dragging tasks out of specific dates, use the [onTaskDrag](api/event/ont
5954
<li>The user makes a move.</li>
6055
<li>dhtmlxGantt recalculates the task's date according to the new position.</li>
6156
<li>dhtmlxGantt fires the [onTaskDrag](api/event/ontaskdrag.md) event.</li>
62-
<li>dhtmlxGantt re-renders the task in the Gantt chart.<br><i>As the [](api/event/ontaskdrag.md) event fires after dhtmlxGantt makes recalculation,
57+
<li>dhtmlxGantt re-renders the task in the Gantt chart.<br><i>As the [onTaskDrag](api/event/ontaskdrag.md) event fires after dhtmlxGantt makes recalculation,
6358
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.</i></li>
6459
</ol>
6560

66-
Let's assume that you want to forbid users to drag tasks out of the **"31 March, 2020 - 11 April, 2020"** interval.
61+
Let's assume that you want to forbid users to drag tasks out of the **"31 March, 2028 - 11 April, 2028"** interval.
6762

6863
![custom_dnd](/img/custom_dnd.png)
6964

7065
Then, you can use the code as in:
7166

72-
[Denying dragging tasks out of interval - [31.03.2020, 11.04.2020]](Denying dragging tasks out of interval - [31.03.2020, 11.04.2020])
7367
~~~js
74-
var leftLimit = new Date(2020, 2 ,31), rightLimit = new Date(2020, 3 ,12);
75-
76-
gantt.attachEvent("onTaskDrag", function(id, mode, task, original){
77-
var modes = gantt.config.drag_mode;
78-
if(mode == modes.move || mode == modes.resize){
79-
80-
var diff = original.duration*(1000*60*60*24);
81-
82-
if(+task.end_date > +rightLimit){
68+
const leftLimit = new Date(2028, 2, 31);
69+
const rightLimit = new Date(2028, 3, 12);
70+
const millisecondsInDay = 24 * 60 * 60 * 1000;
71+
72+
gantt.attachEvent("onTaskDrag", (taskId, dragMode, task, originalTask) => {
73+
const dragModes = gantt.config.drag_mode;
74+
75+
if (dragMode === dragModes.move || dragMode === dragModes.resize) {
76+
const taskDuration = originalTask.duration * millisecondsInDay;
77+
78+
if (+task.end_date > +rightLimit) {
8379
task.end_date = new Date(rightLimit);
84-
if(mode == modes.move)
85-
task.start_date = new Date(task.end_date - diff);
80+
if (dragMode === dragModes.move) {
81+
task.start_date = new Date(task.end_date - taskDuration);
8682
}
87-
if(+task.start_date < +leftLimit){
83+
}
84+
85+
if (+task.start_date < +leftLimit) {
8886
task.start_date = new Date(leftLimit);
89-
if(mode == modes.move)
90-
task.end_date = new Date(+task.start_date + diff);
87+
if (dragMode === dragModes.move) {
88+
task.end_date = new Date(+task.start_date + taskDuration);
89+
}
9190
}
9291
}
9392
});
9493
~~~
9594

96-
97-
[Drag parent task with its children](https://docs.dhtmlx.com/gantt/samples/08_api/05_limit_drag_dates.html)
98-
99-
10095
## Dragging children together with the parent
10196

10297
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)):
10398

10499
~~~js
105-
gantt.attachEvent("onTaskDrag", function(id, mode, task, original){
106-
var modes = gantt.config.drag_mode;
107-
if(mode == modes.move){
108-
var diff = task.start_date - original.start_date;
109-
gantt.eachTask(function(child){
110-
child.start_date = new Date(+child.start_date + diff);
111-
child.end_date = new Date(+child.end_date + diff);
100+
gantt.attachEvent("onTaskDrag", (taskId, dragMode, task, originalTask) => {
101+
const dragModes = gantt.config.drag_mode;
102+
103+
if (dragMode === dragModes.move) {
104+
const dateShift = task.start_date - originalTask.start_date;
105+
gantt.eachTask((child) => {
106+
child.start_date = new Date(+child.start_date + dateShift);
107+
child.end_date = new Date(+child.end_date + dateShift);
112108
gantt.refreshTask(child.id, true);
113-
},id );
109+
}, taskId);
114110
}
115111
});
116-
//rounds positions of the child items to scale
117-
gantt.attachEvent("onAfterTaskDrag", function(id, mode, e){
118-
var modes = gantt.config.drag_mode;
119-
if(mode == modes.move ){
120-
var state = gantt.getState();
121-
gantt.eachTask(function(child){
112+
113+
// rounds positions of the child items to scale
114+
gantt.attachEvent("onAfterTaskDrag", (taskId, dragMode, event) => {
115+
const dragModes = gantt.config.drag_mode;
116+
117+
if (dragMode === dragModes.move) {
118+
const ganttState = gantt.getState();
119+
gantt.eachTask((child) => {
122120
child.start_date = gantt.roundDate({
123-
date:child.start_date,
124-
unit:state.scale_unit,
125-
step:state.scale_step
126-
});
127-
child.end_date = gantt.calculateEndDate(child.start_date,
128-
child.duration, gantt.config.duration_unit);
129-
gantt.updateTask(child.id);
130-
},id );
121+
date: child.start_date,
122+
unit: ganttState.scale_unit,
123+
step: ganttState.scale_step
124+
});
125+
child.end_date = gantt.calculateEndDate(
126+
child.start_date,
127+
child.duration,
128+
gantt.config.duration_unit
129+
);
130+
gantt.updateTask(child.id);
131+
}, taskId);
131132
}
132133
});
133134
~~~
134135

136+
**Related sample**: [Drag parent task with its children](https://docs.dhtmlx.com/gantt/samples/08_api/05_limit_drag_dates.html)
137+
135138
## Dragging projects with subtasks {#draggingprojectswithsubtasks}
136139

137140
:::info
@@ -145,16 +148,13 @@ You can enable drag and drop of projects using the [drag_project](api/config/dra
145148
gantt.config.drag_project = true;
146149
~~~
147150

148-
149-
[Draggable projects](https://docs.dhtmlx.com/gantt/samples/08_api/19_draggable_projects.html)
150-
151+
**Related sample**: [Draggable projects](https://docs.dhtmlx.com/gantt/samples/08_api/19_draggable_projects.html)
151152

152153
## Dragging dependent tasks together with independent tasks
153154

154155
There are several ways of implementing tasks moving with their dependent tasks.
155156
You can read about all of them in a separate article [Dragging Tasks Together with Their Dependent Tasks](guides/dragging-dependent-tasks.md).
156157

157-
158158
## Setting minimal task duration
159159

160160
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
164164
The value is set in milliseconds:
165165
~~~js
166166
// 1 day
167-
gantt.config.min_duration = 24*60*60*1000;
167+
gantt.config.min_duration = 24 * 60 * 60 * 1000;
168168

169-
//OR
169+
// OR
170170

171171
// 1 hour
172-
gantt.config.min_duration = 60*60*1000;
172+
gantt.config.min_duration = 60 * 60 * 1000;
173173
~~~
174174

175175
## Autoscroll during tasks' dragging {#autoscrollduringtasksdragging}
176176

177177
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.
178178

179-
In this case the **autoscroll** functionality is of great help. It is enabled by default, but you can manage this behavior via
179+
In this case the **autoscroll** functionality is of great help. It is enabled by default, but you can manage this behavior via
180180
the [autoscroll](api/config/autoscroll.md) configuration option.
181181

182182
~~~js
@@ -189,7 +189,7 @@ Besides, you can adjust the speed of autoscrolling in milliseconds with the help
189189
~~~js
190190
gantt.config.autoscroll = true;
191191
gantt.config.autoscroll_speed = 50;
192-
192+
193193
gantt.init("gantt_here");
194194
~~~
195195

@@ -201,27 +201,28 @@ If you want to prevent certain tasks from being resized, there are two things yo
201201
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:
202202

203203
~~~js
204-
gantt.templates.task_class = function(start, end, task){
205-
if(task.no_resize) { // no_resize is a custom property used for the demonstration
204+
gantt.templates.task_class = (startDate, endDate, task) => {
205+
if (task.no_resize) { // no_resize is a custom property used for the demonstration
206206
return "no_resize";
207207
}
208208
return "";
209+
};
209210
~~~
210211

211212
Then, you can hide the resize handles using the following CSS:
212213

213214
~~~css
214-
.no_resize .gantt_task_drag{
215-
display: none !important;
215+
.no_resize .gantt_task_drag {
216+
display: none !important;
216217
}
217218
~~~
218219

219220
2. Prevent drag and drop from code using the [onBeforeTaskDrag](api/event/onbeforetaskdrag.md) event.
220221
Returning *false* from the handler will prevent resizing:
221222

222223
~~~js
223-
gantt.attachEvent("onBeforeTaskDrag", function(id, mode, e){
224-
if(mode === "resize" && gantt.getTask(id).no_resize){
224+
gantt.attachEvent("onBeforeTaskDrag", (taskId, dragMode, event) => {
225+
if (dragMode === "resize" && gantt.getTask(taskId).no_resize) {
225226
return false;
226227
}
227228
return true;
@@ -235,9 +236,9 @@ The ["resize"](api/event/onbeforetaskdrag.md) mode of drag and drop means that t
235236
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:
236237

237238
~~~js
238-
gantt.attachEvent("onBeforeTaskDrag", function(id, mode, e){
239-
if(mode === "resize"){
240-
if(gantt.getState().drag_from_start === true) {
239+
gantt.attachEvent("onBeforeTaskDrag", (taskId, dragMode, event) => {
240+
if (dragMode === "resize") {
241+
if (gantt.getState().drag_from_start === true) {
241242
// changing the start date of a task
242243
} else {
243244
// changing the end date of a task
@@ -251,39 +252,37 @@ gantt.attachEvent("onBeforeTaskDrag", function(id, mode, e){
251252

252253
You can locate resize handles using the following selectors:
253254

254-
- .gantt_task_drag[data-bind-property="start_date"]
255-
- .gantt_task_drag[data-bind-property="end_date"]
255+
- `.gantt_task_drag[data-bind-property="start_date"]`
256+
- `.gantt_task_drag[data-bind-property="end_date"]`
256257

257258
The following CSS can be used for disabling resizing of start dates of tasks:
258259

259260
~~~css
260-
.gantt_task_drag[data-bind-property="start_date"]{
261-
display: none !important;
261+
.gantt_task_drag[data-bind-property="start_date"] {
262+
display: none !important;
262263
}
263264
~~~
264265

265266
Similarly, preventing resizing of the end dates looks like this:
266267

267268
~~~css
268-
.gantt_task_drag[data-bind-property="end_date"]{
269-
display: none !important;
269+
.gantt_task_drag[data-bind-property="end_date"] {
270+
display: none !important;
270271
}
271272
~~~
272273

273274
Another way to do this is use the [onBeforeTaskDrag](api/event/onbeforetaskdrag.md) event.
274275
Returning *false* from the handler will prevent resizing:
275276

276277
~~~js
277-
gantt.attachEvent("onBeforeTaskDrag", function(id, mode, e){
278-
if(mode === "resize"){
279-
if(gantt.getState().drag_from_start === true) {
280-
return false;
278+
gantt.attachEvent("onBeforeTaskDrag", (taskId, dragMode, event) => {
279+
if (dragMode === "resize") {
280+
if (gantt.getState().drag_from_start === true) {
281+
return false;
281282
} else {
282-
// changing the end date of a task
283+
// changing the end date of a task
283284
}
284285
}
285286
return true;
286287
});
287288
~~~
288-
289-

static/img/custom_dnd.png

2.09 KB
Loading

0 commit comments

Comments
 (0)