Predecessor Validation
12 Mar 202415 minutes to read
By default, Gantt tasks date values are validated based on predecessor values. You can disable/enable this validation by using the EnablePredecessorValidation property. By default, EnablePredecessorValidation
is true.
@using Syncfusion.Blazor.Gantt
<SfGantt @ref="Gantt" DataSource="@TaskCollection" Height="450px" Width="1000px" ProjectStartDate="ProjectStart" ProjectEndDate="ProjectEnd"
Toolbar="@(new List<string>() { "Add", "Edit", "Update", "Cancel"})" EnablePredecessorValidation="false">
<GanttTaskFields Id="TaskId" Name="TaskName" StartDate="StartDate"
Duration="Duration" Dependency="Predecessor" ParentID="ParentId"></GanttTaskFields>
<GanttEditSettings AllowTaskbarEditing="true" AllowEditing="true" AllowAdding="true"></GanttEditSettings>
</SfGantt>
@code {
public SfGantt<TaskData> Gantt;
private DateTime ProjectStart = new DateTime(2022, 03, 31);
private DateTime ProjectEnd = new DateTime(2022, 07, 06);
private List<TaskData> TaskCollection { get; set; }
protected override void OnInitialized()
{
this.TaskCollection = GetTaskCollection();
}
public class TaskData
{
public int TaskId { get; set; }
public string TaskName { get; set; }
public DateTime StartDate { get; set; }
public string Duration { get; set; }
public string Predecessor { get; set; }
public int Progress { get; set; }
public int? ParentId { get; set; }
}
public static List<TaskData> GetTaskCollection()
{
List<TaskData> Tasks = new List<TaskData>() {
new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05)},
new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Progress = 30, ParentId = 1},
new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "3", Progress = 40, Predecessor = "2fs", ParentId = 1 },
new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "1", Progress = 30, ParentId = 1 },
new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06) },
new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentId = 5 },
new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, Predecessor = "6", ParentId = 5 },
new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "2", Progress = 30, ParentId = 5 }
};
return Tasks;
}
}
Custom validation using TaskbarEditing event
In Gantt, the task relationship link can be broken by editing the start date, end date, and duration value of task. When the task relationship is broken on any edit action, it can be handled in Gantt in the following ways.
Validation mode
When editing the tasks with predecessor links, then the TaskbarEditing event will be triggered. You can validate the editing action within the TaskbarEditing
event using the ValidateMode event argument. The ValidateMode
event argument has the following properties:
Argument | Default value | Description |
---|---|---|
args.ValidateMode.RespectLink | false | In this validation mode, the predecessor links get high priority. For example, in FS type, with this mode enabled, when the successor task is moved before the predecessor task’s end date, the editing will be reverted, and dates will be validated based on the dependency links. |
args.ValidateMode.PreserveLinkWithEditing | true | In this validation mode, the taskbar editing will be considered along with the dependency links. This relationship will be maintained by updating the offset value of predecessors. |
By default, the PreserveLinkWithEditing
validation mode will be enabled, so the predecessors are updated with offset values.
The following code example explains enabling the RespectLink
validation mode while editing the linked tasks in the TaskbarEditing
event.
@using Syncfusion.Blazor.Gantt
<SfGantt DataSource="@TaskCollection" Height="450px" Width="700px">
<GanttTaskFields Id="TaskId" Name="TaskName" StartDate="StartDate" EndDate="EndDate" Duration="Duration" Progress="Progress"
Dependency="Predecessor" ParentID="ParentId"></GanttTaskFields>
<GanttEditSettings AllowTaskbarEditing="true" AllowEditing></GanttEditSettings>
<GanttEvents TValue="TaskData" TaskbarEditing="TaskbarEditing"></GanttEvents>
</SfGantt>
@code {
private List<TaskData> TaskCollection { get; set; }
protected override void OnInitialized()
{
this.TaskCollection = GetTaskCollection();
}
public void TaskbarEditing(TaskbarEditingEventArgs<TaskData> args)
{
if (args.ValidationMode != null)
{
args.ValidationMode.RespectLink = true;
}
}
public class TaskData
{
public int TaskId { get; set; }
public string TaskName { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public string Duration { get; set; }
public int Progress { get; set; }
public string Predecessor { get; set; }
public int? ParentId { get; set; }
}
public static List<TaskData> GetTaskCollection()
{
List<TaskData> Tasks = new List<TaskData>() {
new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21) },
new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 },
new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, Predecessor = "2", ParentId = 1 },
new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 },
new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21) },
new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentId = 5 },
new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, Predecessor = "6", ParentId = 5 },
new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentId = 5 }
};
return Tasks;
}
}
Predecessor offset validation
On taskbar editing, the TaskbarEditing event will be triggered with EnablePredecessorOffsetValidation argument. When EnablePredecessorOffsetValidation
is enabled, the taskbar can be dragged such that it does not violate the predecessor value.
The taskbar can be dragged above the given predecessor offset value and it gets reverted to the minimum predecessor value if dragged below the predecessor offset value.
@using Syncfusion.Blazor.Gantt
<SfGantt @ref="Gantt" DataSource="@TaskCollection" Height="450px" Width="1000px" ProjectStartDate="ProjectStart" ProjectEndDate="ProjectEnd"
Toolbar="@(new List<string>() { "Add", "Edit", "Update", "Cancel"})">
<GanttTaskFields Id="TaskId" Name="TaskName" StartDate="StartDate"
Duration="Duration" Dependency="Predecessor" ParentID="ParentId"></GanttTaskFields>
<GanttEditSettings AllowTaskbarEditing="true" AllowEditing="true" AllowAdding="true"></GanttEditSettings>
<GanttEvents TaskbarEditing="TaskbarEditingHandler" TValue="TaskData"></GanttEvents>
</SfGantt>
@code {
public SfGantt<TaskData> Gantt;
private DateTime ProjectStart = new DateTime(2022, 03, 31);
private DateTime ProjectEnd = new DateTime(2022, 07, 06);
private List<TaskData> TaskCollection { get; set; }
protected override void OnInitialized()
{
this.TaskCollection = GetTaskCollection();
}
public void TaskbarEditingHandler(TaskbarEditingEventArgs<TaskData> args)
{
args.EnablePredecessorOffsetValidation = true;
}
public class TaskData
{
public int TaskId { get; set; }
public string TaskName { get; set; }
public DateTime StartDate { get; set; }
public string Duration { get; set; }
public string Predecessor { get; set; }
public int Progress { get; set; }
public int? ParentId { get; set; }
}
public static List<TaskData> GetTaskCollection()
{
List<TaskData> Tasks = new List<TaskData>() {
new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 02)},
new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 02), Progress = 30, ParentId = 1},
new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 02), Duration = "3", Progress = 40, Predecessor = "2fs", ParentId = 1 },
new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 02), Duration = "1", Progress = 30, ParentId = 1 },
new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 02) },
new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 04), Duration = "3", Progress = 30, ParentId = 5 },
new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 04), Duration = "3", Progress = 40, Predecessor = "6", ParentId = 5 },
new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 04), Duration = "2", Progress = 30, ParentId = 5 }
};
return Tasks;
}
}
NOTE
When
EnablePredecessorOffsetValidation
is enabled, the predecessor offset will not be updated on dragging the taskbar. You can update the predecessor offset either by cell edit or dialog edit.
Auto-link validation
When the connector lines are drawn between tasks, the task date gets validated based on predecessor values. You can restrict this validation on predecessor drawing using the TaskbarEditing event. You can enable/disable the validation using EnablePredecessorValidation event argument. By default, EnablePredecessorValidation
is true.
In the below code example, the connector line which is connected from task id 2 to task id 3 is rendered at load time. Hence validation happens. Whereas, the connector line from task id 6 to task id 7 is drawn dynamically and validation is restricted here by disabling the EnablePredecessorValidation
property.
@using Syncfusion.Blazor.Gantt
<SfGantt @ref="Gantt" DataSource="@TaskCollection" Height="450px" Width="1000px" Toolbar="@(new List<string>() { "Add", "Edit", "Update", "Cancel"})">
<GanttTaskFields Id="TaskId" Name="TaskName" StartDate="StartDate"
Duration="Duration" Dependency="Predecessor" ParentID="ParentId"></GanttTaskFields>
<GanttEditSettings AllowTaskbarEditing="true" AllowEditing="true" AllowAdding="true"></GanttEditSettings>
<GanttEvents TaskbarEditing="TaskbarEditingHandler" TValue="TaskData"></GanttEvents>
</SfGantt>
@code {
public SfGantt<TaskData> Gantt;
private DateTime ProjectStart = new DateTime(2022, 3, 24);
private DateTime ProjectEnd = new DateTime(2022, 7, 6);
private List<TaskData> TaskCollection { get; set; }
protected override void OnInitialized()
{
this.TaskCollection = GetTaskCollection();
}
public void TaskbarEditingHandler(TaskbarEditingEventArgs<TaskData> args)
{
args.EnablePredecessorValidation = true;
}
public class TaskData
{
public int TaskId { get; set; }
public string TaskName { get; set; }
public DateTime StartDate { get; set; }
public string Duration { get; set; }
public string Predecessor { get; set; }
public int Progress { get; set; }
public int? ParentId { get; set; }
}
public static List<TaskData> GetTaskCollection()
{
List<TaskData> Tasks = new List<TaskData>() {
new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 02)},
new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 02), Progress = 30, ParentId = 1},
new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 02), Duration = "3", Progress = 40, Predecessor = "2fs", ParentId = 1 },
new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 02), Duration = "1", Progress = 30, ParentId = 1 },
new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 02) },
new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 04), Duration = "3", Progress = 30, ParentId = 5 },
new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 04), Duration = "3", Progress = 40, ParentId = 5 },
new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 04), Duration = "2", Progress = 30, ParentId = 5 }
};
return Tasks;
}
}
NOTE
EnablePredecessorValidation API is used to enable/disable validation based on predecessor values both on load time and on edit actions like cell editing, dialog editing, and on predecessor drawing. Whereas, EnablePredecessorValidation event argument is used to enable/disable validation only on predecessor drawing.