changing class name on click for duplicate menus - javascript

Here's the fiddle
I am trying to achieve something very simple when a listed item is clicked a new class has to be added to it, there are two identical menus, change of class needs to happen in both the menus even if the click occurs in single menu.
In the fiddle #e8e8e8 color is added to any listed item with class 'zm-active', currently it's on home and works for single menu, I want it to work on both the menus even if click happens on single menu.
Code:
JS:
$(document).ready(function() {
$('.zetta-menu li').on('click', changeClass);
});
function changeClass() {
$('.zetta-menu li').removeClass('zm-active');
$(this).addClass('zm-active');
}
HTML:
<nav id="fixedbar">
<ul onClick="" class="zetta-menu zm-response-switch zm-effect-slide-top">
<li class="zm-active zm-content-full">
<a href="#header-single-1">
Home
</a>
</li>
<li>
<a href="#about-10">
About
</a>
</li>
<li>
<a href="#services-18">
Services
</a>
</li>
<li>
<a href="#portfolio-19">
Portfolio
</a>
</li>
<li>
<a href="#team-19">
Team
</a>
</li>
<li>
<a href="#pricing-17">
Pricing
</a>
</li>
<li>
<a href="#blog-19">
Blog
</a>
</li>
<li>
<a href="#contact-1">
Contact
</a>
</li>
</ul><!-- /.zetta-menu -->
</nav><!-- /#fixedbar -->
<nav class="navbar navbar-single-1 center" role="navigation">
<div class="navbar-inner center">
<ul onClick="" class="zetta-menu zm-response-switch zm-effect-slide-top">
<li class="zm-active zm-content-full">
<a href="#header-single-1">
Home
</a>
</li>
<li>
<a href="#about-10">
About
</a>
</li>
<li>
<a href="#services-18">
Services
</a>
</li>
<li>
<a href="#portfolio-19">
Portfolio
</a>
</li>
<li>
<a href="#team-19">
Team
</a>
</li>
<li>
<a href="#pricing-17">
Pricing
</a>
</li>
<li>
<a href="#blog-19">
Blog
</a>
</li>
<li>
<a href="#contact-1">
Contact
</a>
</li>
</ul><!-- /.zetta-menu -->
</div><!-- /.navbar-inner -->
</nav><!-- /.navbar-single-1 -->
I am not very through in javascript/jquery, any help would be appreciated.

Is there something the links have in common? Of yourse! The href attribute (at least in your example).
So, you grab the href attribute of the link you clicked, by this attribute value you grab all links having the same href, and then you grab their parents (LI) in order to add class to them.
$(document).ready(function() {
$('.zetta-menu li a').click(function () {
var itemsToChange = $('li a[href="'+$(this).attr('href')+'"]').parent(),
allItems = $('.zetta-menu li');
allItems.removeClass('zm-active');
itemsToChange.addClass('zm-active');
});
});
JS Fiddle demo

Related

How can I delete elements which do not contain matching inner element ClassName?

I'm trying to find a way to delete list items which do not contain a specific set of class Names.
The HTML (simplified for this example) looks like this:
<ul class="myListItems">
<li class="listTree">
Link 1
</li>
<li class="listTree">
<span class="treeIcon"> </span>
<a href="">
<span class="draft"></span>
<span class="redirect"></span>
Link 2
</a>
</li>
<ul>
<li class="listTree">
<a href="">
<span class="redirect"></span>
Link 3
</a>
</li>
</ul>
</ul>
What I would like to do, is DELETE all elements which do not contain <span class="redirect"> or <span class="draft">
Use li.querySelector() to test whether the li contains an element matching a selector. You can use this to test if it contains either of the classes you want to keep.
document.querySelectorAll("li").forEach(li => {
if (!(li.querySelector(".draft") || li.querySelector(".redirect"))) {
li.remove();
}
});
<ul class="myListItems">
<li class="listTree">
Link 1
</li>
<li class="listTree">
<span class="treeIcon"> </span>
<a href="">
<span class="draft"></span>
<span class="redirect"></span> Link 2
</a>
</li>
<ul>
<li class="listTree">
<a href="">
<span class="redirect"></span> Link 3
</a>
</li>
</ul>
</ul>

