diff --git a/knowledge-base/grid-scroll-to-selected-row.md b/knowledge-base/grid-scroll-to-selected-row.md index d4d4f98813..0b8e71b16c 100644 --- a/knowledge-base/grid-scroll-to-selected-row.md +++ b/knowledge-base/grid-scroll-to-selected-row.md @@ -22,11 +22,268 @@ res_type: kb ## Description -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. + +I want to programmatically [select a row in the Grid]({%slug grid-selection-row%}) based on specific conditions in my code. Once selected, I’d like the Grid to automatically scroll to that row so it’s visible to the user. ## Solution -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. -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. +The solution to select programatically a row in Grid and scroll to that selected row, depends on the Grid configuration. + +### Grid with **[paging feature]({%slug components/grid/features/paging%})** + +1. Ensure the Grid is on the same page as the selected row. +1. Invoke a JavaScript to make the browser scroll to the selected row into view. The browsers provide the `scrollIntoView()` method that does the scrolling. You can find a selected row in the grid markup by its `k-selected` CSS class. + +### Grid with **[virtualization feature]({%slug components/grid/virtual-scrolling%})** + +1. Use the [Grid state]({%slug grid-state%}). +1. Set the [`Skip` parameter]({%slug grid-state%}#information-in-the-grid-state) to the index of the item in the current data collection. + +## Example + +The example below offers comments in the code on some possible improvements. + +>caption Select a Row in Grid Programmatically and Scroll to the Row + +````CSHTML +@using Telerik.DataSource +@using Telerik.DataSource.Extensions +@inject IJSRuntime JsInterop + + +@* Move JavaScript code to a separate JS file in production *@ + + + + +
+

Grid with Paging

+ + + + + + + + + + +
+

Grid with Virtualization

+ + + + + + + + + + + +@code { + #region Parameters + + private TelerikGrid? GridRef { get; set; } + + private List GridData { get; set; } = new(); + private List Employees { get; set; } = new(); + + private IEnumerable SelectedItemsInPageMode { get; set; } = Enumerable.Empty(); + private IEnumerable SelectedItemsInVirtualization { get; set; } = Enumerable.Empty(); + + private string SelectedEmployeeInPageMode { get; set; } = string.Empty; + private string SelectedEmployeeInVirtualization { get; set; } = string.Empty; + + private int PageInPageMode { get; set; } = 1; + private int PageSizeInPageMode { get; set; } = 30; + private int PageSizeInVirtualization { get; set; } = 20; + + private int GridDataCount { get; set; } + private int AllDataCount { get; set; } + + #endregion Parameters + + #region Event Handlers + + private async Task HandleSelectedRowWithPageMode(string newValue) + { + SelectedEmployeeInPageMode = newValue; + + if (!string.IsNullOrEmpty(SelectedEmployeeInPageMode)) + { + SelectedItemsInPageMode = GridData.Where(item => item.Name == SelectedEmployeeInPageMode).ToList(); + + //Find and set the page where is the selected item + int itemIndex = GridData.IndexOf(SelectedItemsInPageMode.First()); + PageInPageMode = (int)Math.Ceiling((double)(itemIndex + 1) / PageSizeInPageMode); + + await Task.Delay(20);//Simulate network delay so the page can be set and render in the browser + + await JsInterop.InvokeVoidAsync("scrollToSelectedRow"); + } + else + { + SelectedItemsInPageMode = new List(); + await Task.Delay(20);//Simulate network delay + await JsInterop.InvokeVoidAsync("scrollToFirstRow"); + } + } + + private async Task HandleSelectedRowWithVirtualization(string newValue) + { + SelectedEmployeeInVirtualization = newValue; + + int targetItemIndex; + + if (!string.IsNullOrEmpty(SelectedEmployeeInVirtualization)) + { + SelectedItemsInVirtualization = GridData.Where(item => item.Name == SelectedEmployeeInVirtualization).ToList(); + targetItemIndex = GridData.IndexOf(SelectedItemsInVirtualization.First()); + } + else + { + SelectedItemsInVirtualization = new List(); + targetItemIndex = GridData.IndexOf(GridData.First()); + } + await SetSkip(targetItemIndex, SelectedItemsInVirtualization); + } + + #endregion Event Handlers + + #region Methods + + private async Task SetSkip(int skip) + { + await SetSkip(skip, null); + } + + private async Task SetSkip(int skip, IEnumerable itemsToSelect) + { + if (GridRef != null) + { + var state = GridRef.GetState(); + if (itemsToSelect != null) + { + state.SelectedItems = (ICollection)itemsToSelect; + } + state.Skip = ValidateSkip(skip); + await GridRef.SetStateAsync(state); + } + } + + private int ValidateSkip(int desiredSkip) + { + if (desiredSkip < 0) return 0; + int itemsThatFitPerPage = 7; + bool isInvalidSkip = GridDataCount < itemsThatFitPerPage; + return isInvalidSkip ? AllDataCount - itemsThatFitPerPage : desiredSkip; + } + + #endregion Methods + + #region Life Cycle Methods + + protected override async Task OnInitializedAsync() + { + GridData = GenerateData(); + Employees = GridData.Select(e => e.Name).ToList(); + } + + #endregion Life Cycle Methods + + #region Data Generation + + protected async Task ReadItems(GridReadEventArgs args) + { + var datasourceResult = GridData.ToDataSourceResult(args.Request); + var data = ((IEnumerable)datasourceResult.Data).ToList(); + args.Data = data; + args.Total = AllDataCount = datasourceResult.Total; + GridDataCount = data.Count; + + //See more about why this is done here https://docs.telerik.com/blazor-ui/knowledge-base/grid-large-skip-breaks-virtualization + int allowedSkip = ValidateSkip(args.Request.Skip); + if (allowedSkip != args.Request.Skip) + { + await SetSkip(allowedSkip); + } + } + + private List GenerateData() + { + List data = new List(); + for (int i = 1; i <= 100; i++) + { + data.Add(new Employee() + { + EmployeeId = i, + Name = "Employee " + i.ToString(), + Team = "Team " + i % 3 + }); + } + return data; + } + + #endregion Data Generation + + #region Models + + public class Employee + { + public int EmployeeId { get; set; } + public string Name { get; set; } + public string Team { get; set; } + } + + #endregion Models +} +```` -You can find examples in the following sample project: https://github.com/telerik/blazor-ui/tree/master/grid/scroll-to-selected-row +## See Also +* [Grid Row Selection]({%slug grid-selection-row%}) +* [Grid paging feature]({%slug components/grid/features/paging%}) +* [Grid virtualization feature]({%slug components/grid/virtual-scrolling%})