Category and Sub Category in single Dropdownlistfor – ASP.NET MVC

I want to list the Categories as in the picture:

Category and Sub Category in single Dropdownlistfor - ASP.NET MVC

Now I could only list all the categories using VievComponent.

I have a model class like this

public class CategoryModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string Image { get; set; }

    public int? ParentId { get; set; }
}

ViewComponent Class
public class CategoryListViewComponent : ViewComponent
{
    private ICategoryService _categoryService;
    public CategoryListViewComponent(ICategoryService categoryService)
    {
        _categoryService = categoryService;
    }
    public IViewComponentResult Invoke()
    {
        return View(new CategoryListModel()
        {
            SelectedCategory = RouteData.Values["category"]?.ToString(),
            Categories = _categoryService.GetAll()
        });
    }

ViewComponent File
@foreach (var item in Model.Categories)
{
    <li class="menu-item menu-item-submenu" data-menu-toggle="hover" aria-haspopup="true">
        <a asp-controller="Admin" asp-action="CategoryList" asp-route-category="@item.Name.ToLower()" class="menu-link @(Model.SelectedCategory==item.Name.ToLower()?"active":"")">
            <span class="menu-text">@item.Name</span>
            <i class="menu-arrow"></i>
        </a>
    </li>
}

And controller
public IActionResult CategoryList()
{
    return View(new CategoryListModel()
    {
        Categories = _categoryService.GetAll()
    });
}

This way I can to list all my Categories, but how can I list the main and sub categories as in the picture?

result:
enter image description here

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

I think you should have another model for the subcategory items, something like this:

Model:

public class CategoryModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<SubCategoryModel> SubCategories { get; set; }
}

public class SubCategoryModel
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class CategoryListModel
{
    public string SelectedCategory { get; set; }
    public List<CategoryModel> Categories { get; set; }
}

ViewComponent Page:
<ul>
    @foreach (var item in Model.Categories)
    {
        <li class="menu-item menu-item-submenu" data-menu-toggle="hover" aria-haspopup="true">
            <a asp-controller="Admin" asp-action="CategoryList" asp-route-category="@item.Name.ToLower()" class="menu-link @(Model.SelectedCategory==item.Name.ToLower()?"active":"")">
                <span class="menu-text">@item.Name</span>
                <i class="menu-arrow"></i>
            </a>
        </li>
        @if (item.SubCategories != null && item.SubCategories.Count > 0)
        {
            foreach (var subitem in item.SubCategories)
            {
                <li class="menu-item menu-item-submenu" data-menu-toggle="hover" aria-haspopup="true">
                    <a asp-controller="Admin" asp-action="CategoryList" asp-route-category="@subitem.Name.ToLower()" class="menu-link">
                        <span class="menu-text">@item.Name > @subitem.Name</span>
                        <i class="menu-arrow"></i>
                    </a>
                </li>
            }
        }
    }
</ul>

ViewComponent Class:
public class CategoryListViewComponent : ViewComponent
{
    private ICategoryService _categoryService;
    public CategoryListViewComponent(ICategoryService categoryService)
    {
        _categoryService = categoryService;
    }
    public IViewComponentResult Invoke()
    {
        return View(new CategoryListModel()
        {
            Categories = _categoryService.GetAll()
        });
    }
}

CategoryService:
public class CategoryService : ICategoryService
{
    public List<CategoryModel> GetAll()
    {
        var categories = new List<CategoryModel>
        {
            new CategoryModel{ Id = 1, Name = "AA", SubCategories = new List<SubCategoryModel>
                {
                    new SubCategoryModel{ Id = 1, Name = "A1"},
                    new SubCategoryModel{ Id = 2, Name = "A2"},
                } 
            },
            new CategoryModel{ Id = 2, Name = "BB" , SubCategories = new List<SubCategoryModel>
                {
                    new SubCategoryModel{ Id = 1, Name = "B1"},
                    new SubCategoryModel{ Id = 2, Name = "B2"},
                } 
            },
            new CategoryModel{ Id = 3, Name = "CC"},
            new CategoryModel{ Id = 4, Name = "DD"},
        };
        return categories;
    }
}

Result:

Category and Sub Category in single Dropdownlistfor - ASP.NET MVC

UPdate:

public List<CategoryModel> GetAll()
{
    var categories = new List<CategoryModel>
    {
        new CategoryModel{ Id = 1, Name = "AA"},
        new CategoryModel{ Id = 2, Name = "BB"},
        new CategoryModel{ Id = 3, Name = "CC", ParentId = 1},
        new CategoryModel{ Id = 4, Name = "DD", ParentId = 1},
        new CategoryModel{ Id = 5, Name = "EE", ParentId = 2},
        new CategoryModel{ Id = 6, Name = "FF", ParentId = 2},
    };

    return categories;
}

View:
<ul>
    @foreach (var item in Model.Categories)
    {
        @if (item.ParentId == null)
        {
            <li class="menu-item menu-item-submenu" data-menu-toggle="hover" aria-haspopup="true">
                <a asp-controller="Admin" asp-action="CategoryList" asp-route-category="@item.Name.ToLower()" class="menu-link @(Model.SelectedCategory==item.Name.ToLower()?"active":"")">
                    <span class="menu-text">@item.Name</span>
                    <i class="menu-arrow"></i>
                </a>
            </li>
        }

        foreach (var subitem in Model.Categories.Where(s => s.ParentId == item.Id))
        {
            <li class="menu-item menu-item-submenu" data-menu-toggle="hover" aria-haspopup="true">
                <a asp-controller="Admin" asp-action="CategoryList" asp-route-category="@subitem.Name.ToLower()" class="menu-link">
                    <span class="menu-text">@item.Name > @subitem.Name</span>
                    <i class="menu-arrow"></i>
                </a>
            </li>
        }

    }
</ul>


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x