I want to show Components in a tabs , so first of all create few components. In this project we have three components,
First View Component
public class AllViewComponent : ViewComponent
{
private readonly UserManager<ApplicationUser> _userManager;
public AllViewComponent(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
public async Task<IViewComponentResult> InvokeAsync()
{
List<StudentViewModel> allUsers = new List<StudentViewModel>();
var items = await _userManager.Users.ToListAsync();
foreach (var item in items)
{
allUsers.Add(new StudentViewModel {Id=item.Id, EnrollmentNo = item.EnrollmentNo, FatherName = item.FatherName, Name = item.Name, Age = item.Age, Birthdate = item.Birthdate, Address = item.Address, Gender = item.Gender, Email = item.Email });
}
return View(allUsers);
}
}
Second View Component
public class StudentsViewComponent : ViewComponent
{
private readonly UserManager<ApplicationUser> _userManager;
public StudentsViewComponent(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
public async Task<IViewComponentResult> InvokeAsync()
{
List<StudentViewModel> students = new List<StudentViewModel>();
var items = await _userManager.GetUsersInRoleAsync("Student");
foreach (var item in items)
{
students.Add(new StudentViewModel {EnrollmentNo=item.EnrollmentNo,FatherName=item.FatherName, Name = item.Name, Age = item.Age, Birthdate = item.Birthdate, Address = item.Address, Gender = item.Gender, Email = item.Email });
}
return View(students);
}
}
Third View Component
public class TeacherViewComponent : ViewComponent
{
private readonly UserManager<ApplicationUser> _userManager;
public TeacherViewComponent(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
public async Task<IViewComponentResult> InvokeAsync()
{
List<TeacherViewModel> teachers = new List<TeacherViewModel>();
var items = await _userManager.GetUsersInRoleAsync("Teacher");
foreach (var item in items)
{
teachers.Add(new TeacherViewModel {FatherName=item.FatherName, Name = item.Name, Age = item.Age, Birthdate = item.Birthdate, Address = item.Address, Gender = item.Gender, Email = item.Email });
}
return View(teachers);
}
}
Under Shred Folder Create tree structured directory like this
/Shared/Components/All
/Shared/Components/Teacher
/Shared/Components/Students
Under All Directory , you can create a view which default name is "Default"
@model IEnumerable<StudentManagementSystem.ViewModels.StudentViewModel>
@{
ViewData["Title"] = "Default";
}
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.EnrollmentNo)
</th>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Age)
</th>
<th>
@Html.DisplayNameFor(model => model.Birthdate)
</th>
<th>
@Html.DisplayNameFor(model => model.Gender)
</th>
<th>
@Html.DisplayNameFor(model => model.Address)
</th>
<th>
@Html.DisplayNameFor(model => model.FatherName)
</th>
<th>
@Html.DisplayNameFor(model => model.Email)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.EnrollmentNo)
</td>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Age)
</td>
<td>
@Html.DisplayFor(modelItem => item.Birthdate)
</td>
<td>
@Html.DisplayFor(modelItem => item.Gender)
</td>
<td>
@Html.DisplayFor(modelItem => item.Address)
</td>
<td>
@Html.DisplayFor(modelItem => item.FatherName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Email)
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
<a asp-action="Details" asp-route-id="@item.Id">Details</a> |
<a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
Similarly you can create view to other two views.
Now, If you want to implements tabs view then create a ViewModel Class for tabs
namespace StudentManagementSystem.ViewModels
{
public class UsersTabViewModel
{
public Tab ActiveTab { get; set; }
}
public enum Tab
{
All,
Teachers,
Students
}
}
Now, You can use it in cshtml file like this
@model StudentManagementSystem.ViewModels.UsersTabViewModel
@{
ViewData["Title"] = "Index";
}
<h2>Users Table</h2>
<ul class="nav nav-tabs">
<li role="presentation" class="@(Model.ActiveTab == StudentManagementSystem.ViewModels.Tab.All ? "active" : string.Empty )"><a asp-route-tabname="All" asp-action="SwitchToTabs">All</a></li>
<li role="presentation" class="@(Model.ActiveTab == StudentManagementSystem.ViewModels.Tab.Teachers ? "active" : string.Empty )"><a asp-route-tabname="Teachers" asp-action="SwitchToTabs">Teachers</a></li>
<li role="presentation" class="@(Model.ActiveTab == StudentManagementSystem.ViewModels.Tab.Students ? "active" : string.Empty )"><a asp-route-tabname="Students" asp-action="SwitchToTabs">Students</a></li>
</ul>
@switch (Model.ActiveTab)
{
case StudentManagementSystem.ViewModels.Tab.All:
@await Component.InvokeAsync("All");
break;
case StudentManagementSystem.ViewModels.Tab.Teachers:
@await Component.InvokeAsync("Teacher");
break;
case StudentManagementSystem.ViewModels.Tab.Students:
@await Component.InvokeAsync("Students");
break;
default:
break;
}
Now, The controller section for each route value are
public IActionResult Index(UsersTabViewModel vm)
{
if (vm == null)
{
vm = new UsersTabViewModel
{
ActiveTab = Tab.All
};
}
return View(vm);
}
public IActionResult SwitchToTabs(string tabname)
{
var vm = new UsersTabViewModel();
switch (tabname)
{
case "All":
vm.ActiveTab = Tab.All;
break;
case "Teachers":
vm.ActiveTab = Tab.Teachers;
break;
case "Students":
vm.ActiveTab = Tab.Students;
break;
default:
vm.ActiveTab = Tab.All;
break;
}
return RedirectToAction(nameof(AdminController.Index), vm);
}