Создание/Выделение задач с помощью DnD

Библиотека dhtmlxGantt предоставляет расширение, которое добавляет расширенные возможности drag-and-drop для управления задачами на временной шкале.

Вкратце, расширение click_drag поддерживает:

Чтобы начать использовать расширение, включите плагин click_drag с помощью метода gantt.plugins.

Чтобы включить расширенный drag-and-drop, настройте опцию click_drag и укажите необходимые свойства из приведённого ниже списка внутри объекта:

gantt.config.click_drag = {
    callback: onDragEnd,
    singleRow: true
};
  • className - (string) добавляет пользовательский CSS-класс к выбранному элементу
  • render - (function) функция, создающая элемент, отображаемый во время перетаскивания. Принимает два параметра:
    • startPoint - (object) - объект со структурой:
      {absolute: {left: number, top: number}, relative: {left: number, top: number} },
      где absolute — координаты относительно верхнего левого угла документа, а relative — относительно верхнего левого угла элемента viewPort
    • endPoint - (object) аналогично startPoint:
      {absolute: {left: number, top: number}, relative: {left: number, top: number} },
      с absolute и relative координатами, как описано выше
  • viewPort - (HTMLElement) элемент, к которому привязываются события и происходит выделение
  • useRequestAnimationFrame - (boolean) указывает, использовать ли requestAnimationFrame при рендеринге
  • callback - (function) вызывается при отпускании кнопки мыши. Принимает 6 параметров:
    • startPoint - (object) с той же структурой, что описано выше
    • endPoint - (object) с той же структурой, что описано выше
    • startDate - (Date) дата, соответствующая началу перетаскивания
    • endDate - (Date) дата, соответствующая окончанию перетаскивания
    • tasksBetweenDates - (array) задачи, попадающие в диапазон между начальной и конечной датой
    • tasksInRows - (array) задачи, выделенные по вертикали между начальной и конечной координатой
  • singleRow - (boolean) если true, выделение ограничено одной строкой, соответствующей высоте задачи

Вы можете привязать следующие события к элементу временной шкалы (по умолчанию gantt.$task_data, который содержит бары задач):

  • onBeforeDrag — срабатывает после нажатия кнопки мыши, но до начала перетаскивания
  • onDrag — вызывается многократно после начала перетаскивания, но до отпускания кнопки мыши
  • onBeforeDragEnd — срабатывает после отпускания кнопки мыши, но до удаления перетаскиваемого элемента и определения выделенных задач
  • onDragEnd — срабатывает после удаления перетаскиваемого элемента и поиска выделенных задач, но до вызова callback-функции (если она задана)
gantt.$task_data.attachEvent("onBeforeDrag", function (coords) {
    gantt.message("onBeforeDrag event");
});

Related sample:  Добавление обработчиков событий для расширения "click_drag"

Имейте в виду, что обработчики событий можно добавлять только к уже существующим элементам. Поэтому добавляйте обработчики после инициализации Gantt, иначе они не будут работать, так как элементы ещё не созданы.

Создание задач с помощью drag-n-drop

Задачи можно создавать прямо на временной шкале: кликните по пустому месту для установки даты начала, затем потяните вправо для задания длительности.

gantt.config.click_drag = {
    callback: onDragEnd,
    singleRow: true
};
 
gantt.init("gantt_here");
gantt.parse(tasks);
function onDragEnd(startPoint,endPoint,startDate,endDate,tasksBetweenDates,tasksInRow){
    if (tasksInRow.length === 1) {
        var parent = tasksInRow[0];
        gantt.createTask({
            text:"Subtask of " + parent.text,
            start_date: gantt.roundDate(startDate),
            end_date: gantt.roundDate(endDate)
        }, parent.id);
    } else if (tasksInRow.length === 0) {
        gantt.createTask({
            text:"New task",
            start_date: gantt.roundDate(startDate),
            end_date: gantt.roundDate(endDate)
        });
    }
}

Related sample:  Create new tasks by Drag and Drop

Установка времени для незапланированных задач

Расширение click_drag также позволяет задавать временные интервалы для незапланированных задач с помощью перетаскивания.

Выделение задач с помощью drag-n-drop

Выделение задач с помощью drag-and-drop поддерживается в нескольких режимах: по датам, по строкам или внутри выделенной области.

gantt.config.multiselect = true;
gantt.config.click_drag = {
    callback: onDragEnd
};
 
gantt.config.autoscroll = true;
gantt.config.autoscroll_speed = 50;
gantt.init("gantt_here");
gantt.parse(tasks);
function onDragEnd(startPoint,endPoint,startDate,endDate,tasksBetweenDates,tasksInRows){
    var mode = document.querySelector("input[name=selectMode]:checked").value;
        switch(mode) {
            case "1":
                unselectTasks();
                tasksBetweenDates.forEach(function(item) {
                    gantt.selectTask(item.id);
                });
            break;
            case "2":
                unselectTasks();
                tasksInRows.forEach(function(item) {
                    gantt.selectTask(item.id);
                });
            break;
            case "3":
                unselectTasks();
                for (var i=0; i<tasksBetweenDates.length; i++) {
                    for (var j=0; j<tasksInRows.length; j++) {
                        if (tasksBetweenDates[i] === tasksInRows[j]) {
                            gantt.selectTask(tasksBetweenDates[i].id);
                        }
                    }
                }
            break;
            return;
        }
}

Related sample:  Select multiple tasks by Drag and Drop

Создание частей разделённых задач

Drag-and-drop также можно использовать для создания частей разделённых задач.

gantt.config.click_drag = {
    callback: onDragEnd,
    singleRow: true
}
 
gantt.init("gantt_here");
gantt.parse(tasks);
function onDragEnd(startPoint,endPoint,startDate,endDate,tasksBetweenDates,tasksInRow){
    if (tasksInRow.length === 1) {
        var currentTask = tasksInRow[0];
        if (currentTask.type === "project") {
            currentTask.render = "split";
            gantt.addTask({
                text:"Subtask of " + currentTask.text,
                start_date: gantt.roundDate(startDate),
                end_date: gantt.roundDate(endDate)
            }, currentTask.id);
        } else {
            var projectName = "new Project " + currentTask.text;
            var newProject = gantt.addTask({
                text: projectName,
                render: "split",
                type: "project",
            }, currentTask.parent);
            gantt.moveTask(
                newProject,
                gantt.getTaskIndex(currentTask.id),
                gantt.getParent(currentTask.id)
            );
            gantt.moveTask(currentTask.id, 0, newProject);
            gantt.calculateTaskLevel(currentTask)
 
            var newTask = gantt.addTask({
                text:"Subtask of " + projectName,
                start_date: gantt.roundDate(startDate),
                end_date: gantt.roundDate(endDate)
            }, newProject);
            gantt.calculateTaskLevel(newTask);
        }
    } else if (tasksInRow.length === 0) {
        gantt.createTask({
            text:"New task",
            start_date: gantt.roundDate(startDate),
            end_date: gantt.roundDate(endDate)
        });
    }
}

Related sample:  Create split tasks by Drag and Drop

К началу