I am a student and quite new to ASP.NET MVC and I come from ASP.NET Web Form. (Used to it)
I got a list :
<ul class="sidebar bg-grayDark">
<li class="active">
<a href="@Url.Action("Index", "Home")">
<span class="mif-home icon"></span>
<span class="title">Home</span>
</a>
</li>
<li class="bg-hover-black">
<a href="@Url.Action("Index", "Product")">
<span class="mif-shop icon"></span>
<span class="title">Products</span>
<span class="counter">14</span>
</a>
</li>
<li class="bg-hover-black">
<a href="@Url.Action("Index", "Category")">
<span class="mif-flow-cascade icon"></span>
<span class="title">Categories</span>
<span class="counter">9</span>
</a>
</li>
<li class="bg-hover-black">
<a href="@Url.Action("Index", "User")">
<span class="mif-users icon"></span>
<span class="title">Users</span>
<span class="counter">1</span>
</a>
</li>
</ul>
My goal : By which view is rendered, I want to add "active" to the that has been clicked on. Example : I click on "Category", then Home loses his active class and Category has "active" added to his class. (and the reverse thing with "bg-hover-black")
I thought I could do it by checking the view actually rendered but I don't know how to do it. (I don't know how to check the actual view rendered, but using Razor to check conditions is okay)
I tried with JavaScript first :
$(function () {
$('.sidebar').on('click', 'li', function () {
if (!$(this).hasClass('active')) {
$('.sidebar li').removeClass('active');
$(this).addClass('active');
}
})
})
But it doesn't work because when the page loads, the html is re-rendered with "active" for the Home part. (If I remove "active" for Home, then nothing will be active onClick, except between click and page load).
Have you any solution ? I searched a lot on the web but found nothing to help me.
Sorry for any english mistakes, I'm still learning it :).
Thanks,
Hellcat8.
Since you are using the convention where your page is named after the controller you can do this in razor to get the controller/page name:
@{
var pageName = ViewContext.RouteData.Values["controller"].ToString();
}
<ul class="sidebar bg-grayDark">
<li class="@(pageName == "Home" ? "active" : "")">
<a href="@Url.Action("Index", "Home")">
<span class="mif-home icon"></span>
<span class="title">Home</span>
</a>
</li>
<li class="bg-hover-black @(pageName == "Product" ? "active" : "")">
<a href="@Url.Action("Index", "Product")">
<span class="mif-shop icon"></span>
<span class="title">Products</span>
<span class="counter">14</span>
</a>
</li>
<li class="bg-hover-black @(pageName == "Category" ? "active" : "")">
<a href="@Url.Action("Index", "Category")">
<span class="mif-flow-cascade icon"></span>
<span class="title">Categories</span>
<span class="counter">9</span>
</a>
</li>
<li class="bg-hover-black @(pageName == "User" ? "active" : "")">
<a href="@Url.Action("Index", "User")">
<span class="mif-users icon"></span>
<span class="title">Users</span>
<span class="counter">1</span>
</a>
</li>
</ul>
This will set your active class on the page server side removing the need to do this client side with javascript.
Here is my approach for a cascaded Bootstrap dropdown submenu, decorated with active classes in the _layout.cshtml file of a Razor Pages project.
Major elements of this solution:
ViewContext.RouteData.Values["page"].@Url.Action().Code:
<ul class="nav navbar-nav">
@{
String pageRoute = ViewContext.RouteData.Values["page"].ToString();
}
<li class="dropdown @( pageRoute.Contains("/CustomerModel/") ? "active" : "" )">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Customer-Model <span class="caret"></span></a>
<ul class="dropdown-menu">
<li class="@( pageRoute.Contains("/Customers/") ? "active" : "" )"><a asp-page="/CustomerModel/Customers/Index">Customers</a></li>
<li class="@( pageRoute.Contains("/Partners/") ? "active" : "" )"><a asp-page="/CustomerModel/CustomerPermissions/Index">CustomerPermissions</a></li>
</ul>
</li>
<li class="dropdown @( pageRoute.Contains("/StaffModel/") ? "active" : "" )">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Staff-Model <span class="caret"></span></a>
<ul class="dropdown-menu">
<li class="@( pageRoute.Contains("/Staff/") ? "active" : "" )"><a asp-page="/StaffModel/Staff/Index">Staff</a></li>
<li class="@( pageRoute.Contains("/StaffGroups/") ? "active" : "" )"><a asp-page="/StaffModel/StaffGroups/Index">StaffGroups</a></li>
<li class="@( pageRoute.Contains("/PermissionsGroups/") ? "active" : "" )"><a asp-page="/StaffModel/PermissionsGroups/Index">PermissionsGroups</a></li>
<li class="@( pageRoute.Contains("/AllowedModules/") ? "active" : "" )"><a asp-page="/StaffModel/AllowedModules/Index">AllowedModules</a></li>
<li class="@( pageRoute.Contains("/AllowedServices/") ? "active" : "" )"><a asp-page="/StaffModel/AllowedServices/Index">AllowedServices</a></li>
</ul>
</li>
</ul>
To get the name of the active action or controller use the following
var controllerName = ViewContext.RouteData.Values["controller"].ToString();
var actionName = ViewContext.RouteData.Values["action"].ToString();
and then you can give the class for a li using the following code:
<li class="@(actionName == "HomePage" ? "active":"")"><a href="~/Account/HomePage">Home</a></li>
or you can check both of them as following:
<li class="@(controllerName =="Account" && actionName == "HomePage" ? "active":"")"><a href="~/Account/HomePage">Home</a></li>