setting active class in c#.net masterpage - c#

<div id="navigation">
<ul class="nav nav-pills">
<li role="presentation">Home</li>
<li role="presentation">Open Account</li>
<li role="presentation">ATM</li>
<li role="presentation">Branch Locator</li>
<li role="presentation">Contact US</li>
</ul>
</div>
I want to set active class in li tag based on the visited link, I have tried several answers from Stackoverflow but none seems to me working.
For your information, I am using Bootstrap, C#, Visual Studio for my development.

Your elements should look like (in master.page):
<li role="presentation" id="liDefault" runat="server">Home</li>
public String linkDefault
{
get
{
return "not_active";
}
set
{
liDefault.Attributes.Add("class", "" + value + "");
}
}
Then add following to your head part of content page:
<%# MasterType VirtualPath="~/MasterPage.master" %>
And code behind of your content page:
this.Master.linkDefault = "active";

You can achieve it using Jquery.
First set single class on all anchor tags in you li tags i.e:
<div id="navigation">
<ul class="nav nav-pills">
<li role="presentation">Home</li>
<li role="presentation">Open Account</li>
<li role="presentation">ATM</li>
<li role="presentation">Branch Locator</li>
<li role="presentation">Contact US</li>
</ul>
</div>
Now in jquery you have to check if any anchor tag is clicked so an "active" class will be set to its parent li tag. i.e.:
$(".link").click(function(){
$(this).parent().addClass("active");
})
Hope its works.

Related

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

Change color of navbar list item text in _Layout.cshtml when page is selected by user

I am using a bootstrap navbar in my _Layout.cshtml.
On my Index page, the list item "Home" shows as color: rgba(255, 140, 0, 0.781) and the "Features" list item shows as color: green
Desired Result: When I click the "Features" link and navigate to the Features.cshtml page, I want the "Features" list item to change color to color: rgba(255, 140, 0, 0.781) and the Home item to change to color: green.
This is easy to do if I put the navbar markup into every cshtml page. But I would like to just have my bootstrap navbar once in my _Layout.cshtml page.
_Layout.cshtml
<nav class="navbar navbar-expand-lg navbar-light">
<div class="container">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" style="color: rgba(255, 140, 0, 0.781)" asp-page="Index")>#_loc["Home"]</a>
</li>
<li class="nav-item active">
<a class="nav-link" style="color: green" asp-page="Features" localize-content>#_loc["Features"]</a>
</li>
<partial name="_LoginPartial" />
</ul>
</div>
</div>
</nav>
I have this working fine by putting the HTML for the menu bar in every page, but that is not a good solution as I will have to separately maintain a number of instances of my menu bar.
I tried a number of stackoverflow items but didn't find one that worked for this case. Such as set Different colors in asp:DropDownList Items
I tried following the MSDocs for the ForeColor property but couldn't achieve this either.
I have also tried using [ViewData] set in my Index.cshtml.cs but still couldn't figure out how to change the color on page load or when navigating to the Features page.
I have also tried adding # code directly to my _Layout page, such as #if(this.Page = "Index") and #if(System.IO.Directory.GetCurrentDirectory = "Index") but no joy.
Change colour of the navbar element corresponding to the active page
I've had success using a custom tag helper for this, using some code inspirited from here.
The Microsoft doc on creating tag helpers is available here. Third party tutorial available here.
The tag helper will let us specify the action that corresponds to each navbar item, then when the page is being built on the server we will add the active class to the corresponding item.
<ul class="navbar-nav flex-grow-1">
<li navigation-active-for="/Index" class="nav-item">
<a class="nav-link" asp-area="" asp-page="/Index">Home</a>
</li>
<li navigation-active-for="/Privacy" class="nav-item">
<a class="nav-link" asp-area="" asp-page="/Privacy">Privacy</a>
</li>
<li navigation-active-for="/Movies/Index" class="nav-item">
<a class="nav-link" asp-area="" asp-page="/Movies/Index">Movies</a>
</li>
</ul>
In this case, the navigation-active-for attribute will be used.
The tag helper will be as follows
(in my case, the project is called Emotify)
using System;
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.TagHelpers;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.AspNetCore.Routing;
namespace Emotify.TagHelpers
{
[HtmlTargetElement("li", Attributes = _for)]
public class ActiveItemTagHelper : TagHelper
{
private readonly IUrlHelper _urlHelper;
private readonly IHttpContextAccessor _httpAccess;
private readonly LinkGenerator _linkGenerator;
private const string _for = "navigation-active-for";
public ActiveItemTagHelper(
IActionContextAccessor actionAccess,
IUrlHelperFactory factory,
IHttpContextAccessor httpAccess,
LinkGenerator generator
)
{
_urlHelper = factory.GetUrlHelper(actionAccess.ActionContext);
_httpAccess = httpAccess;
_linkGenerator = generator;
}
public override void Process(TagHelperContext context, TagHelperOutput output)
{
// grab attribute value
var targetPage = output.Attributes[_for].Value.ToString();
// remove from html so user doesn't see it
output.Attributes.Remove(output.Attributes[_for]);
// get the URI that corresponds to the attribute value
var targetUri = _linkGenerator.GetUriByPage(_httpAccess.HttpContext, page: targetPage);
// get the URI that corresponds to the current page's action
var currentUri = _urlHelper.ActionLink();
// if they match, then add the "active" CSS class
if (targetUri == currentUri) {
output.AddClass("active", HtmlEncoder.Default);
}
}
}
}
The services used in the constructor from dependency injection must be registered in Startup.cs::ConfigureServices.
ref ref
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
Important: in order to work the tag helper must be registered, like in _ViewImports.cshtml.
#using Emotify
#addTagHelper *, Emotify
Note that this ISNT #addTagHelper *, Emotify.TagHelpers since that's wrong apparently, doesn't work. I'm not sure how namespace nesting works in C#.
Additional notes
dependency injection
I'm very new to C# and Razor, so this may not follow best practices
Desired Result: When I click the "Features" link and navigate to the Features.cshtml page, I want the "Features" list item to change color to color: rgba(255, 140, 0, 0.781) and the Home item to change to color: green.
If you'd like to dynamically set color for active item, you can store active page name in localStorage, then you can retrieve the stored data and dynamically set custom class for specific element to apply expected color to it in _Layout page, like below.
Html
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active" onclick="changeactive('Home')">
<a class="nav-link" asp-page="Index" )>#_loc["Home"]</a>
</li>
<li class="nav-item active" onclick="changeactive('Features')">
<a class="nav-link" asp-page="Features" localize-content>#_loc["Features"]</a>
</li>
<partial name="_LoginPartial" />
</ul>
</div>
JS code
<script>
function changeactive(pname) {
//console.log(pname);
localStorage.setItem("activepage", pname);
}
$(function () {
var pname = localStorage.getItem("activepage");
if (pname == "Home" || pname == "" || pname == null) {
$("ul.navbar-nav li.nav-item:nth-child(1) a").addClass("active-item");
$("ul.navbar-nav li.nav-item:nth-child(2) a").addClass("normal-item");
} else {
$("ul.navbar-nav li.nav-item:nth-child(1) a").addClass("normal-item");
$("ul.navbar-nav li.nav-item:nth-child(2) a").addClass("active-item");
}
})
</script>
CSS class
<style>
.active-item {
color: green !important;
}
.normal-item {
color: rgba(255, 140, 0, 0.781) !important;
}
</style>
Test Result

