Hello everyone,
We created this Feature Request to gather feedback on the way the item expansion is working in the Grid state. Currently, you can expand any items with the ExpandedRows collection of int where you pass the indexes of the rows.
Another option, which we are thinking of, is to provide a Collection<Model>. This would let you pass models, instead of indexes and the Grid would automatically expand those items. This approach would make the need to preserve the indexes redundant, which you should currently do when Filtering/Sorting and Grouping the items in the Grid.
We would appreciate your feedback on both approaches and which you think will be easier to use.
Hello John,
We have another feature request that targets to limit the number of times when the OnRead fires after the Grid state changes. Here is the feature request - Grid SetStateAsync method should not fire OnRead when not necessary. I have added your Vote for it and you can click the Follow button to receive email notifications on status updates.
Regards,
Svetoslav Dimitrov
Progress Telerik
Hello Jonathan,
This feature request targets the way you can expand the Grid rows with DetailTemplate. The Group expanding behavior was not changed as part of this feature request.
Regards,
Svetoslav Dimitrov
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.
Hello everyone,
I would like to offer a workaround solution for the time being. Below, I have provided some additional explanation on the current approach and what will change when this feature request is implemented.
Currently, the Grid exposes a List<int> - ExpandedRows. In order to use features like sorting and filtering you should preserve the index/es (depending on the number of rows you would like to expand). In order to do that, you should use the OnRead event, which gives information on the current state of the data source (filtered/sorted).
@using Telerik.DataSource
@using Telerik.DataSource.Extensions
<TelerikGrid Data="@currentSalesTeamMembers"
OnRowClick="@OnRowClickHandler"
@ref="Grid"
OnRead="@OnReadHandler"
TotalCount="@Total"
Sortable="true">
<DetailTemplate>
@{
var employee = context as MainModel;
<TelerikGrid Data="employee.Orders" Pageable="true" PageSize="5">
<GridColumns>
<GridColumn Field="OrderId"></GridColumn>
<GridColumn Field="DealSize"></GridColumn>
</GridColumns>
</TelerikGrid>
}
</DetailTemplate>
<GridColumns>
<GridColumn Field="Id"></GridColumn>
<GridColumn Field="Name"></GridColumn>
</GridColumns>
</TelerikGrid>
@code {
public TelerikGrid<MainModel> Grid { get; set; }
public int Total { get; set; }
List<MainModel> salesTeamMembers { get; set; }
List<MainModel> currentSalesTeamMembers { get; set; } //implementation of OnRead
public bool shouldPreventOnRead { get; set; }
MainModel currentItem { get; set; } //need to save the selected item to determine its new index
async Task OnReadHandler(GridReadEventArgs args)
{
var dataSourceResult = salesTeamMembers.ToDataSourceResult(args.Request);
currentSalesTeamMembers = dataSourceResult.Data.Cast<MainModel>().ToList(); // this is the collection with the sorted items
int currentIndexOfItem = currentSalesTeamMembers.IndexOf(currentItem);
Total = dataSourceResult.Total;
if (Grid != null && !shouldPreventOnRead)
{
await ExpandFromState(currentIndexOfItem);
}
shouldPreventOnRead = false;
StateHasChanged();
}
async Task OnRowClickHandler(GridRowClickEventArgs args)
{
var item = args.Item as MainModel;
int rowIndex = currentSalesTeamMembers.IndexOf(item);
currentItem = currentSalesTeamMembers[rowIndex];
await ExpandFromState(rowIndex);
}
async Task ExpandFromState(int rowIndex)
{
shouldPreventOnRead = true;
var currentState = Grid.GetState();
if (currentState.ExpandedRows.Contains(rowIndex))
{
currentState.ExpandedRows = new List<int>();
}
else
{
currentState.ExpandedRows = new List<int> { rowIndex };
}
await Grid.SetState(currentState);
}
protected override void OnInitialized()
{
salesTeamMembers = GenerateData();
}
private List<MainModel> GenerateData()
{
List<MainModel> data = new List<MainModel>();
for (int i = 0; i < 5; i++)
{
MainModel mdl = new MainModel { Id = i, Name = $"Name {i}" };
mdl.Orders = Enumerable.Range(1, 15).Select(x => new DetailsModel { OrderId = x, DealSize = x ^ i }).ToList();
data.Add(mdl);
}
return data;
}
public class MainModel
{
public int Id { get; set; }
public string Name { get; set; }
public List<DetailsModel> Orders { get; set; }
}
public class DetailsModel
{
public int OrderId { get; set; }
public double DealSize { get; set; }
}
}
This is not implemented yet, so this code snippet is not runnable, but its purpose is to demonstrate what the feature would be like.
<TelerikGrid Data="@salesTeamMembers"
OnRowClick="@OnRowClickHandler"
@ref="Grid"
Sortable="true">
<DetailTemplate>
@{
var employee = context as MainModel;
<TelerikGrid Data="employee.Orders" Pageable="true" PageSize="5">
<GridColumns>
<GridColumn Field="OrderId"></GridColumn>
<GridColumn Field="DealSize"></GridColumn>
</GridColumns>
</TelerikGrid>
}
</DetailTemplate>
<GridColumns>
<GridColumn Field="Id"></GridColumn>
<GridColumn Field="Name"></GridColumn>
</GridColumns>
</TelerikGrid>
@code {
public TelerikGrid<MainModel> Grid { get; set; }
List<MainModel> salesTeamMembers { get; set; }
async Task OnRowClickHandler(GridRowClickEventArgs args)
{
var item = args.Item as MainModel;
await ExpandFromState(item);
}
async Task ExpandFromState(MainModel row)
{
var currentState = Grid.GetState();
if (currentState.ExpandedItems.Contains(row))
{
currentState.ExpandedItems = new List<MainModel>();
}
else
{
currentState.ExpandedItems = new List<MainModel>(row);
}
await Grid.SetState(currentState);
}
protected override void OnInitialized()
{
salesTeamMembers = GenerateData();
}
private List<MainModel> GenerateData()
{
List<MainModel> data = new List<MainModel>();
for (int i = 0; i < 5; i++)
{
MainModel mdl = new MainModel { Id = i, Name = $"Name {i}" };
mdl.Orders = Enumerable.Range(1, 15).Select(x => new DetailsModel { OrderId = x, DealSize = x ^ i }).ToList();
data.Add(mdl);
}
return data;
}
public class MainModel
{
public int Id { get; set; }
public string Name { get; set; }
public List<DetailsModel> Orders { get; set; }
}
public class DetailsModel
{
public int OrderId { get; set; }
public double DealSize { get; set; }
}
}
Regards,
Svetoslav Dimitrov
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.