jQuery all list items in menu is set to active instead of just the selected one

This is the structure of my menu. I have attached the jQuery code below. The way this works is that when I click on Home Page, its parent element which is the list item has a class that is set to active.
At the moment, When I am at the Home Page, its list item has an active class. However, the list-items for Account Codes and Branches also have an active class set on it. How can I make sure that only my Home Page is affected?
Also, how can I change my jQuery code to work with this menu format where there is a new list within a list?
<ul class="sidebar-menu" id="navigation-menu">
<li><i class="far fa-square"></i><span>Home Page</span></li>
<li class="menu-header">Administrator Mode</li>
<li class="nav-item dropdown">
<i class="fas fa-fire"></i><span>Configuration</span>
<ul class="dropdown-menu">
<li>Account Codes</li>
<li>Branches</li>
</ul>
</li>
</ul>
<script>
$(document).ready(function () {
var current = location.pathname;
$("#navigation-menu a").each(function () {
var $this = $(this);
if ($this.attr('href').indexOf(current) !== -1) {
console.log($this);
$this.parent().addClass('active');
console.log("matched");
}
});
});
</script>
Dropdown Layout
The most effective HTML layout pattern for dropdown menus is to alternate between <ul>/<ol> and <li>:
<ul>
<li class='dropdown'>
Dropdown
<ul class='menu' style='display:none'>
<li>Item</li>
<li class='dropdown'>
<a href='#/'>Dropdown</a>
<ul class='menu' style='display:none'>
<li>Item</li>
<li>Item</li>
</ul>
</li>
</ul>
</li>
</ul>
Also, if you want the menus to be initially closed, add the following inline style:
<ul class='menu' style='display:none'>
The <a>nchors have default behavior that is hard to override when using a framework like Bootstrap or Foundation. Try toggling the .active class on .has-dropdown children tags.
Demo
Details commented in demo
/*
Delegate click event to each .has-dropdown
Toggle .active class on that particular .has-dropdown children tags
Get next .dropdown-menu and toggle it up/down and toggle .active
*/
$('.has-dropdown').on('click', function(e) {
$(this).children().toggleClass('active');
$(this).next('.dropdown-menu').slideToggle().toggleClass('active');
});
.active {
color: tomato
}
<link href='https://cdnjs.cloudflare.com/ajax/libs/foundation/6.5.3/css/foundation.min.css' rel="stylesheet">
<link href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" rel="stylesheet" crossorigin="anonymous">
<ul id="navigation-menu" class="sidebar-menu">
<li>
<a href="#/" class="nav-link">
<i class="fas fa-home"></i><span> Home Page</span>
</a>
</li>
<li class="menu-header">
<a href="#/" class="nav-link has-dropdown">
<i class="fas fa-tools"></i><span> Administration</span>
</a>
<ul class="nav-item dropdown-menu" style='display:none'>
<li>
<a href="#/" class="nav-link has-dropdown">
<i class="fas fa-lock"></i><span> Security</span>
</a>
<ul class="dropdown-menu" style='display:none'>
<li>
<a href="#/" class="nav-link">
<span> Account Codes</span>
</a>
</li>
<li>
<a href="#/" class="nav-link">
<span> Branches</span>
</a>
</li>
</ul>
</li>
<li>
<a href="#/" class="nav-link has-dropdown">
<i class="fas fa-cog"></i><span> Configuration
</span></a>
<ul class="dropdown-menu" style='display:none'>
<li>
<span> Layout</span>
</li>
<li>
<span> Assets</span>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Toggle list elements in Jquery while showing the first few elements all the time

