Skip to content

Commit 5f0634d

Browse files
committed
docs(Grid): Add KB for programmatically row selection and scroll to row
1 parent 7468ad0 commit 5f0634d

File tree

1 file changed

+259
-4
lines changed

1 file changed

+259
-4
lines changed

knowledge-base/grid-scroll-to-selected-row.md

Lines changed: 259 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,266 @@ res_type: kb
2222

2323

2424
## Description
25-
I would like to pre-select a row when the page is loaded, and I would like to show the grid with that row scrolled to the top, or sorted to appear on top.
25+
26+
I want to [select a row in Grid]({%slug grid-selection-row%}) programmatically based on some program logic and conditions. I want after that to scroll the Grid to the selected row so the user can see the selected row.
2627

2728
## Solution
28-
You can find a selected row in the grid markup by the `k-selected` CSS class it has, and use a bit of JavaScript to scroll to it - browsers provide the `scrollIntoView()` method for that.
2929

30-
With **row virtualization**, however, the selected row may not be rendered. That is why you need to find its position and scroll to it through the `Skip` parameter of the Grid.
30+
The solution to select programatically a row in Grid and scroll to that selected row, depends on the Grid configuration.
31+
32+
### Grid with **[paging feature]({%slug components/grid/features/paging%})**
33+
34+
1. Ensure the Grid is on the same page as the selected row.
35+
1. Invoke a JavaScript to make the browser scroll to the selected row into view. The browsers provide the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView" target="_blank">`scrollIntoView()` method</a> that does the scrolling. You can find a selected row in the grid markup by the `k-selected` CSS class it has.
36+
37+
### Grid with **[virtualization feature]({%slug components/grid/virtual-scrolling%})**
38+
39+
1. Use the [Grid state]({%slug grid-state%}).
40+
1. Set the [`Skip` parameter]({%slug grid-state%}#information-in-the-grid-state) to the index of the item in the current data collection.
41+
42+
## Example
43+
44+
The example below offers comments in the code on some possible improvements.
45+
46+
>caption Select a Row in Grid Programmatically and Scroll to the Row
47+
48+
````CSHTML
49+
@using Telerik.DataSource
50+
@using Telerik.DataSource.Extensions
51+
@inject IJSRuntime JsInterop
52+
53+
54+
@* Move JavaScript code to a separate JS file in production *@
55+
<script suppress-error="BL9992">
56+
window.scrollToSelectedRow = function () {
57+
var selectedRow = document.querySelector('.k-selected');
58+
if (selectedRow) {
59+
selectedRow.scrollIntoView();
60+
}
61+
}
62+
</script>
63+
64+
<script suppress-error="BL9992">
65+
window.scrollToFirstRow = function () {
66+
var selectedRow = document.querySelector('.k-table-row.k-master-row');
67+
if (selectedRow) {
68+
selectedRow.scrollIntoView();
69+
}
70+
}
71+
</script>
72+
73+
<br/>
74+
<h2>Grid with Paging</h2>
75+
<TelerikAutoComplete Data="@Employees"
76+
Value="@SelectedEmployeeInPageMode"
77+
Placeholder="Search an employee..."
78+
ShowClearButton="true"
79+
DebounceDelay="500"
80+
Width="300px"
81+
ValueChanged="@ValueChangedInPageMode">
82+
</TelerikAutoComplete>
83+
84+
<TelerikGrid Data=@GridData
85+
SelectionMode="@GridSelectionMode.Single"
86+
@bind-SelectedItems="@SelectedItemsInPageMode"
87+
Pageable="true"
88+
Page="@PageInPageMode"
89+
PageSize="@PageSizeInPageMode"
90+
Height="300px">
91+
<GridColumns>
92+
<GridColumn Field=@nameof(Employee.Name) />
93+
<GridColumn Field=@nameof(Employee.Team) Title="Team" />
94+
</GridColumns>
95+
</TelerikGrid>
96+
97+
<br/>
98+
<h2>Grid with Virtualization</h2>
99+
<TelerikAutoComplete Data="@Employees"
100+
Value="@SelectedEmployeeInVirtualization"
101+
Placeholder="Search an employee..."
102+
ShowClearButton="true"
103+
DebounceDelay="500"
104+
Width="300px"
105+
ValueChanged="@ValueChangedInVirtualization">
106+
</TelerikAutoComplete>
107+
108+
<TelerikGrid @ref="@GridRef"
109+
TItem="@Employee"
110+
OnRead="@ReadItems"
111+
SelectionMode="GridSelectionMode.Single"
112+
@bind-SelectedItems="@SelectedItemsInVirtualization"
113+
Sortable="true"
114+
ScrollMode="@GridScrollMode.Virtual"
115+
RowHeight="40"
116+
PageSize="@PageSizeInVirtualization"
117+
Height="300px">
118+
<GridColumns>
119+
<GridColumn Field=@nameof(Employee.Name) />
120+
<GridColumn Field=@nameof(Employee.Team) Title="Team" />
121+
</GridColumns>
122+
</TelerikGrid>
123+
124+
125+
@code {
126+
#region Parameters
127+
128+
private TelerikGrid<Employee>? GridRef { get; set; }
129+
130+
private List<Employee> GridData { get; set; } = new();
131+
private List<string> Employees { get; set; } = new();
132+
133+
private IEnumerable<Employee> SelectedItemsInPageMode { get; set; } = Enumerable.Empty<Employee>();
134+
private IEnumerable<Employee> SelectedItemsInVirtualization { get; set; } = Enumerable.Empty<Employee>();
135+
136+
private string SelectedEmployeeInPageMode { get; set; } = string.Empty;
137+
private string SelectedEmployeeInVirtualization { get; set; } = string.Empty;
138+
139+
private int PageInPageMode { get; set; } = 1;
140+
private int PageSizeInPageMode { get; set; } = 30;
141+
private int PageSizeInVirtualization { get; set; } = 20;
142+
143+
private int GridDataCount { get; set; }
144+
private int AllDataCount { get; set; }
145+
146+
#endregion Parameters
147+
148+
#region Event Handlers
149+
150+
private async Task ValueChangedInPageMode(string newValue)
151+
{
152+
SelectedEmployeeInPageMode = newValue;
153+
154+
if (!string.IsNullOrEmpty(SelectedEmployeeInPageMode))
155+
{
156+
SelectedItemsInPageMode = GridData.Where(item => item.Name == SelectedEmployeeInPageMode).ToList();
157+
158+
//Find and set the page where is the selected item
159+
int itemIndex = GridData.IndexOf(SelectedItemsInPageMode.First());
160+
PageInPageMode = (int)Math.Ceiling((double)(itemIndex + 1) / PageSizeInPageMode);
161+
162+
await Task.Delay(20);//Simulate network delay so the page can be set and render in the browser
163+
164+
await JsInterop.InvokeVoidAsync("scrollToSelectedRow");
165+
}
166+
else
167+
{
168+
SelectedItemsInPageMode = new List<Employee>();
169+
await Task.Delay(20);//Simulate network delay
170+
await JsInterop.InvokeVoidAsync("scrollToFirstRow");
171+
}
172+
}
173+
174+
private async Task ValueChangedInVirtualization(string newValue)
175+
{
176+
SelectedEmployeeInVirtualization = newValue;
177+
178+
int targetItemIndex;
179+
180+
if (!string.IsNullOrEmpty(SelectedEmployeeInVirtualization))
181+
{
182+
SelectedItemsInVirtualization = GridData.Where(item => item.Name == SelectedEmployeeInVirtualization).ToList();
183+
targetItemIndex = GridData.IndexOf(SelectedItemsInVirtualization.First());
184+
}
185+
else
186+
{
187+
SelectedItemsInVirtualization = new List<Employee>();
188+
targetItemIndex = GridData.IndexOf(GridData.First());
189+
}
190+
await SetSkip(targetItemIndex, SelectedItemsInVirtualization);
191+
}
192+
193+
#endregion Event Handlers
194+
195+
#region Methods
196+
197+
private async Task SetSkip(int skip)
198+
{
199+
await SetSkip(skip, null);
200+
}
201+
202+
private async Task SetSkip(int skip, IEnumerable<Employee> itemsToSelect)
203+
{
204+
if (GridRef != null)
205+
{
206+
var state = GridRef.GetState();
207+
if (itemsToSelect != null)
208+
{
209+
state.SelectedItems = (ICollection<Employee>)itemsToSelect;
210+
}
211+
state.Skip = ValidateSkip(skip);
212+
await GridRef.SetStateAsync(state);
213+
}
214+
}
215+
216+
private int ValidateSkip(int desiredSkip)
217+
{
218+
if (desiredSkip < 0) return 0;
219+
int itemsThatFitPerPage = 7;
220+
bool isInvalidSkip = GridDataCount < itemsThatFitPerPage;
221+
return isInvalidSkip ? AllDataCount - itemsThatFitPerPage : desiredSkip;
222+
}
223+
224+
#endregion Methods
225+
226+
#region Life Cycle Methods
227+
228+
protected override async Task OnInitializedAsync()
229+
{
230+
GridData = GenerateData();
231+
Employees = GridData.Select(e => e.Name).ToList();
232+
}
233+
234+
#endregion Life Cycle Methods
235+
236+
#region Data Generation
237+
238+
protected async Task ReadItems(GridReadEventArgs args)
239+
{
240+
var datasourceResult = GridData.ToDataSourceResult(args.Request);
241+
var data = ((IEnumerable<Employee>)datasourceResult.Data).ToList();
242+
args.Data = data;
243+
args.Total = AllDataCount = datasourceResult.Total;
244+
GridDataCount = data.Count;
245+
246+
//See more about why this is done here https://docs.telerik.com/blazor-ui/knowledge-base/grid-large-skip-breaks-virtualization
247+
int allowedSkip = ValidateSkip(args.Request.Skip);
248+
if (allowedSkip != args.Request.Skip)
249+
{
250+
await SetSkip(allowedSkip);
251+
}
252+
}
253+
254+
private List<Employee> GenerateData()
255+
{
256+
List<Employee> data = new List<Employee>();
257+
for (int i = 1; i <= 100; i++)
258+
{
259+
data.Add(new Employee()
260+
{
261+
EmployeeId = i,
262+
Name = "Employee " + i.ToString(),
263+
Team = "Team " + i % 3
264+
});
265+
}
266+
return data;
267+
}
268+
269+
#endregion Data Generation
270+
271+
#region Models
272+
273+
public class Employee
274+
{
275+
public int EmployeeId { get; set; }
276+
public string Name { get; set; }
277+
public string Team { get; set; }
278+
}
279+
280+
#endregion Models
281+
}
282+
````
31283

32-
You can find examples in the following sample project: https://github.com/telerik/blazor-ui/tree/master/grid/scroll-to-selected-row
284+
## See Also
285+
* [Grid row selection]({%slug grid-selection-row%})
286+
* [Grid paging feature]({%slug components/grid/features/paging%})
287+
* [Grid virtualization feature]({%slug components/grid/virtual-scrolling%})

0 commit comments

Comments
 (0)