Hi everyone. I am getting an issue that happens only every now and then. I have tried to recreate the issue in the a snippet, but I am unable to do it. SO I figured if I provided all my JavaScript somebody might be able to see something. Note I am using an ASP.NET MVC framework, and everything is working fine, other than sometimes getting multiple of the same task getting written to the database, and then shown in the UI after it reloads.
Also note - this code that I have provided is in the same order as it is in my custom JavaScript file. I don’t know if that is causing an issue with the placement of the init values.
If someone could take a glance at this it would be greatly appreciated. Again - I have tried to recreate it in snippets, and I’m not sure what’s causing it.
//Add task button We use this in our ASP controller to grab the correct id
gantt.attachEvent("onTaskCreated",
function(task) {
task.id = @int.MaxValue;
return true;
});
//This code looks kind of ugly, but the developer before me did not utilize the templates
// So i made a janky function to change the color depending if tasks are ‘feasible’ or not.
[code]
gantt.attachEvent(“onBeforeTaskDisplay”, // before the task is rendered in the chart
function(id) {
//debugger;
var t = gantt.getTask(id);
var e = t.enabled;
//Switch statement changes the code dynamically.
switch (e) {
case ("true"):
t.textColor = "";
$(".gantt_task_content").css('color', 'white');
$( "#feasibleId" ).hide();
break;
case ("true" && (t.workflowcomplete ===false || t.workflowitemcomplete ===false)):
t.textColor = "";
$(".gantt_task_content").css('color', 'white');
$( "#feasibleId" ).hide();
break;
case ("false"):
t.textColor = "red";
$(".gantt_task_content").css('color', 'red');
$( "#feasibleId" ).show();
break;
default:
t.textColor = "black";
break;
}[/code]
//This is after you click the ‘save’ button on a new task.
[code]
gantt.attachEvent(“onAfterTaskAdd”,
function(id, task) {
gantt.getTask(task.id);
task.type = gantt.config.types.task; //task = 1 , project = 2
task.workflowcomplete = false;
//Init some custom fields that I use in my controller on the ASP.NET side.
getRootParentId(task);
task.updatenewtask = true;
});[/code]
//This is the function I use to call my custom update parents and update children code
gantt.attachEvent("onAfterTaskUpdate",
function(id, task) {
if (!task.parent || task.parent <= 0) {
$('#projectname_' + id).html(task.text);
if (gantt.hasChild(task.id)) { // update all children feasibility
gantt_updatechildrenfeasibility(task.id, task.enabled);
}
}
gantt_updateparents(task, 'update');
});
//My init code is below
[code] if (!@(editor.ToString().ToLower())) {
gantt.config.readonly = true;
}
gantt.config.auto_scheduling = true; // when updating a task, linked tasks and parent tasks will also be updated
gantt.config.auto_scheduling_strict = true; // tasks are always scheduled on the earliest possible date based on their links
gantt.config.auto_scheduling_initial = true; // perform autoscheduling when data is first loaded
gantt.config.fit_tasks = true; // try to fit all tasks in the gantt chart without scrolling
gantt.config.lightbox_additional_height = 90; // for some reason the edit popup was not tall enough so we have to add a few pixels
gantt.config.scale_unit = ‘month’; // default scale
gantt.config.date_scale = “%M, %Y”; // default scale format
gantt.config.xml_date = “%Y-%m-%d %H:%i:%s”; // set the date format expected from data passed to gantt chart
gantt.config.types = { ‘task’: @((int) GanttTaskTypes.Task), ‘project’: @((int) GanttTaskTypes.Project), ‘milestone’: @((int) GanttTaskTypes.Milestone) } // custom item types so we can use an enum
$('#@ganttdivid').hide(); // hide gantt chart until data is loaded
$('#@loadingid').show();
gantt.init("@ganttdivid");
isGanttInitialized = true; // only one gantt chart can be used at a time
gantt.load('@Url.Action("GetWorkflowGantt", "Workflow", new { area = "", roottaskid = Model.RootNodeId})', 'json', function() {
$('#@loadingid').hide();
$('#@ganttdivid').show(); // show gantt chart now that data is loaded
gantt.render();
});
var dp = new gantt.dataProcessor('@Url.Action("BaseUrl", "Workflow", new { area = ""})');
dp.init(gantt);
dp.setTransactionMode("REST", false);
});[/code]
The last three functions are my custom update parent and update children code.
//Update children feasibility
[code] function gantt_updatechildrenfeasibility(id, feasible) {
//debugger;
if (gantt.hasChild(id)) {
var children = gantt.getChildren(id);
children.forEach(function(cid) {
var child = gantt.getTask(cid);
child.enabled = feasible;
gantt.refreshTask(child.id);
gantt_updatechildrenfeasibility(child.id, feasible);
});
}
}[/code]
// Update parent code
[code]function gantt_updateparents(task, method) {
//debugger;
if (!task.parent || task.parent <= 0) {
var pctdone = Math.round(task.progress * 100);
$(’#taskpctdonediv_’ + task.id)
.css(‘background-color’, ‘hsl(’ + pctdone + ‘, 100%, 45%)’)
.css(‘width’, pctdone + ‘%’)
.html(pctdone + ‘%’); // update percentage in left menu of Index.cshtml
return;
}
var p = gantt.getTask(gantt.getParent(task.id));
var children = gantt.getChildren(p.id);
if (!children || children.length <= 0 || (children.length == 1 && method == 'delete')) { // no children
p.type = gantt.config.types.task; // make item a task
}
else { // has at least one child
p.type = gantt.config.types.project; // make item a project
}
var durationcompleted = 0;
var totalduration = 0;
$.each(gantt.getChildren(p.id),
function(index, t) {
if (!(method == 'delete' && t == task.id)) {
var child = gantt.getTask(t);
if (!!child.duration) {
totalduration += child.duration;
if (!!child.progress) {
durationcompleted += child.duration * child.progress;
}
}
}
});
p.progress = totalduration > 0 ? durationcompleted / totalduration : 0;
// update site project completion status
if (p.$level == 0) {
if (p.progress >= 1 && !p.workflowcomplete) {
p.workflowcomplete = true;
gantt_updateprojectcompletionstatus(p, true);
} else if (p.progress < 1 && p.workflowcomplete) {
p.workflowcomplete = false;
gantt_updateprojectcompletionstatus(p, false);
}
}
gantt.updateTask(p.id); // update parent task
gantt.render(); // refresh gantt chart
}[/code]
// **** End update parents ****
// this is necessary to show all tasks are completed in the UI
[code]function gantt_updateprojectcompletionstatus(task, complete) {
var children = gantt.getChildren(task.id);
$.each(children,
function(index, t) {
var child = gantt.getTask(t);
if (!child.workflowcomplete && complete) {
child.workflowcomplete = true;
gantt_updateprojectcompletionstatus(child, complete);
} else if (child.workflowcomplete && !complete) {
child.workflowcomplete = false;
gantt_updateprojectcompletionstatus(child, complete);
}
});
};[/code]