Add a active link to custom ul in wordpress - javascript

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 ..

Related

Keep active class on gallery navigation when using pagination

I have the following navigation on the gallery page of my website that allows users to filter the images by category.
<ul>
<li>All</li>
<li>Our Gym</li>
<li>Our Classes</li>
<li>Our Coaches</li>
</ul>
I've added the following snippet to add the class 'active' the category that is currently being viewed by the user.
<script>
jQuery(function($) {
var path = window.location.href;
$('.gallery_listing_wrapper li a').each(function() {
if (this.href === path) {
$(this).addClass('active');
}
});
});
</script>
This works for the above gallery navigation however once I navigate using the pagination it doesn't work.
The URL for the pagination is slightly different to the gallery and its categories.
For example - instead of /gallery/our-gym/ - page/ and the page number is added to the URL i.e. /gallery/page/2/
Is it possible to adjust the above snippet to keep the active class on All when the pagination is being used?
You could always just add the class to the "All" button if none of the other buttons match the current URL.
<script>
jQuery(function($) {
var path = window.location.href;
let match = $(`.gallery_listing_wrapper li a[href="${path}"]`);
if(match.length >= 1)
match.addClass("active");
else
$(".gallery_listing_wrapper li a[href='/gallery/']").addClass("active");
});
</script>

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

Active class nav item based on retrieved url portion

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;
}

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 class to an `<a>` tag based on a comparison with an `<li>` class name

I just starting with javascript and jQuery and still learning syntax. I am trying to accomplish something that seems pretty complicated and was hoping maybe someone could help.
I am trying to add an "active" class to a top menu tab's <a> tag if the user is on any of the sub pages containing that tab's associated sidebar menu.
Each topmenu tab has its own sidemenu and the same sidemenu appears on all of its associated pages.
Each sidemenu has a unique classname assigned to its <li> tags that identify which topmenu tab it is associated with.
I assume this has to be initiated by a onLoad or something on the new page so I can't use 'this.' to refer to the parent topmenu tab.
I think what I need to do is get the href value of each ul.topmenu li a, with the / stripped out. (i.e. /kitchen, /park, /market becomes kitchen, park and market)
I think I can do it with something like this maybe?:
var hrefs = $("ul.topmenu li a").attr('href');
hrefs = hrefs.replace("/","")
Then I need to see if the class exists in ul.sidemenu li.[classname] (i.e. class="active-trail first odd sf-item-1 sf-depth-2 park sf-no-children")
maybe?:
$("ul.sidemenu li").hasClass('hrefs')
If a match is found I need to add "active" to the class for the "ul.topmenu li a"
maybe?:
$("ul.topmenu li a").addClass("selected");
I am sure there is a good way to do this. Am I even close? Any help is appreciated.
Edit:
This is the HTML for my topmenu:
<ul id="superfish-1" class="sf-menu main-menu sf-horizontal sf-style-default sf-total-items-6 sf-parent-items-0 sf-single-items-6 topmenu">
<li id="menu-218-1" class="first odd sf-item-1 sf-depth-1 topmenu sf-no-children">Home</li>
<li id="menu-456-1" class="active-trail middle even sf-item-2 sf-depth-1 topmenu sf-no-children">Park</li>
<li id="menu-549-1" class="middle odd sf-item-3 sf-depth-1 topmenu sf-no-children">Farmstay</li>
<li id="menu-574-1" class="middle even sf-item-4 sf-depth-1 topmenu sf-no-children">Market</li>
<li id="menu-580-1" class="middle odd sf-item-5 sf-depth-1 topmenu sf-no-children">Kitchen</li>
<li id="menu-352-1" class="last even sf-item-6 sf-depth-1 topmenu sf-no-children">Galleries</li>
</ul>
This is the HTML for the sidemenu shown on the pages under "Park" mainmenu link:
<ul id="superfish-2" class="sf-menu main-menu sf-vertical sf-style-default sf-total-items-5 sf-parent-items-0 sf-single-items-5 sidemenu">
<li id="menu-561-2" class="first odd sf-item-1 sf-depth-2 park sf-no-children">Activities</li>
<li id="menu-562-2" class="middle even sf-item-2 sf-depth-2 park sf-no-children">Facilities</li>
<li id="menu-550-2" class="middle odd sf-item-3 sf-depth-2 park sf-no-children">Hours</li>
<li id="menu-564-2" class="middle even sf-item-4 sf-depth-2 park sf-no-children">Rules (there are always some)</li>
<li id="menu-563-2" class="last odd sf-item-5 sf-depth-2 park sf-no-children">Volunteers</li>
</ul>
Edit 2:
Okay, I think I am close. I switched to pulling from the URL, don't know why I didn't think to do it before, it should be much easier and doesn't require special attribute settings. It is not working yet, but here is what I have:
<script type="text/javascript">
$(document).ready(function() {
//split the url into parts
//www.greenwoodhill.com/park/activities should become an array of [greenwoodhill.com, park, activities]
var a = location.pathname.split("/");
//make sure there are at least 2 parts
if ( a.length > 2 ) {
//get the second section of the url
//should be "park" in this case
var page = a[2]
// for each url in the .topmenu
$('ul.topmenu li a').each(function(){
// check if the href ends with /<page> and assign the class if so
if ( this.href.substr( -page.length -1) === '/' + page){
$(this).addClass('itworks');
}
});
}
});
</script>
Update in regard to the updated answer
Your code is correct as a concept, but you have a couple of mistakes in execution ...
location.pathname docs returns the path without the domain.
So in your case it would be '/park/activities'
That would be splitted to ['','park','activities'].
To avoid the confusing empty first element you should us the .substr() docs method to remove the 1st / before splitting.
This results to location.pathname.substr(1).split("/"); which will return ['park','activities']
Arrays in javascript are 0-bazed docs, which means that the first element has an index of 0 (and not 1, as you might think)
Now that we have cleaned the array from the empty element and we should check for a.length > 1 and since we need the 1st element (index of 0) we would access it with a[0].
I added .toLowerCase() docs to make the comparison case-insensitive..
All combined it results in
var a = location.pathname.substr(1).split("/");
//make sure there are at least 2 parts
if (a.length > 1) {
var page = a[0].toLowerCase();
// for each url in the .topmenu
$('ul.topmenu li a').each(function() {
// check if the href ends with /<page> and assign the class if so
if (this.href.substr(-page.length - 1).toLowerCase() === '/' + page) {
$(this).addClass('itworks');
}
});
}
Working example at http://jsfiddle.net/gaby/gSxJc/
Original Answer
Assuming that the classnames of the .sidemenu match the urls of the .topmenu you can
// extract the classname from the first '.sidemenu li' element
var classname = $('ul.sidemenu li')[0].classname;
// for each url in the .topmenu
$('ul.topmenu li a').each(function(){
// check if the href ends with /<classname> and assign the class if so
if ( this.href.substr( -classname.length -1) === '/' + classname){
$(this).addClass('selected');
}
});
Update
since you create the .sidemenu manually, you should add a data- attribute to it and give it the value you want to use, to avoid searching through classnames ..
Something like
<ul id="superfish-2" data-page="park" class="sf-menu main-menu sf-vertical sf-style-default sf-total-items-5 sf-parent-items-0 sf-single-items-5 sidemenu">
and now instead of searching for the classname you can do
var page = $('ul.sidemenu li').data("page");
// for each url in the .topmenu
$('ul.topmenu li a').each(function(){
// check if the href ends with /<page> and assign the class if so
if ( this.href.substr( -page.length -1) === '/' + page){
$(this).addClass('selected');
}
});

Categories

Resources