Completed
Last Updated: 12 Oct 2023 12:12 by ADMIN
Release 3.0.0
Svetoslav
Created on: 01 Dec 2020 10:17
Category: Grid
Type: Feature Request
19
Expanded Items in the Grid State.

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.

5 comments
ADMIN
Svetoslav Dimitrov
Posted on: 12 Oct 2023 12:12

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

Stay tuned by visiting our public roadmap and feedback portal pages! Or perhaps, if you are new to our Telerik family, check out our getting started resources!
John
Posted on: 08 Oct 2023 05:12
The problem with SetState is that it forced OnRead event for me. This makes all my data disappear and then when the event completed (data get) the expansion disappears and the state does not show the item in the expandedItems list anymore. It does expand...but then it unexpands after OnRead event.
ADMIN
Svetoslav Dimitrov
Posted on: 27 Oct 2022 08:53

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/.

Jonathan
Posted on: 20 Oct 2022 15:17
Has this been implemented yet? Being able to expand a group by clicking the group/row header?
ADMIN
Svetoslav Dimitrov
Posted on: 08 Dec 2020 09:50

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. 

Current approach:

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; }
    }
}

After implementing this feature request:

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/.