blazor-docs/knowledge-base/grid-pin-rows.md

4.4 KiB

title description type page_title slug position tags res_type
Pin rows on top of the Grid Pin one or more rows on top of the Grid how-to Pin rows on top of the Grid grid-pin-rows grid, pin, rows, sticky, frozen, locked kb

Environment

Product Grid for Blazor

Description

I would like to pin one or more rows on top of the Grid so that they are always visible to the users.

Solution

To achieve the desired behavior you can:

  • Use the [OnRead event]({%slug components/grid/manual-operations%}) to place the row/rows on top of the data collection for the Grid.
  • Use the [OnRowRender event]({%slug grid-events%}#onrowrender) to add a custom CSS class to the rows you want to pin.
  • Dynamically calculate the top CSS rule with JavaScript.
  • Register the JavaScript file.
````C# @* Pin rows to the Grid *@

@using Telerik.DataSource @using Telerik.DataSource.Extensions

@inject IJSRuntime js

@code { private void RowRenderHandler(GridRowRenderEventArgs args) { var gridRow = args.Item as Employee;

    foreach (var pinnedRowIndex in pinnedGridRows)
    {
        if (gridRow.ID == pinnedRowIndex)
        {
            args.Class = "k-grid-row-sticky";
        }
    }
}

public List<int> pinnedGridRows { get; set; } = new List<int>()
{
    5, 12, 21
};

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    await js.InvokeVoidAsync("pinElements", ".k-grid-row-sticky", 40);
}

public int pinnedRowIndex { get; set; } = 20;

public List<Employee> SourceData { get; set; }

private List<Employee> PinnedTopRow(DataSourceResult result)
{
    List<Employee> _data = result.Data.Cast<Employee>().ToList();
    var indexToInsert = 0;

    foreach (var pinnedRow in pinnedGridRows)
    {
        var rowToBePinned = _data.FirstOrDefault(x => x.ID == pinnedRow);
        _data.Remove(rowToBePinned);

        _data.Insert(indexToInsert, rowToBePinned);
        indexToInsert++;
    }

    return _data;
}

protected async Task ReadItems(GridReadEventArgs args)
{
    await Task.Delay(1000);

    var datasourceResult = SourceData.ToDataSourceResult(args.Request);

    args.Data = PinnedTopRow(datasourceResult);
    args.Total = datasourceResult.Total;
}

protected override void OnInitialized()
{
    SourceData = GenerateData();
}

private List<Employee> GenerateData()
{
    var result = new List<Employee>();
    var rand = new Random();
    for (int i = 0; i < 100; i++)
    {
        result.Add(new Employee()
        {
            ID = i,
            Name = "Name " + i,
            HireDate = DateTime.Now.Date.AddDays(rand.Next(-20, 20))
        });
    }

    return result;
}

public class Employee
{
    public int ID { get; set; }
    public string Name { get; set; }
    public DateTime HireDate { get; set; }
}

}

````JavaScript
@* Calculate the top CSS rule *@

function pinElements(pinCSSClass, rowHeight) {
    let elements = document.querySelectorAll(pinCSSClass);

    elements.forEach((element, index) => {
        element.style.top = index * rowHeight + "px"
    });
}