Unplanned
Last Updated: 31 Aug 2026 13:12 by Graeme
Graeme
Created on: 31 Aug 2026 13:12
Category: Gantt
Type: Bug Report
1
Timeline header does not scroll horizontally with the content

The Gantt Timeline header no longer scrolls horizontally together with the content below it.

The issue occurs in version 15.0.0.

A possible workaround is to enable scroll syncing with JavaScript:

https://blazorrepl.telerik.com/GqYiHFvd10Uo0MgN20

@implements IAsyncDisposable
@inject IJSRuntime JS

<TelerikGantt Data="@GanttData"
              @bind-View="@CurrentView"
              Class="scrollable-gantt-1"
              IdField="@nameof(FlatModel.Id)"
              ParentIdField="@nameof(FlatModel.ParentId)"
              Width="700px"
              Height="500px">
    <GanttViews>
        <GanttDayView></GanttDayView>
        <GanttWeekView></GanttWeekView>
        <GanttMonthView></GanttMonthView>
        <GanttYearView></GanttYearView>
    </GanttViews>
    <GanttColumns>
        <GanttColumn Field="@nameof(FlatModel.Id)"
                     Visible="false">
        </GanttColumn>
        <GanttColumn Field="@nameof(FlatModel.Title)"
                     Expandable="true"
                     Width="160px"
                     Title="Task Title">
        </GanttColumn>
        <GanttColumn Field="@nameof(FlatModel.PercentComplete)"
                     Title="Completed"
                     Width="60px">
        </GanttColumn>
        <GanttColumn Field="@nameof(FlatModel.Start)"
                     Width="100px"
                     TextAlign="@ColumnTextAlign.Right">
        </GanttColumn>
        <GanttColumn Field="@nameof(FlatModel.End)"
                     DisplayFormat="End: {0:d}"
                     Width="100px">
        </GanttColumn>
    </GanttColumns>
</TelerikGantt>

<script suppress-error="BL9992">
    function initGanttScrollSync(ganttSelector) {
        const ganttTimelineContent = document.querySelector(ganttSelector + " .k-gantt-timeline .k-grid-content");
        if (ganttTimelineContent) {
            ganttTimelineContent.addEventListener("scroll", onGanttTimelineScroll);
        }
    }

    function disposeGanttScrollSync(ganttSelector) {
        const ganttTimelineContent = document.querySelector(ganttSelector + " .k-gantt-timeline .k-grid-content");

        if (ganttTimelineContent) {
            ganttTimelineContent.removeEventListener("scroll", onGanttTimelineScroll);
        }
    }

    function onGanttTimelineScroll(e) {
        const ganttTimelineHeader = e.target.closest(".k-gantt-timeline").querySelector(".k-grid-header-wrap");
        if (ganttTimelineHeader) {
            ganttTimelineHeader.scrollLeft = e.target.scrollLeft;
        }
    }
</script>

@code {
    private List<FlatModel> GanttData { get; set; } = new List<FlatModel>();
    private List<FlatModel> Data { get; set; } = new List<FlatModel>();

    private GanttView CurrentView { get; set; } = GanttView.Week;

    private int LastId { get; set; } = 1;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await JS.InvokeVoidAsync("initGanttScrollSync", ".scrollable-gantt-1");
        }

        await base.OnAfterRenderAsync(firstRender);
    }

    public async ValueTask DisposeAsync()
    {
        await JS.InvokeVoidAsync("disposeGanttScrollSync", ".scrollable-gantt-1");
    }

    protected override void OnInitialized()
    {
        GanttData = new List<FlatModel>();
        var random = new Random();

        for (int i = 1; i <= 3; i++)
        {
            var newItem = new FlatModel()
            {
                Id = LastId,
                Title = $"Employee  {i}",
                Start = new DateTime(2020, 12, 10 + i),
                End = new DateTime(2020, 12, 11 + i),
                PercentComplete = Math.Round(random.NextDouble(), 2),
                HasChildren = true
            };

            GanttData.Add(newItem);
            var parentId = LastId;
            LastId++;

            for (int j = 1; j <= 2; j++)
            {
                GanttData.Add(new FlatModel()
                {
                    Id = LastId,
                    ParentId = parentId,
                    Title = $"Employee {i} : {j}",
                    Start = new DateTime(2020, 12, 20 + j),
                    End = new DateTime(2020, 12, 21 + i + j),
                    PercentComplete = Math.Round(random.NextDouble(), 2)
                });

                LastId++;
            }
        }

        base.OnInitialized();
    }

    public class FlatModel
    {
        public int Id { get; set; }
        public int? ParentId { get; set; }
        public string Title { get; set; } = string.Empty;
        public double PercentComplete { get; set; }
        public DateTime Start { get; set; }
        public DateTime End { get; set; }
        public bool HasChildren { get; set; }
    }
}

 

0 comments