How do i set "nav-item active" in Blazor? - c#

I'm building an application using Blazor & Bootstrap. I want to use a standard bootstrap navbar. I can't figure out how to add the "active" class to the <li> tag selected.
This is my code:
<div class="collapse navbar-collapse">
<ul class="navbar-nav">
<li class="nav-item">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">Home</NavLink>
</li>
<li class="nav-item">
<NavLink class="nav-link" href="/counter" Match="NavLinkMatch.All">Counter</NavLink>
</li>
<li class="nav-item">
<NavLink class="nav-link" href="/fetchdata" Match="NavLinkMatch.All">Fetch data</NavLink>
</li>
</ul>
</div>
The built in <NavLink> which is a blazor component changes the class for the <a/> automatically. But since i am using bootstrap navbar i need to add "active" to the class of the selected <li>.
This is how it should look like when the link is active:
<li class="nav-item active">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">Home</NavLink>
</li>

You could use the navigation manager:
<li class="nav-item #GetActive("", NavLinkMatch.All)">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">Home</NavLink>
</li>
#code {
[Inject]
NavigationManager NavigationManager { get; set; }
protected override void OnInitialized() => NavigationManager.LocationChanged += (s, e) => StateHasChanged();
bool IsActive(string href, NavLinkMatch navLinkMatch = NavLinkMatch.Prefix)
{
var relativePath = NavigationManager.ToBaseRelativePath(NavigationManager.Uri).ToLower();
return navLinkMatch == NavLinkMatch.All ? relativePath == href.ToLower() : relativePath.StartsWith(href.ToLower());
}
string GetActive(string href, NavLinkMatch navLinkMatch = NavLinkMatch.Prefix) => IsActive(href, navLinkMatch) ? "active" : "";
}

You should be able to use a custom template to achieve this:
<NavLink href="/myhref">
<Template>
<li class="#(context.isActive ? "active" : string.Empty)">
#context.content
</li>
</Template>
My link description
</NavLink>
Source

You can use the Bootstrap NavBar and Blazor's NavLink without having to add any additional code. The one caveat is that your "active" class will added to the <a> tag, as per Bootstrap's documentation, and not on the <li> tag.
From the Bootstrap 5.x docs (the initial example for navbar):
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
With that in mind, the Blazor NavLink component replaces the <a> tag:
<li class="nav-item">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
<hr />
</NavLink>
</li>
<li class="nav-item">
<NavLink class="nav-link" href="/Reporting" Match="NavLinkMatch.All">
Reporting
<hr />
</NavLink>
</li>
Finally, once this is in place, you can add your own CSS to further modify the appearance:
.nav-link > hr {
visibility: hidden;
color: white;
height: 2px;
margin-top: 4px;
margin-bottom: 0;
}
.nav-item .nav-link.active > hr {
visibility: visible;
filter: blur(1.5px);
}
No other code is needed.
In my example, a blurred line will appear under the active menu item, as seen below (note, additional HTML/CSS would be required to achieve the completed visual):

Related

Making an li active according query string value

I am programming a website with ASP.NET MVC using C#. I have ul li, with a few tabs, I want to get the query string and check the value, according to the query string value, I want to make a li active
<li class="nav-item">
<a class="nav-link #{Context.Request.Query["ordering"] == "newest" ? 'active' : ''}" href="~/products?CatId=#Context.Request.Query["CatId"]&ordering=newest" role="tab" aria-controls="newest" aria-selected="true">newest</a>
</li>
<li class="nav-item">
<a class="nav-link #{Context.Request.Query["ordering"] == "MostVisited" ? 'active' : ''}" href="~/products?CatId=#Context.Request.Query["CatId"]&ordering=MostVisited" role="tab" aria-controls="MostVisited" aria-selected="false">MostVisited</a>
</li>
<li class="nav-item">
<a class="nav-link #{Context.Request.Query["ordering"] == "Most-Rank" ? 'active' : ''}" href="~/products?CatId=#Context.Request.Query["CatId"]&ordering=Most-Rank" role="tab" aria-controls="Most-Rank" aria-selected="false">Most-Rank</a>
</li>
<li class="nav-item">
<a class="nav-link #{Context.Request.Query["ordering"] == "cheapest" ? 'active' : ''}" href="~/products?CatId=#Context.Request.Query["CatId"]&ordering=cheapest" role="tab" aria-controls="cheapest" aria-selected="false">cheapest</a>
</li>
but it doesn't work, what is the problem?
Can you try to replace #{Context.Request.Query["ordering"] == "MostVisited" ? 'active' : ''}" by #(Context.Request.Query["ordering"] == "MostVisited" ? 'active' : '')" ?
If it is Razor template, then the right syntax is #(expression), not #{expression}.
Regards

