Access Model Fields in the Gantt Timeline Tooltip
Environment
Product | Gantt for Blazor |
Description
I want to access and display model fields in the Gantt Timeline Tooltip. In the TooltipTemplate
I can access some of the model fields, which match the properties of a Gantt Tree item. But how to access and show all model fields?
Solution
You have two options to display the other fields form you model in the Tooltip:
Get the Gantt Data Item From Context Properties
This solution relies on finding the task item in your data based on the properties that the TooltipTemplateContext
provides. The approach is applicable only if all items in your data have unique values for these properties and the task titles are not localized.
- Cast the
TooltipTemplate
context
toTooltipTemplateContext
. - Use the available properties of the
TooltipTemplateContext
to find the data item in the Gantt data collection. The example below uses theTitle
property. - Display the desired fields of the model instance in the
TooltipTemplate
.
<TelerikGantt Data="@Data"
Width="900px"
Height="600px"
IdField="Id"
ParentIdField="ParentId">
<TooltipTemplate>
@{
FlatModel model = GetModel(((TooltipTemplateContext)context).Title);
}
@model.CustomField
<br/>
@model.SomeIntField
</TooltipTemplate>
<GanttColumns>
<GanttColumn Field="Title"
Expandable="true"
Width="160px"
Title="Task Title">
</GanttColumn>
<GanttColumn Field="PercentComplete"
Title="Status"
Width="60px"
DisplayFormat="{0:P}">
</GanttColumn>
<GanttColumn Field="Start"
Width="100px"
DisplayFormat="{0:d}">
</GanttColumn>
<GanttColumn Field="End"
Width="100px"
DisplayFormat="{0:d}">
</GanttColumn>
</GanttColumns>
<GanttViews>
<GanttWeekView></GanttWeekView>
</GanttViews>
</TelerikGantt>
@code {
private List<FlatModel> Data { get; set; }
private FlatModel GetModel(string title)
{
return Data.FirstOrDefault(x => x.Title == title);
}
public class FlatModel
{
public int Id { get; set; }
public int? ParentId { get; set; }
public string Title { get; set; }
public double PercentComplete { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public string CustomField { get; set; }
public int SomeIntField {get; set;}
}
public int LastId { get; set; } = 1;
protected override void OnInitialized()
{
Data = new List<FlatModel>();
var random = new Random();
for (int i = 1; i < 6; i++)
{
var newItem = new FlatModel()
{
Id = LastId,
Title = "Task " + i.ToString(),
Start = new DateTime(2021, 7, 5 + i),
End = new DateTime(2021, 7, 11 + i),
PercentComplete = Math.Round(random.NextDouble(), 2),
CustomField = "Details for task " + i,
SomeIntField = i
};
Data.Add(newItem);
var parentId = LastId;
LastId++;
for (int j = 0; j < 5; j++)
{
Data.Add(new FlatModel()
{
Id = LastId,
ParentId = parentId,
Title = " Task " + i + " : " + j.ToString(),
Start = new DateTime(2021, 7, 5 + j),
End = new DateTime(2021, 7, 6 + i + j),
PercentComplete = Math.Round(random.NextDouble(), 2),
CustomField = "Details for task " + i,
SomeIntField = j
});
LastId++;
}
}
base.OnInitialized();
}
}
Use a Separate Tooltip Component
This solution relies on disabling the built-in Tooltip and adding a custom one, so you have full control over its rendering and content.
- Disable the built-in Tooltip by setting the Gantt
ShowTooltip
parameter tofalse
. - Use a
TaskTemplate
to render a uniqueid
attribute to each task. - Add a TelerikTooltip in the
TaskTemplate
. - Set the Tooltip's
TargetSelector
to point to the task wrapper uniqueid
. - Access the model from the
context
of theTaskTemplate
and get the needed properties to display in the Tooltip.
This approach renders a dedicated Tooltip for each task. This makes it useful if you don't have too many tasks - otherwise, you may face performance issues. In this case, either use the above approach or add only one Tooltip instance as shown here.
<TelerikGantt Data="@Data"
Width="900px"
Height="600px"
IdField="Id"
ParentIdField="ParentId"
ShowTooltip="false">
<TaskTemplate Context="taskContext">
<div id="@($"id-{taskContext.Id.ToString()}")">
<div class="task-title">@taskContext.Title</div>
<div class="k-task-complete" style="width:@(taskContext.PercentComplete * 100)%; z-index: -1;"></div>
</div>
<TelerikTooltip TargetSelector="@($"#id-{taskContext.Id.ToString()}")" >
<Template>
@{
@taskContext.CustomField
<br />
@taskContext.SomeIntField
}
</Template>
</TelerikTooltip>
</TaskTemplate>
<GanttColumns>
<GanttColumn Field="Title"
Expandable="true"
Width="160px"
Title="Task Title">
</GanttColumn>
<GanttColumn Field="PercentComplete"
Title="Status"
Width="60px"
DisplayFormat="{0:P}">
</GanttColumn>
<GanttColumn Field="Start"
Width="100px"
DisplayFormat="{0:d}">
</GanttColumn>
<GanttColumn Field="End"
Width="100px"
DisplayFormat="{0:d}">
</GanttColumn>
</GanttColumns>
<GanttViews>
<GanttWeekView></GanttWeekView>
</GanttViews>
</TelerikGantt>
@code {
private List<FlatModel> Data { get; set; }
public class FlatModel
{
public int Id { get; set; }
public int? ParentId { get; set; }
public string Title { get; set; }
public double PercentComplete { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public string CustomField { get; set; }
public int SomeIntField { get; set; }
}
public int LastId { get; set; } = 1;
protected override void OnInitialized()
{
Data = new List<FlatModel>();
var random = new Random();
for (int i = 1; i < 6; i++)
{
var newItem = new FlatModel()
{
Id = LastId,
Title = "Task " + i.ToString(),
Start = new DateTime(2021, 7, 5 + i),
End = new DateTime(2021, 7, 11 + i),
PercentComplete = Math.Round(random.NextDouble(), 2),
CustomField = "Details for task " + i,
SomeIntField = i
};
Data.Add(newItem);
var parentId = LastId;
LastId++;
for (int j = 0; j < 5; j++)
{
Data.Add(new FlatModel()
{
Id = LastId,
ParentId = parentId,
Title = " Task " + i + " : " + j.ToString(),
Start = new DateTime(2021, 7, 5 + j),
End = new DateTime(2021, 7, 6 + i + j),
PercentComplete = Math.Round(random.NextDouble(), 2),
CustomField = "Details for task " + i,
SomeIntField = j
});
LastId++;
}
}
base.OnInitialized();
}
}