Distinguish the parents from each other and fold out only the submenu from the category that was selected

I have a recursive table that contains the categories and subcategories. The back end and printing out the submenus work fine. But I am having difficulties opening only the selected category. They are printed out with a for each loop, so how can I distinguish them from each other? I tried using a solution on the internet, but it folds out all the categories. I am new to Blazor, so the code may not be efficient.

@if (_categories == null)
{
    Loading
}
else
{
    <div >
    @foreach (var menu in _categories)
    {

        <div class="nav-item px-3">
            <NavLink class="nav-link" href="@($"/category/{menu.Id}")" @onclick="()=>expandSubmenu= !expandSubmenu">
                <span>@menu.Description</span>
            </NavLink>
            @if (menu.Children != null && menu.Children.Any() && expandSubmenu)
            {
                @foreach (var child in menu.Children)
                {
                    <li class="nav-item px-3">
                        <NavLink class="nav-link" href="@($"/category/{child.Id}")">
                                <span>@child.Description</span>
                            </NavLink>
                    </li>
                }
            }
        </div>
    }
    </div>
}

@code {
    private Category[] _categories = null;
    
    private bool expandSubmenu;
    
    protected override void OnInitialized()
    {
        _ = LoadAllCategories();

        StateHasChanged();
    }

    public List<Category> MakeTree(int ParentId){

        List<Category> categories;
        categories = _categoryService.FetchCategories(_context, ParentId).ToList();


        foreach(var cat in categories)
        {
            cat.Children = MakeTree(cat.Id).ToList();
        }
        return categories;
    }

    private async Task LoadAllCategories()
    {
        var load = Task.Run(() => { _categories = MakeTree(0).ToArray(); });
        StateHasChanged();

        await load;
        StateHasChanged();
        _ = LoadingFinished.InvokeAsync();
    }
}

What I am getting
What I am getting

What I want
what I want

>Solution :

This is because you are using the same bool variable (expandSubmenu) for all submenus. ExpandSubmenu should be a property of Category class. Then you can do:

@foreach (var menu in _categories)
{

    <div class="nav-item px-3">
        <NavLink class="nav-link" href="@($"/category/{menu.Id}")" @onclick="()=>menu.ExpandSubmenu= !menu.ExpandSubmenu">
            <span>@menu.Description</span>
        </NavLink>
        @if (menu.Children != null && menu.Children.Any() && menu.ExpandSubmenu)
        {
            @foreach (var child in menu.Children)
            {
                <li class="nav-item px-3">
                    <NavLink class="nav-link" href="@($"/category/{child.Id}")">
                            <span>@child.Description</span>
                        </NavLink>
                </li>
            }
        }
    </div>
}

Leave a Reply