New to Telerik UI for Blazor? Download free 30-day trial

Expand only current item of the Grid and programmatically collapse all others

Environment

Product Grid for Blazor

Description

I have a Grid with hierarchy enabled. When I expand one row, I want to programmatically collapse all other expanded rows.

Solution

The OnRowExpand event provides arguments of type GridRowExpandEventArgs. You can check the Item field of the arguments to get information which item is currently expanded.

You can then use the Grid State to programmatically set its ExpandedRows field. In order to achieve the desired behavior, the ExpandedRows of the Grid State should only has information for the current expanded item. This will result in collapsing all previously expanded items and keep just the current one expanded.

The ExpandedRows accepts a list of item indexes. In order to get the correct index of the current expanded item in case of filtering, sorting, paging of the Grid, use the OnRead event to work with the current data.

See code comments in the example below for more details on the spot.

@using Telerik.DataSource.Extensions

Expanded item index: @currItemIndex

<TelerikGrid Data="@currentSalesTeamMembers" OnRowExpand="@OnExpand" OnRead="@OnReadHandler" TotalCount="@Total"
             @ref="GridRef" Sortable="true" Pageable="true" FilterMode="GridFilterMode.FilterRow">
    <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> GridRef { get; set; }

    List<MainModel> salesTeamMembers { get; set; }

    List<MainModel> currentSalesTeamMembers { get; set; } //implementation of OnRead

    MainModel currentItem { get; set; } //need to save the expanded item to determine its new index

    public int currItemIndex { get; set; } //the new index of the current expanded item

    public int Total { get; set; }

    //use the OnRead event to work with the current data in order to get the new index of the current expanded item in case of filtering, sorting, paging of the Grid
    void OnReadHandler(GridReadEventArgs args)
    {
        var dataSourceResult = salesTeamMembers.ToDataSourceResult(args.Request);

        currentSalesTeamMembers = dataSourceResult.Data.Cast<MainModel>().ToList(); // this is the collection with the current items

        Total = dataSourceResult.Total;

        StateHasChanged();
    }

    //in the OnRowExpand handler you can perform the desired logic to collapse the rest of the items and keep just the current one opened
    async Task OnExpand(GridRowExpandEventArgs args)
    {
        currentItem = args.Item as MainModel;

        //get the new index of the current expanded item from the current data
        currItemIndex = currentSalesTeamMembers.IndexOf(currentItem);

        //use the Grid state and its ExpandedRows field to set the only expanded item to be the current one
        GridState<MainModel> desiredState = GridRef.GetState();

        desiredState.ExpandedRows = new List<int> { currItemIndex };

        await GridRef.SetState(desiredState);
    }

    //data generation and models
    protected override void OnInitialized()
    {
        salesTeamMembers = GenerateData();
    }

    private List<MainModel> GenerateData()
    {
        List<MainModel> data = new List<MainModel>();
        for (int i = 0; i < 30; 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; }
    }
}
In this article
Not finding the help you need? Improve this article