I have a menu which has categories with subcategories. I want to show/hide the list elements but the catch is I need the first 2 elements to show all the time. I have tried to look for the solution everywhere and the closest I came was jQuery toggle show/hide elements after a certain number of matching elements
but this doesn't seem to be working for me as my filters are little more complicated. Can someone please help me with this. Clicking on 'Sub-Categories' shows/hides links.
Also i must add the default state must be collapsed.
My basic fiddle without any style
HTML code:
<li class="children level1">
<a href="https://dev.holmescustom.com/signage/office-signage">
<span>Office Signs</span>
</a>
<ul class="level1" style="display: block;">
<li class="level2">
<a href="https://dev.holmescustom.com/signage/office-signage/wash-hands-hygiene">
<span>Wash Hands and Hygiene</span>
</a>
</li>
<li class="level2">
<a href="https://dev.holmescustom.com/signage/office-signage/entrance-and-exit">
<span>Entrance & Exit Signage</span>
</a>
</li>
<li class="level2">
<a href="https://dev.holmescustom.com/signage/office-signage/way-finding">
<span>Way-finding Signage</span>
</a>
</li>
</ul>
</li>
<li class="children level1">
<a href="https://dev.holmescustom.com/signage/shop-by-template">
<span>Shop by Template</span>
</a>
<ul class="level1" style="display: block;">
<li class="level2">
<a href="https://dev.holmescustom.com/signage/shop-by-template/smoking-no-vaping-signs">
<span>Smoking & Vaping</span>
</a>
</li>
<li class="level2">
<a href="https://dev.holmescustom.com/signage/shop-by-template/parking-signs">
<span>Parking</span>
</a>
</li>
<li class="level2">
<a href="https://dev.holmescustom.com/signage/shop-by-template/store-hours">
<span>Store Hours</span>
</a>
</li>
<li class="level2">
<a href="https://dev.holmescustom.com/signage/shop-by-template/restrooms-signs">
<span>Restrooms</span>
</a>
</li>
</ul>
</li>
jQuery code:
jQuery('li.children.level1').each(function () {
if (jQuery(this).find('ul').length) {
jQuery(this).append('Sub-Categories');
}
});
jQuery('.subCat').click(function () {
jQuery(this).prev('ul:first.level1').slideToggle();
});
To achieve expected result, use below option
jQuery('.subCat').click(function () {
jQuery(this).parent().find('li:gt(1)').slideToggle();
});
Subcategories parent
Find li greater than 1 (li's index starts from 0 )
Hide by default, using jQuery(this).find('li:gt(1)').hide()
code sample for reference - https://codepen.io/nagasai/pen/omYKzv?editors=1010
jQuery('li.children.level1').each(function () {
if (jQuery(this).find('ul').length) {
jQuery(this).append('Sub-Categories');
}
jQuery(this).find('li:gt(1)').hide()
});
jQuery('.subCat').click(function () {
jQuery(this).parent().find('li:gt(1)').slideToggle();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<li class="children level1">
<a href="https://dev.holmescustom.com/signage/office-signage">
<span>Office Signs</span>
</a>
<ul class="level 1" style="display: block;">
<li class="level2">
<a href="https://dev.holmescustom.com/signage/office-signage/wash-hands-hygiene">
<span>Wash Hands and Hygiene</span>
</a>
</li>
<li class="level2">
<a href="https://dev.holmescustom.com/signage/office-signage/entrance-and-exit">
<span>Entrance & Exit Signage</span>
</a>
</li>
<li class="level2">
<a href="https://dev.holmescustom.com/signage/office-signage/way-finding">
<span>Way-finding Signage</span>
</a>
</li>
</ul>
</li>
<li class="children level1">
<a href="https://dev.holmescustom.com/signage/shop-by-template">
<span>Shop by Template</span>
</a>
<ul class="level1" style="display: block;">
<li class="level2">
<a href="https://dev.holmescustom.com/signage/shop-by-template/smoking-no-vaping-signs">
<span>Smoking & Vaping</span>
</a>
</li>
<li class="level2">
<a href="https://dev.holmescustom.com/signage/shop-by-template/parking-signs">
<span>Parking</span>
</a>
</li>
<li class="level2">
<a href="https://dev.holmescustom.com/signage/shop-by-template/store-hours">
<span>Store Hours</span>
</a>
</li>
<li class="level2">
<a href="https://dev.holmescustom.com/signage/shop-by-template/restrooms-signs">
<span>Restrooms</span>
</a>
</li>
</ul>
</li>
Change your javascript that do the slideToggle as this;
jQuery('.subCat').click(function () {
var ul = jQuery(this).prev('ul:first.level1');
var li = ul.find('li:gt(1)');
li.slideToggle();
});

jQuery Menu > Collapse All Not WIthin Current Tree

Menu - Snippet
<ul class="Menu Open">
<li>
<a href="javascript:;" data-title="Account">
<span class="Title">Account</span>
</a>
<ul class="sub-menu First TeStInG">
<li>
<a href="javascript:;" data-title="Account/Dashboard">
<span class="Title">Dashboard</span>
</a>
</li>
<li>
<a href="javascript:;" data-title="Account/Messages">
<span class="Title">Messages</span>
</a>
<ul>
<li>
<a href="javascript:;" data-title="Account/Messages/Compose">
<span class="Title">Compose</span>
</a>
</li>
</ul>
</li>
<li>
<a href="javascript:;" data-title="Account/Profile">
<span class="Title">Profile</span>
</a>
<ul>
<li>
<a href="javascript:;" data-title="Account/Profile/View">
<span class="Title">View</span>
</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
JQuery - Snippet
$(document).ready(function() {
"use strict";
$(document).on('click', function(e) {
if ($(e.target).closest($('.Menu')).length) {
if ($(e.target).closest("a").siblings("ul").length === 0) {
console.log('Doesn\'t have Children');
} else {
$(e.target).closest("a").siblings("ul").show();
}
}
});
});
What I'm Trying To Achieve
Without using jQuery UI, I would like to make it so that only one menu item is visible at a time on each level.
If the user has expanded a level multiple times then clicks on a different higher level, all within should be hidden.
If the user clicks on a same level item which expands, all other same level should be hidden.
I've tried several ways to do this, however I keep getting tied up whereas I either make things hide which shouldn't or make it so that I cannot expand anything. I've done this previously and cannot understand why I cannot do this now.
You can use find() but when you click on parent you will have to check if it is parent, so when you want to open you just want to open direct children but when you want to close you want to close all chidren.
$("ul li ul").hide()
$('li').click(function(e) {
e.stopPropagation()
var parent = $(this)
$(this).find('ul').each(function() {
if ($(this).is(':visible')) {
$(this).hide()
} else {
if ($(this).parent().is(parent)) {
$(this).show()
}
}
})
$(this).siblings().children('ul').hide()
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="Menu Open">
<li>
<a href="javascript:;" data-title="Account">
<span class="Title">Account</span>
</a>
<ul class="sub-menu First TeStInG">
<li>
<a href="javascript:;" data-title="Account/Dashboard">
<span class="Title">Dashboard</span>
</a>
</li>
<li>
<a href="javascript:;" data-title="Account/Messages">
<span class="Title">Messages</span>
</a>
<ul>
<li>
<a href="javascript:;" data-title="Account/Messages/Compose">
<span class="Title">Compose</span>
</a>
</li>
</ul>
</li>
<li>
<a href="javascript:;" data-title="Account/Profile">
<span class="Title">Profile</span>
</a>
<ul>
<li>
<a href="javascript:;" data-title="Account/Profile/View">
<span class="Title">View</span>
</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>

how to add class to tag when i click on it

I need to add class="active" to tag <li> when i click on <a> to become <li class="active">
Notice i have multiple <li> tags and i need to class="active" only for tag <li> that i clicked on it.
this my sample code :
<ul class="nav">
<li>
<a href="...">
Personal Informations <i class="pe-7s-user"></i>
</a>
</li>
<li>
<a href="...">
Qualifications <i class="pe-7s-note2"></i>
</a>
</li>
</ul>
Use .parent() and .addClass()
$(function(){
$('a').click(function(e){
e.preventDefault();
$(this).parent().addClass('active');
})
})
.active {
background-color: orange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav">
<li>
<a href="#">
Personal Informations <i class="pe-7s-user"></i>
</a>
</li>
<li>
<a href="#">
Qualifications <i class="pe-7s-note2"></i>
</a>
</li>
</ul>

Categories

Resources