Bootstrap 4.5 Tab always opens page instead of tab content in Blazor

I'm new to Blazor and just made a new project using WASM, Bootstrap 4.5 and .NET 5. I'm trying to make a tab layout work but whenever I click my tabs, they attempt to navigate to a new page, rather than opening the associated tab content.
I am not quite sure what it is I'm doing wrong here, as looking at pages of examples shows I'm doing what the examples are doing (Although it's possible I've simply grown blind to my own code now.)
Here is the code that generates the tabs and their content from my GameDetails.razor page:
#if (_game != null)
{
<ul class="nav nav-pills nav-fill" role="tablist">
#foreach (Tuple<string, string> key in _parsedMappings.Keys)
{
<li class="nav-item">
<a class="nav-link #(_isFirstElem == true ? "active" : "")"
id="#key.Item2.Replace(" ", "")-tab"
data-toggle="tab"
href="##key.Item2.Replace(" ", "")"
role="tab"
aria-controls="#key.Item2.Replace(" ", "")"
aria-selected="#(_isFirstElem == true ? "true" : "false")">#key.Item1, #key.Item2</a>
</li>
_isFirstElem = false;
}
#if (_isFirstElem == false) _isFirstElem = true;
</ul>
<div class="tab-content" id="tabContent">
#foreach (KeyValuePair<Tuple<string, string>, List<Mapping>> pair in _parsedMappings)
{
<div class="tab-pane fade show #(_isFirstElem == true ? "active" : "")"
id="#pair.Key.Item2.Replace(" ", "")"
role="tabpanel"
aria-labelledby="#pair.Key.Item2.Replace(" ", "")-tab">
<ul class="list-group">
#foreach (Mapping mapping in pair.Value)
{
<li class="list-group-item">
<b>#mapping.FunctionName</b>: <i>#mapping.Key</i>
</li>
}
</ul>
</div>
_isFirstElem = false;
}
</div>
}
It produces this html:
<ul class="nav nav-pills nav-fill" role="tablist">
<li class="nav-item"><a class="nav-link active" id="Keyboard&Mouse-tab" data-toggle="tab" href="#Keyboard&Mouse" role="tab" aria-controls="Keyboard&Mouse" aria-selected="true">PC, Keyboard & Mouse</a>
</li>
<li class="nav-item"><a class="nav-link " id="NintendoSwitchJoycons-tab" data-toggle="tab" href="#NintendoSwitchJoycons" role="tab" aria-controls="NintendoSwitchJoycons" aria-selected="false">Nintendo Switch, Nintendo Switch Joycons</a>
</li>
</ul>
<div class="tab-content" id="tabContent">
<div class="tab-pane fade show active" id="Keyboard&Mouse" role="tabpanel" aria-labelledby="Keyboard&Mouse-tab">
<ul class="list-group">
<li class="list-group-item">...</li>
<li class="list-group-item">...</li>
...
</ul>
</div>
<div class="tab-pane fade show " id="NintendoSwitchJoycons" role="tabpanel" aria-labelledby="NintendoSwitchJoycons-tab">
<ul class="list-group">
<li class="list-group-item">...</i></li>
<li class="list-group-item">...</i></li>
...
</ul>
</div>
</div>
Which to my knowledge is correctly formatted. So I am not quite sure why the tab tries to navigate to a web page instead of opening the tab content.
What am I doing wrong?
Try to remove the "&" symbol from id="" attributes

ActionLink using Bootstrap 3 submenu not working, url not being called

