Add different class to all levels of parents of a selected link - javascript

Following is my html
<ul>
<li>
Women
<ul>
<li>Top
<ul>
<li>Short</li>
<li>Lengthy
<ul>
<li><a class="selected" href="">Child Parent</a></li>
<li>Child Parent</li>
<li>Child Parent</li>
<li>Child Parent</li>
</ul>
</li>
<li>Medium</li>
<li>Full Sleve</li>
</ul>
</li>
<li>Casuals</li>
<li>Jeans</li>
<li>Kurthah</li>
</ul>
</li>
<li>Men
<ul>
<li>Top</li>
<li>Casuals</li>
<li>Jeans</li>
<li>Kurthah</li>
</ul>
</li>
<li>Children</li>
<ul>
Here I have a class selected for a link which is selected. What I need is, I want to add a class to the parent li <li>Lengthy, its top parent <li>Top and its top parent <li>Women
All the parents should have different class.
Please find the fiddle here: http://jsfiddle.net/w3pjrxff/2/

Try this:
$(document).ready(function() {
$(document).find("a.selected").each(function(){
$(this).parents("li").each(function(i, v){
$(v).addClass('newPar' + i);
});
});
});
Where i is the index (0, 1, 2 and so on, for different classes), jQuery.parents() gets all parent elements, with the parameter 'li' it only retrieves all li parents.

You may try
$(document).ready(function() {
$("a").attr("href", "#"); // kind of disable all links
$("a").click(function () {
$("a").removeClass("selected");
$(this).addClass("selected");
$(this).parents("a").addClass("selected");
});
});
The problem with your html is, that the <a> are not parents but siblings of the next ul.