Displaying dropdown of links with query builder

I am trying to create a dropdown in Umbraco 7, using the query builder. The dropdown is part of a navbar, which contains links to other pages as well. The page contains HTML with Razor code.
#{
var selection = Model.Content.Site().FirstChild("Sprog").Children()
.Where(x => x.IsVisible());
}
<ul class="sf-menu well" data-type="navbar">
#foreach(var item in selection){
if(item.Name == "Sommerhuse") {
<li>
Sommerhuse
#{
var selection2 = Umbraco.TypedContent(1090).Children()
.Where(x => x.IsVisible());
}
<ul>
#foreach(var sommerhus in selection2){
<li>
#sommerhus.Name
</li>
}
</ul>
</li>
} else {
<li>
#item.Name
</li>
}
}
</ul>
I tried nesting another query builder with the content I need for the dropdown into my navbar query builder and iterating through that
But this still doesn't create the dropdown. Instead it just returns a static link, where the dropdown should be shown. In my HTML prototype, the dropdown works fine using this code.
<nav class="nav pull-right">
<ul class="sf-menu well" data-type="navbar">
<li class="active">
Forside
</li>
<li>
Lejebetingelser
</li>
<li>
Sommerhuse
<ul>
<li>
Blokhus
</li>
<li>
Hvide Sande
</li>
<li>
Langeland
</li>
<li>
Marielyst
</li>
<li>
Ebeltoft
</li>
<li>
Rørvig
</li>
<li>
Bogense
</li>
</ul>
</li>
<li class="">
Kontakt
</li>
<li>
</li>
</ul>
</nav>
Apologies for the bad formatting, for some reason Visual Studio refuses to auto-format .cshtml files.
You don't have the <nav class="nav pull-right"> in your razor script.
Tip: do not compare on the name of a page because this will break your dropdown if the content editor changes the node name.
if(item.Name == "Sommerhuse") { // BAD IDEA
rather use the documentTypeAlias (if it is another document type)
if(item.DocumentTypeAlias == "aliasOfTheDocumentType") { // much safer
That will only work if the page has a special document type of course.

How to add active style using bootstrap

good day, i'm trying to add an active style to indicate current page on my web app bt couldn't get a solution, i looked at previous post and answers where i saw this which was said to have worked
<ul class="nav">
<li><a data-target="#" data-toggle="pill" href="#accounts">Accounts</a></li>
<li><a data-target="#" data-toggle="pill" href="#users">Users</a></li><br/>
</ul>
when i used the data-toggle attribute in this code
<ul class="nav nav-tabs">
<li class="colour">#Html.ActionLink("Staffs", "addStaff", "SchlAdmin")</li>
<li class="colour" data-toggle="tab">#Html.ActionLink("Students", "addStudent", "SchlAdmin")</li>
<li class="colour">#Html.ActionLink("Incidents", "staffInc", "SchlAdmin")</li>
<li class="colour" data-toggle="tab">#Html.ActionLink("Admin", "addasset", "SchlAdmin")</li>
<li class="colour">#Html.ActionLink("Search", "staffSearch", "SchlAdmin")</li>
<li class="colour" data-toggle="tab">#Html.ActionLink("Profile", "prof", "SchlAdmin")</li>
</ul>
i couldn't redirect to the page that has the data-toggle attribute but made that page active.
I have already made the same issue. Please see my Code and I think it helps you, if you have some question I'm ready to answer you.
View:
<ul class="nav nav-tabs" id="myTab">
<li id="activeTab" class="active"><a data-toggle="tab" href="#active">Active</a></li>
<li id="currentTab" class=""><a data-toggle="tab" href="#current">Current</a></li>
<li id="completedTab" class=""><a data-toggle="tab" href="#completed">Completed</a></li>
</ul>
<div class="tab-content" id="myTabContent">
<div id="active" class="tab-pane fade active in">
#Html.Action("Active", "Home")
</div>
<div id="current" class="tab-pane fade">
#Html.Action("Current", "Home")
</div>
<div id="completed" class="tab-pane fade in">
#Html.Action("Completed","Home")
</div>
</div>
JavaScript - when need to catch Active tab from URL and make it open
$(document).ready(function() {
var tab = #ViewBag.tabId;
switch (tab) {
case 1:
removeAllActiveTabs();
$('#activeTab').addClass('active');
$('#active').addClass('active');
$('#active').addClass('in');
break;
case 2:
removeAllActiveTabs();
$('#currentTab').addClass('active');
$('#current').addClass('active');
$('#current').addClass('in');
break;
case 3:
removeAllActiveTabs();
$('#completedTab').addClass('active');
$('#completed').addClass('active');
$('#completed').addClass('in');
break;
default:
$('#activeTab').addClass('active');
$('#active').addClass('active');
$('#active').addClass('in');
break;
}
});
function removeAllActiveTabs() {
$('#myTab').each(function() {
$(this).find('li').removeClass('active');
});
$('#myTabContent').each(function() {
$(this).find('div').removeClass('active');
$(this).find('div').removeClass('in');
});
}
JavaScript - If you want to change URL when tab change
//When Client click on Tabs show in URL
$('#activeTab').on('click',function() {
window.history.pushState('','','/Home/SomeAction?tabId=1');
});
$('#currentTab').on('click',function() {
window.history.pushState('','','/Home/SomeAction?tabId=2');
});
$('#completedTab').on('click',function() {
window.history.pushState('','','/Home/SomeAction?tabId=3');
});
You need to add a classname active to your li.
Example:
<li class="active"><a data-target="#" data-toggle="pill" href="#users">Users</a></li>

MVC PagedList first page with no querystring

I m using the TroyGoode MVC PagedList https://github.com/TroyGoode/PagedList
Working great except that i have duplicated content on the first page
#Html.PagedListPager((IPagedList)ViewData.Model.EnumerableAds, page => Url.Action("MyPage", "Home", new { page }))
Which gave me the HTML output :
<div class="pagination-container">
<ul class="pagination">
<li class="PagedList-skipToPrevious">«</li>
<li>1</li>
<li class="active"><a>2</a></li>
<li>3</li>
<li class="PagedList-skipToNext">»</li>
</ul>
</div>
I want to remplace :
<li class="PagedList-skipToPrevious">«</li>
<li>1</li>
by
<li class="PagedList-skipToPrevious">«</li>
<li>1</li>
Is it possible?
Like #Br4d suggested, here is the code that would accomplish this
public ActionResult MyPage(int? page=1)
{
your code here
}
Now you can send a null for the first page and it will default to page 1.

Categories

Resources