Active class nav item based on retrieved url portion - javascript

I would like to add a css class (.active) on the appropriate navigation link.
My navigation:
<nav>
<ul>
<li id="Thuispagina">Thuispagina</li>
<li id="Nieuws">Nieuws</li>
<li id="Skirms">Skirms</li>
<li id="Reservatie">Reservatie</li>
<li id="Fotogalerij">Fotogalerij</li>
<li id="Contact">Contact</li>
<li id="Forum">Forum</li>
</ul>
</nav>
If I would be on one of the following pages: domain.com/airsoft-contact/index.php, domain.com/airsoft-contact/edit.php or domain.com/airsoft-contact/delete.php it should add the active class to the li item with id Contact
If I would be on one of the following pages: domain.com/airsoft-fotogalerij/index.php, domain.com/airsoft-fotogalerij/edit.php or domain.com/airsoft-fotogalerij/delete.php it should add the active class to the li item with id Fotogalerij
On the other hand there is one exception: the index.php page is not in any submap so the logic should make an exception there.

Well the better or simple way is using jquery but u can do it with php too using a condition example class="<?php if ($_SERVER['PHP_SELF']=="ur script name"){ echo "active";}?>" or u can use ternary operator for better views so this is a way, u can find others

The easiest way to implement this (if you aren't an expert user) is to add in the navigation element a js like this for every link
if(window.location.href == "yourlink"){
document.getElementById("elementid").class = "active";
}
Another way can be something like:
var links = [ new Link("yoururl1", "yourelement1"), new Link("yoururl2", "yourelement2"), new Link("yoururl3", "yourelement3")];
for(link in links){
if(link.url == window.location.href){
document.getElementById(link.elementid).class = "active";
}
}
function Link (url, elementid){
this.url = url;
this.elementid = elementid;
}

Related

Toggling class based on click of link

I have a navbar like this:
Here is the relevant navbar HTML:
<div class = "navbar">
<a class = "active" href ="{% url 'keiji-home' %}">home</a>
<a href ="#" onclick = "makeActiveLink('communities-tag')"
id="communities-tag">
communities
</a>
feeling lucky
about
<div class = "navbar--right">
login/signup
</div>
</div>
I want to have the red background (class = "active") on the link (such as "home","communities","feeling lucky",...) when I am on that page. Ie: when on "about", the red background would be on about.
I am new to JS: here is my attempt so far from looking at other questions:
function makeActiveLink(id)
{
var selectedLink = document.getElementById(id);
selectedLink.classList.className += "active";
}
Then on the link, for example "communities":
<a href ="#" onclick = "makeActiveLink('communities-tag')"
id="communities-tag">
However, this is not correct.
Furthermore, I would like the "active" class to be removed from the previous link, ie when going from "home" to "about", the class should be removed from "home" and put on "about".
Not sure if this helps, but I am using Django (again new to that) to run this site.
This is what you are possibly trying to achieve:
function makeActiveLink(obj)
{
var links = document.getElementsByName("nav");
links.forEach(function(item) { item.classList.remove("active"); }
obj.classList.add("active");
}
And then in html:
home
communities
...
selectedLink.classList.className += "active"; delete "+"
And for the link "Home", made a name class="active done" and in the css, add .done {background: ...(your color)} and change the class with JS in your funtion.
I hope it's clear for you.
element.classList.className is invalid since they are different things.
This code should do the trick:
function makeActiveLink(id) {
//Remove 'active' from old link
var oldLink = document.getElementByClassName("active")[0];
oldLink.classList.remove("active");
//Add 'active' to new link
var selectedLink = document.getElementById(id);
selectedLink.classList.add("active");
}
getElementByClassName() searches for elements containing a certain class and returns a collection of elements, hence the [0] at the end.
Beware this does mean you can't use the active class anywhere else on the page. If this is an issue, consider renaming it to something like active-nav.
As a side-note, consider including all your code (including html) in a snippet to make it easier to help.
simply:
<div class="navbar">
<a class="active" href="{% url 'keiji-home' %}">home</a>
<a href="#" > communities </a>
feeling lucky
about
<div class="navbar--right"> login/signup
</div>
document.querySelectorAll('div.navbar > a').forEach((lnk,_,A)=>
{
lnk.onclick=_=>A.forEach(a=>a.classList.toggle('active',(a===lnk)))
})

How to find the class of element in a each loop

I am trying to create a menu system where I can change the style of the active page item in the menu. I am using a separate body class on each page, then I want to cycle through the li in the menu and find a match to the body class. At that match I will add the new styling to that menu item.
Here is my code so far.
HTML
<body class="home-state">
...
<div class="menu-left">
<ul>
<li class="home-state">
Home
</li>
<li class="work-state">
Work
</li>
<li class="services-state">
Services
</li>
<li class="about-state">
About
</li>
<li class="blog-state">
Blog
</li>
<li class="shop-state">
Shop
</li>
<li class="contact-state">
<a data-toggle="modal" href="#modal-coworking">Contact</a>
</li>
<li class="project-state">
Project brief
</li>
</ul>
</div>
...
</body>
JS
var bodyClass = $("body").attr('class');
$('.menu-left ul li').each(function(){
First: I want to find the element's class here I have used $(this).attr("class"); which didn't work
var element = $(this);
Second: I want to use a if statement to check to see if the class matches the bodyClass
console.log(element);
Last: If there is a match I want to add the class .active to the element li.
});
Given that elements can have multiple classes, I'd suggesting changing your body element to use a data- attribute rather than a class to specify what the current page is:
<body data-current="home-state">
Then the JS needed to add the active class to the relevant menu item is simple:
$("li." + $("body").attr("data-current")).addClass("active")
You don't need to loop over the menu items comparing classes as mentioned in the question, because you can just directly select the required li element based on its class.
In the event that the body element doesn't have a data-current attribute then $("body").attr("data-current") would return undefined, which would mean the code above tries to select an element with $("li.undefined") and add a class to it. Probably you have no elements with such a class so that would be harmless, but if you wanted to explicitly test that the data-current attribute exists:
var current = $("body").attr("data-current")
if (current) {
$("li." + current).addClass("active")
}
You can do this in couple ways, here is the simple way to do this;
var bodyClass = $("body").attr('class');
$("li." + bodyClass).addClass("active")
You can also use a loop for this one;
var bodyClass = $("body").attr('class');
$(".menu-left li").each(function(i, classes) {
if (bodyClass === $(this).attr("class")) {
$(this).addClass("active")
}
})
both will do the job.
enter image description here
enter image description here
as the comment said,the element can have more than one class ,so you should check it one by one
You missed to bind the click event for the menu item. Follow like below
var bodyClass = $("body").attr('class');
$('.menu-left ul li').on( "click", function() {
var myClass = $(this).attr("class");
alert(myClass);
});
Tested: https://codepen.io/anon/pen/XzYjGY

Set menu item active based on URL

I've been trying really hard to accomplish what I'm trying to accomplish, but I can't get it to work the way I want. I have a navigation menu with first-level menu items (duh) and second-level menu items. It looks like this:
<ul class="nav" id="side-menu">
<li>
Dashboard
</li>
<li>
Pages
</li>
<li>
Users<span class="fa arrow"></span>
<ul class="nav nav-second-level">
<li>
All users
</li>
<li>
Roles
</li>
</ul>
</li>
</ul>
I'm using the following jQuery function to add the active class to active menu items:
function setActive() {
var url = window.location;
var element = $('ul.nav a').filter(function() {
return this.href == url || url.href.indexOf(this.href) == 0;
}).addClass('active').parent().parent().addClass('in').parent();
if (element.is('li')) {
element.addClass('active');
}
// Remove active class from A element if the page isn't the dashboard.
if (location.pathname !== '/admin/' && $('[href="/admin/"]').hasClass('active')) {
$('[href="/admin/"]').removeClass('active');
}
};
This works fine for all first-level menu items and for the second-level menu item All users, but when I go to /admin/users/roles/, it makes All users and Roles active. The same thing happens when I go to /admin/users/roles/add/. I think this happens because the code makes all menu items active which look like the window.location, but I don't know how to only make Roles active when I go to /admin/users/roles/ and /admin/users/roles/add/, etc.
I really hope someone can help me with this. If you can, I'll buy you a beer.
try this..
var loc = window.location.pathname;
$('#side-menu').find('a').each(function() {
$(this).toggleClass('active', $(this).attr('href') == loc);
});
and ue full absolute path in href i.e.http://yourdomain.com//admin/users/roles/

Add a active link to custom ul in wordpress

I have a custom list(ul) in wordpress sidebar. I want to add active class to list items.
<ul class="sidebar-list">
<li> OWLE</li>
<li>Sink or Swim</li>
<li>Swim and Survive</li>
<li>VWSC</li>
<li>Water Smart</li>
<li>Grey Medallion</li>
<li>Aquatic PD Workshops</li>
<li>Edu From Anywhere</li>
<li>Bronze e-Lifesaving</li>
<li>Water Smart Award</li>
<li>Victorian Water Safety Certificate</li>
<li>Edu From Anywhere Newsletter</li>
<li>Edu Casual Instructor</li>
<li>Grey Medallion</li>
<li>Sink or Swim</li>
<li>Edu Instructor of year Profile</li>
<li>Swim & Survive Licensee of year</li>
</ul>
<li class="active"> OWLE</li>
should look like on 'index.php/owle/'.
Add this to your wordpress them's custom javascript. Lot of themes have that. Check theme customization.
var url = window.location;
// Will only work if string in href matches with location
$('sidebar-list li a[href="'+ url +'"]').parent().addClass('active');
// Will also work for relative and absolute hrefs
$('sidebar-list li a').filter(function() {
return this.href == url;
}).parent().addClass('active');
if your theme don't have this you have to hardcode this. I recommend you add this to your footer.php
add_filter('nav_menu_css_class' , 'special_nav_class' , 10 , 2);
function special_nav_class($classes, $item){
if( in_array('current-menu-item', $classes) ){
$classes[] = 'active '; // your new class
}
return $classes;
}
Try this code, It Works. All you have to do is juss change those class names with the classes you are using.
you no need to do coding for it.
create sidebar with wordpress menu.
wordpress menu have default class for currunt item
current-menu-item
and you can add css to it ..

Jquery to copy first link to second ul and then change class of first link

Short question:
http://jsfiddle.net/wF4FH/2/
What I want is for Page1 to be right above Page2 and Page10 above Page 20 before I change the classes. This should work for any number of elements.
The code provided gives an "Uncaught TypeError: Object # has no method 'append' ".
Long question:
I'm having problem finding the correct way to insert an li element based on the first link. The problem is I cant use id's on my markup so I have to "walk through" each class and check for names. I might just make this a lot more complicated than it is because my first two solutions didn't work the way I thought they would.
html
<ul class="nav">
<li class="active">
Start
</li>
<li class="has-child">
page1
<ul class="">
<li>
page2
</li>
</ul>
</li>
<li class="has-child">
page10
<ul class="">
<li>
page20
</li>
<li>
page30
</li>
</ul>
</li>
javascript
//Copy first link to child ul li
var pageLinks = $("li.has-child > a:first-child");
if (pageLinks != null) {
//var dropdownMenus = $("li.dropdown > a:first-child");
for (var i = 0; i < pageLinks.length; i++) {
for (var x = 0; x < pageLinks.length; x++) {
if (pageLinks[i].innerHTML === pageLinks[x].innerHTML) {
pageLinks[x].childNodes.append(pageLinks[i]);
}
}
}
}
//Change css classes
$("li.has-child").attr('class', 'dropdown');
$(".dropdown ul").addClass("dropdown-menu");
$(".dropdown a").attr("href", "#").addClass("dropdown-toggle").attr('data-toggle', 'dropdown');
strong text
What I want is for Page1 to be right above Page2 and Page10 above Page 20 before I change the classes. This should work for any number of elements.
When they are copied to the inner ul I change the top level menu item to a different class to work as a clickable dropdown men item.
The code provided gives an "Uncaught TypeError: Object # has no method 'append' ".
It is the navigation of a cms I cant change the markup on.
try this:
$links = $('li.has-child').children('a:first-child');
if($links.length > 0){
$links.each(function(i,link){
$(link).next().prepend($('<li></li>').append($(link)))
})
}
http://jsfiddle.net/wF4FH/6/
You need .clone() method to copy elements..
UPDATED
$links = $('li.has-child').children('a:first-child');
if($links.length > 0){
$links.each(function(i,link){
$(link).next().prepend($('<li></li>').append($(link).clone()))
})
}
http://jsfiddle.net/wF4FH/7/
When you have a jQuery object and you access it by numeric index, you're left with an HTML element. So $('body')[0] == document.body. This means that when you access pageLinks[x], you're really getting a raw element. This means that you want pageLinks[x].appendChild(pageLinks[i]);, not pageLinks[x].childNodes.append(pageLinks[i]);

Categories

Resources