Skip to content

Commit 30a167e

Browse files
dimodiradkostanev
authored andcommitted
kb(Grid): Add KB for sticky headers
1 parent 6286e3d commit 30a167e

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed

knowledge-base/grid-sticky-headers.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
---
2+
title: Enable Sticky Grid Headers
3+
description: Learn how to enable sticky Grid or TreeList headers, which remain visible at the top of the browser viewport when the users scrolls the whole web page.
4+
type: how-to
5+
page_title: How To Enable Sticky Grid Headers
6+
slug: grid-kb-sticky-headers
7+
tags: telerik, blazor, grid, treelist, css, styling
8+
ticketid: 1687016, 1592949, 1522505
9+
res_type: kb
10+
---
11+
12+
## Environment
13+
14+
<table>
15+
<tbody>
16+
<tr>
17+
<td>Product</td>
18+
<td>
19+
Grid for Blazor, <br />
20+
TreeList for Blazor
21+
</td>
22+
</tr>
23+
</tbody>
24+
</table>
25+
26+
## Description
27+
28+
This KB also answers the following questions:
29+
30+
* How to lock (freeze) the Grid header row, so that it remains at the top of the browser viewport during page scrolling?
31+
* How to set a `position:sticky` style to the Grid header row?
32+
* How to make the Grid header stick and persist (always show) at the top of the page while scrolling without a fixed Grid height?
33+
34+
## Solution
35+
36+
Sticky Grid headers require custom CSS. The Grid and TreeList components use very similar HTML rendering, so the approach for both components is the same.
37+
38+
The solution prevents you from setting a Grid `Height`. This should not be a problem, as the idea is users to scroll the whole web page, rather than the Grid.
39+
40+
1. Set the Grid `Class` to some custom CSS class.
41+
1. Use the custom CSS class to apply `position:sticky` style to `.k-grid-header` and reset the `overflow` styles of all Grid elements that have this style set to `hidden` or `scroll`.
42+
43+
>caption Enable sticky Grid headers
44+
45+
````RAZOR
46+
<label class="k-checkbox-label">
47+
<TelerikCheckBox @bind-Value="@StickMasterHeader" />
48+
Sticky Master Grid Header
49+
</label>
50+
51+
<label class="k-checkbox-label">
52+
<TelerikCheckBox @bind-Value="@StickDetailHeader" />
53+
Sticky Detail Grid Header
54+
</label>
55+
56+
<TelerikGrid Data="@CategoryData"
57+
Class="@( StickMasterHeader ? "sticky-header" : "" )"
58+
TItem="@Category"
59+
OnStateInit="@OnMasterGridStateInit">
60+
<GridColumns>
61+
<GridColumn Field="@nameof(Category.Name)"
62+
Title="Category Name" />
63+
</GridColumns>
64+
<DetailTemplate>
65+
<TelerikGrid Data="@ProductData.Where(x => x.CategoryId == context.Id)"
66+
Class="@( StickDetailHeader ? "sticky-header" : "" )">
67+
<GridColumns>
68+
<GridColumn Field="@nameof(Product.Name)"
69+
Title="@( $"Product Name for Category {context.Id}" )" />
70+
</GridColumns>
71+
</TelerikGrid>
72+
</DetailTemplate>
73+
</TelerikGrid>
74+
75+
<style>
76+
.sticky-header > .k-grid-aria-root,
77+
.k-grid-aria-root:has(.sticky-header),
78+
.k-grid-container:has(.sticky-header),
79+
.k-grid-content:has(.sticky-header) {
80+
overflow: visible;
81+
height: auto;
82+
}
83+
84+
.k-detail-cell:has(.sticky-header) {
85+
overflow: visible;
86+
}
87+
88+
.sticky-header .k-grid-header {
89+
position: sticky;
90+
top: 0;
91+
z-index: 10;
92+
}
93+
</style>
94+
95+
@code {
96+
private List<Category> CategoryData { get; set; } = new();
97+
private List<Product> ProductData { get; set; } = new();
98+
99+
private bool StickMasterHeader { get; set; } = true;
100+
private bool StickDetailHeader { get; set; } = true;
101+
102+
private int LastId { get; set; }
103+
104+
private void OnMasterGridStateInit(GridStateEventArgs<Category> args)
105+
{
106+
args.GridState.ExpandedItems = CategoryData;
107+
}
108+
109+
protected override void OnInitialized()
110+
{
111+
var rnd = Random.Shared;
112+
113+
for (int i = 1; i <= 15; i++)
114+
{
115+
CategoryData.Add(new Category()
116+
{
117+
Id = i,
118+
Name = $"Category Name {i} {(char)rnd.Next(65, 91)}{(char)rnd.Next(65, 91)}"
119+
});
120+
121+
for (int j = 1; j <= 5; j++)
122+
{
123+
int productId = ++LastId;
124+
ProductData.Add(new Product()
125+
{
126+
Id = productId,
127+
CategoryId = i,
128+
Name = $"Product Name {productId} {(char)rnd.Next(65, 91)}{(char)rnd.Next(65, 91)}"
129+
});
130+
}
131+
}
132+
}
133+
134+
public class Category
135+
{
136+
public int Id { get; set; }
137+
public string Name { get; set; } = string.Empty;
138+
}
139+
140+
public class Product
141+
{
142+
public int Id { get; set; }
143+
public int CategoryId { get; set; }
144+
public string Name { get; set; } = string.Empty;
145+
}
146+
}
147+
````
148+
149+
## See Also
150+
151+
* [Grid Overview](slug:grid-overview)
152+
* [TreeList Overview](slug:treelist-overview)

0 commit comments

Comments
 (0)