bootstrap in C# submenus not being called, the url is shown in the bottom of the browser but when clicked nothing happens. What I am doing wrong?
<div class="navbar-collapse collapse dropdown">
<ul class="nav navbar-nav" role="menu">
<li role="menuitem">#Html.ActionLink("Contracts", "Index", "Contracts")</li>
<li class="dropdown-submenu" data-toggle="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
Configuration <b class="caret"></b></a>
<ul class="dropdown-menu" role="menu">
<li role="menuitem">#Html.ActionLink("Contract Type", "ContractType",
"Configuration")</li>
<li role="menuitem">#Html.ActionLink("Cost Type", "CostType",
"Configuration")</li>
</ul>
</li>
</ul>
</div>
check your ActionResult does it match with your .chtml page ActionLink
I upgraded to Bootstrap 4.1. Now it is OK
<ul class="navbar-nav mr-auto">
<li class="nav-item #Html.IfSelected("Proposals")">
<a class="nav-link" href="#Url.Action("Index", "Proposal")">Proposals</a>
</li>
<li class="nav-item #Html.IfSelected("Contracts")">
<a class="nav-link" href="#Url.Action("Index", "Contracts")">Contracts</a>
</li>
<li class="nav-item #Html.IfSelected("Reporting")">
<a class="nav-link" href="#Url.Action("Reporting", "Home")">Reporting</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="" id="navbarDropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
Configuration
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#Url.Action("Actions", "Configuration")">Actions</a>
<a class="dropdown-item" href="#Url.Action("ContractType", "Configuration")">Contract Type</a>
<a class="dropdown-item" href="#Url.Action("CostType", "Configuration")">Cost Type</a>
<a class="dropdown-item" href="#Url.Action("PendingOn", "Configuration")">Pending On</a>
<a class="dropdown-item" href="#Url.Action("Periods", "Configuration")">Periods</a>
<a class="dropdown-item" href="#Url.Action("Operators", "Configuration")">Operators</a>
<a class="dropdown-item" href="#Url.Action("SellerType", "Configuration")">Entity Type</a>
<a class="dropdown-item" href="#Url.Action("Status", "Configuration")">Status</a>
<a class="dropdown-item" href="#Url.Action("Result", "Configuration")">Results</a>
<a class="dropdown-item" href="#Url.Action("Vendors", "Configuration")">Vendors</a>
<a class="dropdown-item" href="#Url.Action("Users", "Configuration")">Users</a>
</div>
</li>
</ul>

Bootstrap 3 Tabs not applying the a href using URL.Action in Razor

I have some tabs in my Razor I have:
<div class="page-tabs">
<ul class="nav nav-tabs">
<li class='#(actionName.ToLower() == "viewsongamendments" &&
controllerName.ToLower() == "songmanagement" ? "active" : "")'>
Old Track Details
</li>
<li class='#(actionName.ToLower() == "updatedamendments" &&
controllerName.ToLower() == "songmanagement" ? "active" : "")'>
Updated Track Details
</li>
</ul>
But when looking in the source code, its not applying the ahref to the tab. Currently, this is showing:
<a data-container="body" data-toggle="tooltip" title="" data-original-title="Old Track Details">Old Track Details</a>
Bootstrap tabs work as below, please note how the hrefs match up from the nav element to the tabs in the tab-content element. The href is NOT a link to an action when used in this bootstrap context.
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#home">Home</a></li>
<li><a data-toggle="tab" href="#menu1">Menu 1</a></li>
<li><a data-toggle="tab" href="#menu2">Menu 2</a></li>
</ul>
<div class="tab-content">
<div id="home" class="tab-pane fade in active">
<h3>HOME</h3>
<p>Some content.</p>
</div>
<div id="menu1" class="tab-pane fade">
#Html.RenderAction("ViewSongAmendments", "SongManagement")
</div>
<div id="menu2" class="tab-pane fade">
<h3>Menu 2</h3>
<p>Some content in menu 2.</p>
</div>
</div>
I managed to get it working with the code below. I ended up adding a variable new { songid = fullAccountCode the fullAccountCode pulled a value from the Model.
<div class="page-tabs">
<ul class="nav nav-tabs">
<li class='#(actionName.ToLower() == "viewsongamendments" &&
controllerName.ToLower() == "songsmanagement" ? "active" : "")'>
Old Song Details
</li>
<li class='#(actionName.ToLower() == "updatedsongamendments" &&
controllerName.ToLower() == "songsmanagement" ? "active" : "")'>
Updated Song Details
</li>
</ul>

Asp.net core mvc -- Changing partial on user log in

I have a partial that looks like this:
#if (SignInManager.IsSignedIn(User))
{
<form asp-area="" asp-controller="Account" asp-action="Logout" method="post" id="logoutForm" class="navbar-right">
<ul class="nav navbar-nav navbar-right">
<li>
<a asp-area="" asp-controller="Manage" asp-action="Index" title="Manage">Hello #UserManager.GetUserName(User)!</a>
</li>
<li>
<button type="submit" class="btn btn-link navbar-btn navbar-link">Log out</button>
</li>
</ul>
</form>
}
else
{
<ul class="nav navbar-nav navbar-right">
<li><a asp-area="" asp-controller="Registrieren" asp-action="Create">Anmelden</a></li>
<li><a asp-area="" asp-controller="Login" asp-action="Details">Einloggen</a></li>
</ul>
}
Now i'm not using the SignInManager to handle the login. I'm using Microsoft.AspNetCore.Session with a cookie.
I would like to handle the condition when the partial is shown by code. Like so:
if(session == xx)
{
//show logged in part of partial
}
or even maybe something like
name = HttpContext.Session.GetString("nameKey");
if(name != "")
{
//show logged in part of partial
}
What's the easiest way to achieve this?

Categories

Resources