As I said in the comments, if you want to add a numerically incremented classes you can use(but then to remove those classes it will be difficult)
$(document).ready(function() {
var $selected = $('.selected');
var $parents = $selected.parent().parents('li');
$parents.children('a').addClass(function(i) {
return 'parent-' + (i + 1)
});
});
.selected {
color: #FF0000;
}
.parent-1 {
color: #00FF00;
}
.parent-2 {
color: #0000FF;
}
.parent-3 {
color: #FF00FF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>Women
<ul>
<li>Top
<ul>
<li>Short</li>
<li>Lengthy
<ul>
<li><a class="selected" href="">Child Parent</a></li>
<li>Child Parent</li>
<li>Child Parent</li>
<li>Child Parent</li>
</ul>
</li>
<li>Medium</li>
<li>Full Sleve</li>
</ul>
</li>
<li>Casuals</li>
<li>Jeans</li>
<li>Kurthah</li>
</ul>
</li>
<li>Men
<ul>
<li>Top</li>
<li>Casuals</li>
<li>Jeans</li>
<li>Kurthah</li>
</ul>
</li>
<li>Children</li>
<ul>
Another approach will be
$(document).ready(function() {
var $selected = $('.selected');
$selected.parent().parents('li').addClass('parent');
});
.selected {
color: #FF0000;
}
.parent > a {
color: #00FF00;
}
.parent .parent > a {
color: #0000FF;
}
.parent .parent .parent > a {
color: #FF00FF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>Women
<ul>
<li>Top
<ul>
<li>Short</li>
<li>Lengthy
<ul>
<li><a class="selected" href="">Child Parent</a></li>
<li>Child Parent</li>
<li>Child Parent</li>
<li>Child Parent</li>
</ul>
</li>
<li>Medium</li>
<li>Full Sleve</li>
</ul>
</li>
<li>Casuals</li>
<li>Jeans</li>
<li>Kurthah</li>
</ul>
</li>
<li>Men
<ul>
<li>Top</li>
<li>Casuals</li>
<li>Jeans</li>
<li>Kurthah</li>
</ul>
</li>
<li>Children</li>
<ul>

Here is another fiddle if you need to add different classes to each parent. This code, however, can be optimized.
$(document).ready(function() {
var curr_parent= $(document).find("a.selected").parent();
var parent1= $(curr_parent).parent().closest('li');
$(parent1).addClass('parent1')
var parent2 = $(parent1).parent().closest('li');
$(parent2).addClass('parent2')
var parent3 = $(parent2).parent().closest('li');
$(parent3).addClass('parent3')
});

Related

How can I select all the li child of an element in js

How can I select all the li child of an element in js
I want to select all the li elements of this item (direct child, grand child all)
document.querySelectorAll(".stellarnav li.has-sub").forEach(item =>{
item.addEventListener("click", function(){
console.log(item)
// to make you understand I described it below in css language
// in CSS language it is like this: item li
// then I want to removeAttribute from the all the child
// like this
document.querySelectorAll(`${item} li`).forEach(childItem =>{
childItem.removeAttribute("open");
})
// how can I achive this thing to select all the li childs
// here I tried it but this is not valid
})
});```
Just run this.querySelectorAll('li').forEach(li=>li.removeAttribute("open"));
This is a document querySelectorAll document
Tested code:
document.querySelectorAll(".nav li.has-sub").forEach(item =>{
item.addEventListener("click", function(){
this.querySelectorAll('li').forEach(li=>li.removeAttribute("open"));
})
})
li[open]{
color: red;
}
.nav >li{
margin: 10px
}
<ul class='nav'>
<li class='has-sub'>
this is has-sub li 1
<ul>
<li open>
this is open
</li>
<li open>
this is open
</li>
<li> this is another li
</li>
</ul>
</li>
<li class='has-sub'>
this is has-sub li 2
<ul>
<li open>
this is open
</li>
<li open>
this is open
</li>
<li> this is another li
</li>
</ul>
</li>
<li>
this is li 3
<ul>
<li open>
this is not has-sub open
</li>
<li open>
this is not has-sub open
</li>
<li> this is another li
</li>
</ul>
</li>
</ul>

How to add a class to li element which has a ul child element in pure Javascript not jQuery

How can i add a class to an <li> element which has a child <ul> element. I found there are so many examples in jQuery but not in Javascript. I would like to do it in Pure Javascript for Performance Optimization. The code is as follows: Thanks in Advance!
<nav id="navigation">
<li>Home</li>
<li> <!-- >>> I want to add a class to this <li> element as it has a <ul> child element -->
Services
<ul>
<li>Graphic Designing</li>
<li>Web Designing</li>
</ul>
</li>
<li>Contact</li>
</nav>
I think you need something like this
// -------- vanilla js
document.querySelectorAll('li').forEach((el) => {
if(el.querySelector('ul')) el.classList.add('theClassNameYouNeed');
});
// -------- jQuery (just to see the difference) :)
$('li').each(function() {
const el = $(this);
if(el.find('ul').length) el.addClass('theClassNameYouNeed');
});
Useful resources to move from jQuery to pure Javascript (Vanilla):
http://youmightnotneedjquery.com/
https://tobiasahlin.com/blog/move-from-jquery-to-vanilla-javascript/
https://gist.github.com/joyrexus/7307312
document.querySelectorAll('li').forEach((el) => {
if(el.querySelector('ul')) el.classList.add('theClassNameYouNeed');
});
.theClassNameYouNeed {
background: green;
}
<li>Home</li>
<li>
Services
<ul>
<li>Graphic Designing</li>
<li>Web Designing</li>
</ul>
</li>
<li>Contact</li>
This is one possible way of adding the class to the li element which has ul as child
const liElem = document.querySelectorAll("li")
liElem.forEach(elem => {
if(elem.querySelector("ul")) {
elem.classList.add("new-class");
}
})
.new-class {
color: red;
background: #ececec
}
<li>Home</li>
<li>
Services
<ul>
<li>Graphic Designing</li>
<li>Web Designing</li>
</ul>
</li>
<li>Contact</li>
Demo snippet
const liElems = document.querySelectorAll('li');
liElems.forEach((elem) => {
const childrenElems = elem.querySelectorAll('ul')
if(childrenElems.length > 0){
elem.setAttribute("class", "democlass")
}
});
<html>
<head></head>
<body>
<li>Home</li>
<li>
Services
<ul>
<li>Graphic Designing</li>
<li>Web Designing</li>
</ul>
</li>
<li>Contact</li>
<script src="script.js"></script>
<body>
</html>
You can do this two ways below using only JavaScript off-course.
Here is simple direct solution to add class to the li which has ul in it. This selects the first li > ul in the DOM and apply class to it using classList and add method.
Live Demo:
window.addEventListener('DOMContentLoaded', (event) => {
let getLiUL = document.querySelector('li > ul')
getLiUL.parentElement.classList.add('foo')
});
.foo {
background: green;
}
<nav>
<li>Home</li>
<li>I want to add a class to this element as it has a child element
Services
<ul>
<li>Graphic Designing</li>
<li>Web Designing</li>
</ul>
</li>
<li>Contact</li>
</nav>
Here is solution which uses querySelectorAll method and forEach loop. This loops through all the li in the DOM and apply class to the only li which has ul as a child.
Live Demo:
window.addEventListener('DOMContentLoaded', (event) => {
let getLiUL = document.querySelectorAll('li')
getLiUL.forEach(function(e) {
e.querySelector('ul') ? e.classList.add('foo') : " "
})
});
.foo {
background: green;
}
<nav>
<li>Home</li>
<li>I want to add a class to this element as it has a child element
Services
<ul>
<li>Graphic Designing</li>
<li>Web Designing</li>
</ul>
</li>
<li>Contact</li>
</nav>
References:
ClassList
querySelector
querySelectorAll

jQuery, How wait for one click event to be executed per element type?

I have a list of items where those items have their own content organized as lists. So far I have my jQuery expand the list to see the items for their lists. When clicking another item reverting the previously click item to be not expanded.
$(document).ready(function() {
$("li").click(function(){
$(this).find("ul.bid_project").toggleClass("expanded" , 500);
var list_items = $(this).find("ul.bid_project > li.bidding_content");
if(!list_items.is(':visible')){
list_items.show();
} else {
list_items.hide();
}
$(this).siblings().each(function() {
if($(this).find("ul.bid_project").hasClass("expanded")) {
$(this).find("ul.bid_project").toggleClass("expanded", 500);
$(this).find("ul.bid_project > li.bidding_content").hide();
}
});
});
});
My problem is that if I furiosily click on all of li that has the click eventhandler, they each run their own function to expand and check expansion. Is it possible to wait for only one click to be made then continue taking clicks other click on other nodes?
<ul id="bids" class="current_bids_container">
<li>
<ul class="bid_project">
<p class="bidding_title">NYC MTA Above Grade Facility Hardening</p>
<li class="bidding_content">• Lmao </li>
<li class="bidding_content">• Lmao </li>
<li class="bidding_content">• Lmao </li>
<li class="bidding_content">• Lmao </li>
</ul>
</li>
<li>
<ul class="bid_project">
<p class="bidding_title">CONEY ISLAND HOSPITAL PARKING LOT</p>
<li class="bidding_content">• Lmao </li>
<li class="bidding_content">• Lmao </li>
<li class="bidding_content">• Lmao </li>
<li class="bidding_content">• Lmao </li>
</ul>
</li>
</ul>
I just created this Code Snippet below.
I think the solution is to remove the duration from the toggleClass Method and instead use CSS for animations.
Additionally I recommend to NOT place any non-"li"-elements inside an "ul"-element. Just a best practice. Another best practice is to use dash in CSS classnames instead of underscores ("bidding-content" instead of "bidding_content").
Hope this helps.
$(document).ready(function() {
// start website with all collapsed
$("#bids li.bidding-content").hide();
// expand / collapse on click
$("li").click(function() {
$(this).find("ul.bid-project").toggleClass("expanded");
var list_items = $(this).find("ul.bid-project > li.bidding-content");
if(!list_items.is(':visible')){
list_items.show();
} else {
list_items.hide();
}
$(this).siblings().each(function() {
if($(this).find("ul.bid-project").hasClass("expanded")) {
$(this).find("ul.bid-project").toggleClass("expanded");
$(this).find("ul.bid-project > li.bidding-content").hide();
}
});
});
});
ul {
list-style-type: none;
}
ul.bid-project {
opacity: 0;
transform: translateY(-25px);
}
.expanded {
transition: 1s;
opacity: 1 !important;
transform: translateY(0px) !important;
}
<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<ul id="bids" class="current-bids-container">
<li>
<p class="bidding-title">NYC MTA Above Grade Facility Hardening</p>
<ul class="bid-project">
<li class="bidding-content">• Lmao </li>
<li class="bidding-content">• Lmao </li>
<li class="bidding-content">• Lmao </li>
<li class="bidding-content">• Lmao </li>
</ul>
</li>
<li>
<p class="bidding-title">CONEY ISLAND HOSPITAL PARKING LOT</p>
<ul class="bid-project">
<li class="bidding-content">• Lmao </li>
<li class="bidding-content">• Lmao </li>
<li class="bidding-content">• Lmao </li>
<li class="bidding-content">• Lmao </li>
</ul>
</li>
</ul>

toggleclass active doesn't work properly

I want the menu to work like this. When you click Main1 it becomes active and the list will show, when you click it again the list will hide. When Main1 is active and you click Main2, then the Main1 should be inactive and Main2 active.
But my Javascript doesn't seem to make it work well. It makes the Main1 inactive when you click Main2 and the other way, but if you click on any of the active Main it doesn't become incactive. Please help
<div class="directory-section-list">
<ul class="list_item">
<li class="li_lvl lvl0" id="bx_1847241719_2">Main1</li>
<ul>
<li class=""><span class="li_lvl lvl1">1.5-4.5</span>
<ul>
<li>FD 15</li>
<li>FD 18</li>
</ul>
</ul>
<ul class="list_item">
<li class="li_lvl lvl0" id="bx_1847241719_2">Main2</li>
<ul>
<li class=""><span class="li_lvl lvl1">1.5-4.5</span>
<ul>
<li>FD 15</li>
<li>FD 18</li>
</ul>
</ul >
</div>
Javascript
$(' .list_item .lvl0').click(function(){
$(".list_item.active").removeClass("active");
$(this).parent().toggleClass('active');
});
$(' .list_item .lvl1').click(function(){
$(this).parent().toggleClass('active');
});
Try this,
$('.list_item .lvl0').click(function(){
$('.directory-section-list .active').removeClass('active');
if ($(this).parent().hasClass('active'))
{
$(this).parent().removeClass('active');
}
else
{
$(this).parent().addClass('active');
}
});
$('.list_item .lvl1').click(function(){
$(this).parent().toggleClass('active');
});
Please try this
HTML
<div class="directory-section-list">
<ul class="list_item">
<li class="li_lvl lvl0" id="bx_1847241719_2">Main1</li>
<ul>
<li class=""><span class="li_lvl lvl1">1.5-4.5</span>
<ul>
<li>FD 15</li>
<li>FD 18</li>
</ul>
</ul>
</ul>
<ul class="list_item">
<li class="li_lvl lvl1" id="bx_1847241719_2">Main2</li>
<ul>
<li class=""><span class="li_lvl lvl1">1.5-4.5</span>
<ul>
<li>FD 15</li>
<li>FD 18</li>
</ul>
</ul>
</ul>
</div>
Java Script
$(' .list_item .lvl0').click(function () {
$(' .list_item .lvl1').parent().removeClass("active");
$(this).parent().toggleClass('active');
});
$(' .list_item .lvl1').click(function () {
$(' .list_item .lvl0').parent().removeClass("active");
$(this).parent().toggleClass('active');
});
Sorry but your HTML List had a couple of errors the
<li class=""><span class="li_lvl lvl1">1.5-4.5</span>
will never be closed...
its all about the HTML Structure - i've done another change -> check the HTML Structure of this JS Fiddle: http://jsfiddle.net/marco_rensch/hzu76hgt/32/
I think you want something like this?
$(document).ready(function(){
$('.maindiv').hide();
$( "button" ).click(function() {
$('.maindiv[data-link=' + $(this).data('link') + ']').toggle("fade",300);
});
});
div {
background-color: green;
color: white;
width: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<button class="show" data-link="main1">Main1</button>
<button class="show" data-link="main2">Main2</button>
<div>
<div class="maindiv" data-link="main1">
<h1>This is main1</h1>
</div>
<div class="maindiv" data-link="main2">
<h1>This is main2</h1>
</div>
</div>
Well Thank you all for your help. I managed to do it taking some of your examples and making it work my own way. Thank you again. I will post the Javascript fix.
$(document).ready(function() {
$('.li_lvl').click(function () {
if ($(this).parent().hasClass('active')) {
$(this).parent().removeClass('active');
}
else {
$('.directory-section-list .active').removeClass('active');
$(this).parent().addClass('active');
}
});
This will toggle class active of the parent .li_lvl which is the ul.list_item. If parent has class active it will remove class active. If any other list_item will have class active whilst you click on the other list_item, it will remove class active on the other list_item and make class active on the list_item you clicked.

Javascript/JQuery- Highlighting one link at a time on click

I have some links I'd like to be highlighted when you select them, but only one at a time. I found this JQuery code, however, I can't get it to work. The links won't highlight even when I click it. I had a really straight forward Javascript function that changed the color of the link with the onlick. But I would like for it to only highlight the most recently clicked link.
The new JQuery is presented in the code, it appears like it should work I just don't know why it's not. The Javascript function, selectedLink(), I used to call on the onlick method. I'm willing to use either or, I just want the functionality.
.highlight {
color: #3385D6;
border: 1px solid;
border-color: #BBBBBB;
background:#70AAE2;
font-weight: bold;
}
function selectedLink(id){
var sublink = document.getElementById(id);
sublink.style.background = "#CCCCCC";
sublink.style.color = "#3385D6";
sublink.style.fontWeight = "bold";
sublink.style.border = "1px solid";
sublink.style.borderColor = "#BBBBBB";
}
<input type="radio" name="UItab" id="tabf" >
<label for="tabf"><span>Menu Item</span></label>
<div>
<div>
<ul class="sub-menu">
<li id="">SecondLevel A</li></td>
<li id="">SecondLevel B</li>
<li id="">SecondLevel C</li>
</ul>
</div>
<div id="togglebox">
<li id="">ThirdLevel A</li>
<li id="">ThirdLevel B</li>
<li id="">ThirdLevel C</li>
</div>
<div id="barbox">
<li id="">Fourth Level A</li>
<li id="">Fourth Level B</li>
<li id="">Fourth Level C</li>
</div>
<div id="piebox">
<li id="">Fourth Level A</li>
<li id="">Fourth Level B</li>
<li id="">Fourth Level C</li>
</div>
<script>
$('a').click(
function(e){
e.preventDefault;
$('.highlight').removeClass('highlight');
$(this).addClass('highlight')
});
</script>
Code is fine just wrap around a $(function(){/*here*/});
$(function () {
$('a').click(function (e) {
e.preventDefault();
$('.highlight').removeClass('highlight');
$(e.target).addClass('highlight');
});
});
function selectedLink(id) {
var sublink = document.getElementById(id);
sublink.style.background = "#CCCCCC";
sublink.style.color = "#3385D6";
sublink.style.fontWeight = "bold";
sublink.style.border = "1px solid";
sublink.style.borderColor = "#BBBBBB";
}
function toggle_visibility(s) {}
.highlight {
color: #3385D6;
border: 1px solid;
border-color: #BBBBBB;
background:#70AAE2;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="radio" name="UItab" id="tabf" >
<label for="tabf"><span>Menu Item</span></label>
<div>
<div>
<ul class="sub-menu">
<li id="">SecondLevel A</li>
<li id="">SecondLevel B</li>
<li id="">SecondLevel C</li>
</ul>
</div>
<div id="togglebox">
<li id="">ThirdLevel A</li>
<li id="">ThirdLevel B</li>
<li id="">ThirdLevel C</li>
<li id="">ThirdLevel D</li>
<li id="">ThirdLevel E</li>
<li id="">ThirdLevel F</li>
</div>
<div id="barbox">
<li id="">Fourth Level A</li>
<li id="">Fourth Level B</li>
<li id="">Fourth Level C</li>
</div>
instead of removing class to .highlight, remove class for all a elements
$(a).removeClass('highlight');
It may not be the solution but it looks like you should use e.preventDefault() instead of e.preventDefault
may be this will work:
$(document).ready(function(){
$('a').click(function(e){
e.preventDefault();
//All a tag having class highlight
$('a.highlight').removeClass('highlight');
$(this).addClass('highlight');
});
});
Try this:
$('a').click(
function(e){
e.preventDefault();
$(this).addClass('highlight').siblings().removeClass('highlight');
});

Categories