--- FOR FUTURE REQUEST ---
Could be very useful to scrolling tha grid to a specific item\row (in Normal Grd and also in Virtual Grid mode, both) programmatically. Whithout javascript.
For example after loading a grid that show 20 items, programmatically is it possible to go (and display in grid) not the first 20 rows but for example at row 100. So the vertical scrolling bar muso go dow sice arriving and show that row.
Best Regards
Paolo Leonesi
Hello Al,
Yes, add a small Task.Delay() in OnAfterRenderAsync(). The exact delay duration usually doesn't matter, but you can test what is the smallest reliable number in your case. I updated my example.
Regards,
Dimo
Progress Telerik
I've implemented the suggested solution from Dimo. I don't have to worry about virtual scrolling and I'm not scrolling to a selected row. I have placed an id on an element in the first column and calling scrollIntoView on it.
It works most of the time but sometimes the javascript is called before the render is complete and it doesn't find the element. Is there a way to make sure rendering is complete before the javascript is called in OnAfterRenderAsync? Or is there updated guidance on how to scroll to a grid row programmatically?
Thanks,
Al
Hi Paolo,
I agree that automatic scrolling to a row can be useful. However, the scenario raises some questions that will depend on the business requirements (for example what happens if the row is not currently rendered). And more importantly - the feature depends on the Grid to have all the data, otherwise it doesn't know where the row is. This is not the case with manual data operations (OnRead).
That is why we prefer to leave developers to implement the required calculations. Here is an example that you can use for reference (compatible with UI for Blazor 3.0):
@using Telerik.DataSource
@using Telerik.DataSource.Extensions
@inject IJSRuntime js
<p>
<label for="rowID">Row ID (1 - @AllData.Count.ToString()):</label>
<TelerikNumericTextBox Id="rowID"@bind-Value="@IDToSelect" Min="1" Max="@AllData.Count" Width="100px" />
<TelerikButton OnClick="@SelectRow">Select and Scroll to Row</TelerikButton>
</p>
<TelerikGrid @ref="@SelectableGrid"
OnRead="@GridOnRead"
Pageable="true"
PageSize="@GridPageSize"@bind-Page="@GridPage"
Height="420px"
Sortable="true"
FilterMode="GridFilterMode.FilterRow"
SelectionMode="GridSelectionMode.Single"@bind-SelectedItems="@SelectedItems">
<GridColumns>
<GridCheckboxColumn SelectAll="true" Width="42px" />
<GridColumn Field=@nameof(Product.Name) Title="Product Name" />
<GridColumn Field=@nameof(Product.Price) Title="Price" />
<GridColumn Field=@nameof(Product.Quantity) Title="Units In Stock" />
</GridColumns>
</TelerikGrid>
<script suppress-error="BL9992">function scrollToRow() {
var row = document.querySelector("tr.k-state-selected");
if (row) {
row.scrollIntoView();
}
}</script>
@code {
List<Product> AllData { get; set; }
TelerikGrid<Product> SelectableGrid { get; set; }
DataSourceRequest GridDataRequest { get; set; }
int GridPageSize { get; set; } = 30;
int GridPage { get; set; } = 1;
IEnumerable<Product> SelectedItems { get; set; } = new List<Product>();
int IDToSelect { get; set; } = 50;
bool ShouldScrollToRow { get; set; } = false;
async Task SelectRow()
{
GridDataRequest.Page = 1;
GridDataRequest.PageSize = AllData.Count;
GridDataRequest.Skip = 0;
var gridDataNoPaging = (AllData.ToDataSourceResult(GridDataRequest).Data as IEnumerable<Product>).ToList();
int rowIndex = gridDataNoPaging.FindIndex(item => item.ID == IDToSelect);
var newPage = rowIndex / GridPageSize + 1;
if (newPage != GridPage)
{
var gridState = SelectableGrid.GetState();
gridState.Page = newPage;
await SelectableGrid.SetState(gridState);
}
ShouldScrollToRow = true;
SelectedItems = new List<Product>() { AllData.Where(item => item.ID == IDToSelect).FirstOrDefault() };
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (ShouldScrollToRow)
{
await Task.Delay(1);
ShouldScrollToRow = false;
await js.InvokeVoidAsync("scrollToRow");
}
await base.OnAfterRenderAsync(firstRender);
}
async Task GridOnRead(GridReadEventArgs args)
{
GridDataRequest = args.Request;
var result = AllData.ToDataSourceResult(args.Request);
args.Data = (result.Data as IEnumerable<Product>).ToList();
args.Total = result.Total;
}
protected override void OnInitialized()
{
AllData = new List<Product>();
var rnd = new Random();
for (int i = 1; i <= 120; i++)
{
AllData.Add(new Product()
{
ID = i,
Name = "Product " + i.ToString(),
Price = (decimal)rnd.Next(1, 100),
Quantity = (short)rnd.Next(1, 100)
});
}
}
publicclass Product
{
public int ID { get; set; }
publicstring Name { get; set; }
public decimal Price { get; set; }
public short Quantity { get; set; }
}
}
Regards,
Dimo
Progress Telerik