I'm looking for a way to implement "tab notification" in AngularJS, to indicate that there are alerts that need to be taken care of. Something like :
(1) (3)
TAB_ONE TAB_TWO TAB_THREE
Do you have any suggestions on how this can be done?
I will use a UI framework, like Bootstrap. Then I will have a controller that holds the counters for the badges.
(function() {
var app = angular.module("tabbadges",[]);
app.controller("badgesController", badgesController);
function badgesController($scope) {
$scope.badges = {
tab1: 4,
tab2: 6,
tab3: 2
};
}
})();
I will then create the html for the view
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link active" href="#">Tab one
<span class="badge badge-pill badge-primary">{{badges.tab1}}</span>
</a>
<li class="nav-item">
<a class="nav-link" href="#">Tab two
<span class="badge badge-light badge-primary">{{badges.tab2}}</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Tab three <span class="badge badge-light badge-primary">{{badges.tab3}}</span></a>
</li>
</ul>
[Codepen] (https://codepen.io/xaviguardia/pen/LYEybvZ)
Related
in my web project, I used a free theme https://themewagon.com/themes/free-bootstrap-4-html-5-admin-dashboard-website-template-skydash/
Here in the nav bar, I customized it as
<nav class="sidebar sidebar-offcanvas" id="sidebar">
<ul class="nav">
<li class="nav-item">
<a class="nav-link elements" href="~/Home/Index">
<i class="icon-grid menu-icon"></i>
<span class="menu-title">Dashboard</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action("Index","SelfService")">
<i class="ti-menu-alt menu-icon"></i>
<span class="menu-title">Our Services</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action("OnProcessTasks","SelfCareTasks")">
<i class="ti-timer menu-icon"></i>
<span class="menu-title">In Process Tasks</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action("CompletedTasks","SelfCareTasks")">
<i class="ti-file menu-icon"></i>
<span class="menu-title">Completed Tasks</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action("OnProcessTasks","SelfCareTasks")">
<i class="ti-face-smile menu-icon"></i>
<span class="menu-title">My Profile</span>
</a>
</li>
</ul>
</nav>
My issue is When I run this, on load first 2 items showed as Active and both items are highlighted. I checked with the sample, but it runs without this issue, also I tried removing the href and then the nav bar showed only one item as active.
I still couldn't figure out why this happening. Any comments?
I can't see what is wrong other than just this thing:
<a class="nav-link elements" href="~/Home/Index">
Change it to:
<a class="nav-link elements" href="#Url.Action("Index", "Home")">
The reason for this change is because you're following the Razor Syntax.
I am in the process of porting an old web form app to Blazor WASM.
The app is using a lot of JavaScript and I wonder how to best work with the DOM in Blazor.
Let's take this example:
<ul id="cii-tabmenu" class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link active" data-tabIndex="0" href="#">Mål og investeringspolitik</a>
</li>
<li class="nav-item">
<a class="nav-link" data-tabIndex="1" href="#">Risk-reward-profil</a>
</li>
<li class="nav-item">
<a class="nav-link" data-tabIndex="2" href="#">Gebyrer</a>
</li>
<li class="nav-item">
<a class="nav-link" data-tabIndex="3" href="#">Tidligere resultater</a>
</li>
<li class="nav-item">
<a class="nav-link" data-tabIndex="4" href="#">Praktiske oplysninger</a>
</li>
</ul>
We need the following to have a functional tab strip
A click handler that gets the tab clicked
Code that sets the Active class on the clicked tab and removed it on the previous tab.
I can easily add an onclick handler like #onClick="TabClicked(index)" but how can I set the active class and remove the one previously selected?
I know how to do it in JavaScript but now I work in Blazor and would like to use as little js as possible.
This is not the most elegant solution by a long shot but it should help you understand the blazor paradigm better:
<ul id="cii-tabmenu" class="nav nav-tabs">
<li class="nav-item">
<a class="#(myawesometab[0])" data-tabIndex="0" href="#" #onclick="#(e => myawesometabclick(e, 0))">Mål og investeringspolitik</a>
</li>
<li class="nav-item">
<a class="#(myawesometab[1])" data-tabIndex="1" href="#" #onclick="#(e => myawesometabclick(e, 1))">Risk-reward-profil</a>
</li>
<li class="nav-item">
<a class="#(myawesometab[2])" data-tabIndex="2" href="#" #onclick="#(e => myawesometabclick(e, 2))">Gebyrer</a>
</li>
<li class="nav-item">
<a class="#(myawesometab[3])" data-tabIndex="3" href="#" #onclick="#(e => myawesometabclick(e, 3))">Tidligere resultater</a>
</li>
<li class="nav-item">
<a class="#(myawesometab[4])" data-tabIndex="4" href="#" #onclick="#(e => myawesometabclick(e, 4))">Praktiske oplysninger</a>
</li>
</ul>
#code
{
private string[] myawesometab = new string[5] { "nav-link active", "nav-link", "nav-link", "nav-link", "nav-link" };
private void myawesometabclick(MouseEventArgs e, int myawesometabnumber)
{
for (int i = 0; i < 5; i++)
{
myawesometab[i] = "nav-link";
}
myawesometab[myawesometabnumber] = "nav-link active";
}
}
Also, as razor pages use a similar file structure to winforms, you might try to update the entire project to razor pages, although I obviously don't understand all the complexities of the project.
I am having some trouble with the tab list below:
<ul class="nav nav-tabs" data-tabs="tabs" role="tablist">
<li class="nav-item">
<a class="nav-link active" href="{$PageUrl}" role="tab">View</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{$PageUrl}?action=edit" role="tab">Edit</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{$PageUrl}?action=diff" role="tab">History</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{$PageUrl}?action=print" role="tab">Print</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{$PageUrl}?action=attr" role="tab">Attributes</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="dropdown2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu" aria-labelledby="dropdown2">
<a class="dropdown-item" data-toggle="tab" href="#fat2" role="tab">#fat</a>
<a class="dropdown-item" data-toggle="tab" href="#mdo2" role="tab">#mdo</a>
</div>
</li>
</ul>
Everything displays fine but this differs from how a lot of people implement tabs. Most examples i see have 'tab-content' and that shows the content for each tab. In my case i am using tabs to link alternate pages all together. This is where my issue comes in, When clicking on 'Edit' tab it does indeed load the edit page but with the active class or the 'View' tab still active. I cannot get the active class to switch between the tabs. I think this is because the page is reloading therefore eliminating the active data and setting it to default. How can I get around this and have it show the correct active tab after the newly selected page loads? Thanks for any help!
Edit:
Previously I was trying to use this at the bottom of my body with no luck:
$(function(){
var current = location.pathname;
$('#nav li a').each(function(){
var $this = $(this);
// if the current path is like this link, make it active
if($this.attr('href').indexOf(current) !== -1){
$this.addClass('active');
}
})
})
Here is a possible solution:
<ul class="nav nav-tabs" data-tabs="tabs" role="tablist">
<li class="nav-item">
<a class="default nav-link" href="{$PageUrl}" role="tab">View</a>
</li>
<li class="nav-item">
<a class="edit nav-link" href="{$PageUrl}?action=edit" role="tab">Edit</a>
</li>
<li class="nav-item">
<a class="diff nav-link" href="{$PageUrl}?action=diff" role="tab">History</a>
</li>
<li class="nav-item">
<a class="print nav-link" href="{$PageUrl}?action=print" role="tab">Print</a>
</li>
<li class="nav-item">
<a class="attr nav-link" href="{$PageUrl}?action=attr" role="tab">Attributes</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="dropdown2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu" aria-labelledby="dropdown2">
<a class="dropdown-item" data-toggle="tab" href="#fat2" role="tab">#fat</a>
<a class="dropdown-item" data-toggle="tab" href="#mdo2" role="tab">#mdo</a>
</div>
</li>
</ul>
<script>
$(function() {
var action = (location.search.match(/(\^?|&)action=(.*?)($|&)/i) || [])[2]
if(action) {
$('a.nav-link.'+action).addClass('active')
} else {
$('a.nav-link.default').addClass('active')
}
})
</script>
Does not add active class to any of the tabs by default.
All tab links have their action as class, to make it easy
On load it thecks the query in the window's address, and sets the active class accordingly
I have a navigation which can have up to two sub menus. Means, I have to open the li above (add class "open" to class "arrow") two times if the current page is a href in a sub sub navigation.
However, I am struggling on how to do this, how to solve this problem. My idea was to solve it via jQuery. Is there a better solution?
This is my navigation:
<ul class="page-sidebar-menu page-header-fixed page-sidebar-menu-light">
<li class="nav-item start">
<a href="my-domain.com/dashboard" class="nav-link nav-toggle">
<i class="icon-home"></i>
<span class="title">Dashboard</span>
<span class="selected"></span>
</a>
</li>
<li class="nav-item">
<a href="javascript:void(0)" class="nav-link nav-toggle">
<i class="icon-people"></i>
<span class="title">Kontakte</span>
<span class="arrow"></span>
</a>
<ul class="sub-menu">
<li class="nav-item">
<a href="my-domain.com/kontaktverwaltung" class="nav-link ">
<span class="title">Kontaktverwaltung</span>
<span class="selected"></span>
</a>
</li>
<li class="nav-item">
<a href="javascript:void(0)" class="nav-link nav-toggle">
<span class="title">Kunden</span>
<span class="arrow"></span>
</a>
<ul class="sub-menu">
<li class="nav-item ">
Kundendetails
<span class="selected"></span>
</li>
<li class="nav-item">
Kundenverwaltung
<span class="selected"></span>
</li>
</ul>
</li>
</ul>
</li>
</ul>
Example:
The current page is this one: my-domain.com/kundenverwaltung. That means, I have to add the class "active open" to both li elements of the ul sub menus as well as the class "open" to the class "arrow" of the li elements.
This is how it should be:
<ul class="page-sidebar-menu page-header-fixed page-sidebar-menu-light">
<li class="nav-item start">
<a href="my-domain.com/dashboard" class="nav-link nav-toggle">
<i class="icon-home"></i>
<span class="title">Dashboard</span>
</a>
</li>
<li class="nav-item **active open**">
<a href="javascript:void(0)" class="nav-link nav-toggle">
<i class="icon-people"></i>
<span class="title">Kontakte</span>
<span class="arrow **open**"></span>
</a>
<ul class="sub-menu">
<li class="nav-item">
<a href="my-domain.com/kontaktverwaltung" class="nav-link ">
<span class="title">Kontaktverwaltung</span>
</a>
</li>
<li class="nav-item **active open**">
<a href="javascript:void(0)" class="nav-link nav-toggle">
<span class="title">Kunden</span>
<span class="arrow **open**"></span>
</a>
<ul class="sub-menu">
<li class="nav-item ">
Kundendetails
</li>
<li class="nav-item">
Kundenverwaltung
</li>
</ul>
</li>
</ul>
</li>
</ul>
I have marked the changes on the classes with ** before and after the class name. This is my jQuery so far:
<script>
$("a.nav-link").each(function(index){
if($(this).attr("href") == window.location.href) {
$(this).parent().addClass("active open");
if ($(this).parent().parent().is("ul")) {
$(this).parent().parent().parent().addClass("active open");
var li = $(this).parent().parent().parent();
$(li[0].nodeName + " .arrow").addClass("open");
}
}
});
</script>
However, I don't think this is the best solution.. is there any better way? Kind regards
If you change the structure of HTML, your code will not be work, so - don't use parent(), try to use closest() https://api.jquery.com/closest, by reason that the closest() is a more reliable method
Cache data. U can use
http://api.jquery.com/attribute-equals-selector:
var $a = jQuery('a[href*="' + window.location.href + '"]');
$a.addClass("active open");
For adding a class to active page you should try added this by backend side, different kind of templating - can do it. But your approach also can be use
I'm using a bootstrap template for a side navbar as a partial in EJS which is then included on all pages that use it. Is was taken from their Dashboard template. The HTML is
<nav class="col-sm-3 col-md-2 hidden-xs-down bg-faded sidebar">
<ul class="nav nav-pills flex-column">
<li class="nav-item">
<a class="nav-link active" href="/profile">Overview</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/accountdetails">Account Details</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/admin">Admin</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/transactions">Transactions</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/contract">Contract</a>
</li>
</ul>
</nav>
Whichever link has the active class has particular styling with darker blue in the background. I now want to change this programatically when navigating to the different links.
They're all going to different pages so I could just change there the issue is that I'm including the whole sidebar code as an EJS partial so that wouldn't work. I also tried this answer but it didn't work (flashes the active styling but disappears - probably because it is routing to another page?).
There are plenty of questions here about changing an HTML element programatically but they usually use document.getElementById which seems like too much work (giving each an ID, checking all, etc). Is there a quicker / correct way of doing this?
You could do the following:
Set a click event on .nav-item, to add .active class.
Remove .active class from any other sibling element.
$('.nav-item').on('click', function() {
$(this).addClass('active').siblings('li').removeClass('active');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<nav class="col-sm-3 col-md-2 hidden-xs-down bg-faded sidebar">
<ul class="nav nav-pills flex-column">
<li class="nav-item active">
<a class="nav-link" href="#">Overview</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Account Details</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Admin</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Transactions</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contract</a>
</li>
</ul>
</nav>
Some people answering are a bit confused, thinking you are staying on the same page, and changing the class of your <a> tags. But I think your clicks on these navigate to new pages, and you want the appropriate <a> to have class active when the page loads.
This might help:
<script>
var path = location.pathname; // ex: '/profile';
var activeItem = document.querySelector("a[href='" + path + "']");
activeItem.class += ' active';
</script>
And of course with jquery it's even easier:
$(function() {
var path = location.pathname;
$("a[href='" + path + "']").addClass('active');
})
This is a code for helping you.
<nav class="col-sm-3 col-md-2 hidden-xs-down bg-faded sidebar">
<ul class="nav nav-pills flex-column">
<li class="nav-item">
<a class="nav-link active" href="#">Overview</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Account Details</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Admin</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Transactions</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contract</a>
</li>
</ul>
</nav>
<script type="text/javascript">
$(function () {
$(".nav-item").click(function () {
$(".nav-item").each(function () {
$(this).find("a").removeClass("active");
});
$(this).find("a").addClass("active");
});
});
</script>
If your using EJS you can probably do something like the following
<a class="nav-link<% if (page_name === 'profile') { %> active<% } %>" href="/profile">Overview</a>
This is untested but should get you going on the right path. Just do a if statement using EJS's syntax to check if you are on the correct page and add the word active.