jquery how to hide a single element from others if not exist - javascript

I am working on a sidebar with (single menu) and (submenus).
The menus that contains (submenu) has (+-) toggle, and the ones with singles has nothing.
How can I hide the (+-) of the single menus from other similar elements.
I have tried this way, it hides for all of them.
HTML
<div class="multitoggle">
<ul id="accordions">
<li class="nav-parents">
<div class="link"> <span class="plus">+</span> <span class="minus">-</span> CURRENT ACCOUNTS</div>
<ul class="submenu">
<li>MPOWER CLASSIC</li>
<li>MPOWER GOLD</li>
<li>MPOWER PLATINUM</li>
</ul>
</li>
<li class="nav-parents">
<div class="link"> <span class="plus">+</span> <span class="minus">-</span> OUR SEGMENTS</div>
</li>
</ul>
</div>
JS
$(window ).load(function(e) {
if ($('.nav-parents').has('submenu').length == 0) {
$('.nav-parents').find('.plus, .minus').css('display', 'none');
}
});

Actually only has() will not work in this case. You have to use the combination of not() and has(). And also you missed the dot before submenu. You can do it like following.
$(window ).load(function(e) {
$('.nav-parents').not(':has(.submenu)').find('.plus, .minus').css('display', 'none');
});

Your if statement doesn't do much here, because when you run this:
$('.nav-parents').find('.plus, .minus').css('display', 'none');
it will just select all .nav-parents again and hide their pluses and minuses.
To select only the nav-parents with no submenu, you should use this jQuery code:
$('.nav-parents').not(':has(.submenu)')
Here is your code working in a snippet:
$(window).load(function(e) {
$('.nav-parents')
.not(':has(.submenu)')
.find('.plus, .minus')
.hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="multitoggle">
<ul id="accordions">
<li class="nav-parents">
<div class="link">
<span class="plus">+</span>
<span class="minus">-</span>
CURRENT ACCOUNTS
</div>
<ul class="submenu">
<li>
MPOWER CLASSIC
</li>
<li>
MPOWER GOLD
</li>
<li>
MPOWER PLATINUM
</li>
</ul>
</li>
<li class="nav-parents">
<div class="link">
<span class="plus">+</span>
<span class="minus">-</span>
OUR SEGMENTS
</div>
</li>
</ul>
</div>

You can do it in css itself as the div will be the last-child or only-child if it doesn't have a submenu. so you can achieve it by using
.nav-parents > div.link:last-child > span{
display:none;
}
.nav-parents > div.link:last-child > span{
display:none;
}
<div class="multitoggle">
<ul id="accordions">
<li class="nav-parents">
<div class="link"> <span class="plus">+</span> <span class="minus">-</span> CURRENT ACCOUNTS</div>
<ul class="submenu">
<li>MPOWER CLASSIC</li>
<li>MPOWER GOLD</li>
<li>MPOWER PLATINUM</li>
</ul>
</li>
<li class="nav-parents">
<div class="link"> <span class="plus">+</span> <span class="minus">-</span> OUR SEGMENTS</div>
</li>
</ul>
</div>
Jquery way:-
If you still want to do it on jquery you can remove easily by
$(window ).load(function(e) {
$('.nav-parents > div.link:only-child > span').css('display', 'none');
});
$(window ).load(function(e) {
$('.nav-parents > div.link:last-child > span').css('display', 'none');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="multitoggle">
<ul id="accordions">
<li class="nav-parents">
<div class="link"> <span class="plus">+</span> <span class="minus">-</span> CURRENT ACCOUNTS</div>
<ul class="submenu">
<li>MPOWER CLASSIC</li>
<li>MPOWER GOLD</li>
<li>MPOWER PLATINUM</li>
</ul>
</li>
<li class="nav-parents">
<div class="link"> <span class="plus">+</span> <span class="minus">-</span> OUR SEGMENTS</div>
</li>
</ul>
</div>

Related

How to toggle clicked menu link and untoggle all of toggled links

My website came with this javascript for submenu toggle that work, however, when I click a new menu link the rest toggled links does not close so all them are left open.
How to toggle only clicked link and untoggle or remove all "open" links? If you have a new format of javascript that's fine too.
jQuery(function($) {
$('li.has-submenu span.icon-caret').click(function(e){
var $me = $(this);
if($me.siblings('.wsite-menu-wrap').hasClass('open')) {
$me.siblings('.wsite-menu-wrap').toggleClass('open');
} else {
$me.siblings('.wsite-menu-wrap').addClass('open');
}
});
});
HTML:
<div id="navMobile" class="nav mobile-nav">
<ul class="wsite-menu-default">
<li class="wsite-menu-item-wrap has-submenu">
<a class="wsite-menu-item">Style</a>
<span class="icon-caret"></span>
<div class="wsite-menu-wrap" style="display:none">
<ul class="wsite-menu">
</ul>
</div>
</li>
<li class="wsite-menu-item-wrap has-submenu">
<a class="wsite-menu-item">Life</a>
<span class="icon-caret"></span>
<div class="wsite-menu-wrap" style="display:none">
<ul class="wsite-menu">
</ul>
</div>
</li>
<li class="wsite-menu-item-wrap has-submenu">
<a class="wsite-menu-item">Work</a>
<span class="icon-caret"></span>
<div class="wsite-menu-wrap" style="display:none">
<ul class="wsite-menu">
</ul>
</div>
</li>
</ul>
</div>
Remove the open class from each element first : $('.open').removeClass('open');
First I would remove the display: none if you have no animations with jQuery on the menues. Further I don't know your CSS but you can try it like the following example
$(document).ready(function() {
$('#navMobile .wsite-menu-item').on('click', toggleMenuLink);
function toggleMenuLink(event) {
var target = $(event.target).parent();
event.preventDefault();
target.siblings().removeClass('open');
if (target.hasClass('has-submenu')) {
target.toggleClass('open');
}
}
});
#navMobile .has-submenu > .wsite-menu-wrap,
#navMobile .has-submenu > .wsite-menu {
display: none;
}
#navMobile .has-submenu.open > .wsite-menu-wrap,
#navMobile .has-submenu.open > .wsite-menu {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="navMobile" class="nav mobile-nav">
<ul class="wsite-menu-default">
<li class="wsite-menu-item-wrap has-submenu">
<a class="wsite-menu-item">Style</a>
<span class="icon-caret"></span>
<div class="wsite-menu-wrap">
<ul class="wsite-menu">
<li class="wsite-menu-item-wrap">
<a class="wsite-menu-item">New 1</a>
<span class="icon-caret"></span>
</li>
</ul>
</div>
</li>
<li class="wsite-menu-item-wrap has-submenu">
<a class="wsite-menu-item">Life</a>
<span class="icon-caret"></span>
<div class="wsite-menu-wrap">
<ul class="wsite-menu">
<li class="wsite-menu-item-wrap">
<a class="wsite-menu-item">New 2</a>
<span class="icon-caret"></span>
</li>
</ul>
</div>
</li>
<li class="wsite-menu-item-wrap has-submenu">
<a class="wsite-menu-item">Work</a>
<span class="icon-caret"></span>
<div class="wsite-menu-wrap">
<ul class="wsite-menu">
</ul>
</div>
</li>
</ul>
</div>
I was able to crack the code...
$('li.has-submenu span.icon-caret').on('click', function(e) {
event.preventDefault();
var $me = $(this);
if ($me.parent().hasClass('open')) {
$me.parent().removeClass('open');
$me.find('.open').removeClass('open');
}
else {
$('.open').removeClass('open');
$me.parents('.has-submenu').children('.wsite-menu-wrap').addClass('open');
}
});

Check if elements with same attribute have any child elements that has classname active

I am trying to find if all (ul) elements have the matching data-validation of (required) AND any of its children (li) have the class of (active). I just want to make sure the (required) ul have active divs.
My code is of the following:
<div class="fields">
<ul class="ul-cls" data-validation="required">
<li><div class="active"></div></liv>
<li><div class=" "></div></liv>
</ul>
<ul class="ul-cls" data-validation="required">
<li><div class="active"></div></liv>
<li><div class=" "></div></liv>
<li><div class=" "></div></liv>
<li><div class="active"></div></liv>
</ul>
<ul class="ul-cls" data-validation="not-required">
<li><div class="active"></div></liv>
<li><div class="active"></div></liv>
</ul>
</div>
My JavaScript code is:
$(".fields .ul-cls").each(function() {
if ($(".ul-cls", this).attr('data-validation') == 'required') {
if ($("li div.active").length >=1) {
// Do something
}
}
});
You can use Array.prototype.every to check that every .fields .ul-cls[data-validation="required"] has an .active descendant. Also note that you should end <li> tags with </li>, not </liv>:
const allActive = Array.prototype.every.call(
$('.fields .ul-cls[data-validation="required"]'),
ul => $(ul).find('.active').length >= 1
);
if (allActive) {
console.log('all are active!');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="fields">
<ul class="ul-cls" data-validation="required">
<li>
<div class="active"></div>
</li>
<li>
<div class=" "></div>
</li>
</ul>
<ul class="ul-cls" data-validation="required">
<li>
<div class="active"></div>
</li>
<li>
<div class=" "></div>
</li>
<li>
<div class=" "></div>
</li>
<li>
<div class="active"></div>
</li>
</ul>
<ul class="ul-cls" data-validation="not-required">
<li>
<div class="active"></div>
</li>
<li>
<div class="active"></div>
</li>
</ul>
</div>
Non-passing example:
const allActive = Array.prototype.every.call(
$('.fields .ul-cls[data-validation="required"]'),
ul => $(ul).find('.active').length >= 1
);
if (allActive) {
console.log('all are active!');
} else {
console.log('fail');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="fields">
<ul class="ul-cls" data-validation="required">
<li>
<div>this one is required but not active</div>
</li>
<li>
<div class=" "></div>
</li>
</ul>
<ul class="ul-cls" data-validation="required">
<li>
<div class="active"></div>
</li>
<li>
<div class=" "></div>
</li>
<li>
<div class=" "></div>
</li>
<li>
<div class="active"></div>
</li>
</ul>
<ul class="ul-cls" data-validation="not-required">
<li>
<div class="active"></div>
</li>
<li>
<div class="active"></div>
</li>
</ul>
</div>
This seems to work!
SetTimeout(function(){
var numReq = $('.fields .ul-cls[data-validation="required"]').length,
numSel = $('.fields .ul-cls[data-validation="required"] li div.active').length;
console.log(numReq+"->"+numSel);
if(numSel >= numReq){
alert('validated!')
}else{
console.log('not valid')
}
}, 100);
// Set Timeout because click action delays update
Use find to get the desired element / class inside your ul-cls class with this, like below. I edited your HTML content in the snippet and added active class on the first ul div to check the condition.
$(".fields .ul-cls").each(function() {
if ($(this).attr('data-validation') == 'required') {
if ($(this).find($("li div.active")).length == $(this).find($(" li div")).length) {
console.log('Pass the test')
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="fields">
<ul class="ul-cls" data-validation="required">
<li>
<div class="active"></div>
</li>
<li>
<div class="active"></div>
</li>
</ul>
<ul class="ul-cls" data-validation="required">
<li>
<div class="active"></div>
</li>
<li>
<div class=" "></div>
</li>
<li>
<div class=" "></div>
</li>
<li>
<div class="active"></div>
</li>
</ul>
<ul class="ul-cls" data-validation="not-required">
<li>
<div class="active"></div>
</li>
<li>
<div class="active"></div>
</li>
</ul>
</div>

Display selected attribute value in else condition

Below I am looking through a list of swatches and assigning the title attribute to variable and then displaying this value below the swatch.
On mouseleave if the parent has selected class I return false so that the title attribute value is still shown. However if I mouseleave from swatch where parent does not have selected class the title attribute value becomes empty as shown in the code.
How do I modify so that on mouseleave if parent does not have selected class, it uses the title attribute value from the parent selected class?
$('.producttile_swatches .swatches ul li span.swatch_color').each(function(){
$(this).mouseenter(function(){
var swatchColor = $(this);
var swatchTitle = swatchColor.attr('title');
var swatchTitleInsert = swatchColor.closest('.carousel').next();
swatchTitleInsert.html(swatchTitle);
$(this).mouseleave(function(){
if($(this).parent().hasClass('selected')){
return false;
} else {
//I want to display title attr value from parent selected//
swatchTitleInsert.html('');
}
});
});
});
span {display:block;margin-bottom:10px;width:50px;height:50px;background:#ccc;}
.swatch-title-insert {width:300px;height:50px;background:blue;color:#fff;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="carousel producttile_swatches">
<div class="swatches">
<ul>
<li class="product_swatch_list_item">
<a href="#" class="selected">
<span class="swatch_color" title="red"></span>
</a>
</li>
<li class="product_swatch_list_item">
<a href="#">
<span class="swatch_color" title="white"></span>
</a>
</li>
<li class="product_swatch_list_item">
<a href="#">
<span class="swatch_color" title="blue"></span>
</a>
</li>
</ul>
</div>
</div>
<div class="swatch-title-insert"></div>
<div class="carousel producttile_swatches">
<div class="swatches">
<ul>
<li class="product_swatch_list_item">
<a href="#">
<span class="swatch_color" title="red"></span>
</a>
</li>
<li class="product_swatch_list_item">
<a href="#" class="selected">
<span class="swatch_color" title="white"></span>
</a>
</li>
<li class="product_swatch_list_item">
<a href="#">
<span class="swatch_color" title="blue"></span>
</a>
</li>
</ul>
</div>
</div>
<div class="swatch-title-insert"></div>
<div class="carousel producttile_swatches">
<div class="swatches">
<ul>
<li class="product_swatch_list_item">
<a href="#">
<span class="swatch_color" title="red"></span>
</a>
</li>
<li class="product_swatch_list_item">
<a href="#">
<span class="swatch_color" title="white"></span>
</a>
</li>
<li class="product_swatch_list_item">
<a href="#" class="selected">
<span class="swatch_color" title="blue"></span>
</a>
</li>
</ul>
</div>
</div>
<div class="swatch-title-insert"></div>
I think this is your answer:
$('.producttile_swatches .swatches ul li span.swatch_color').each(function(){
var swatchColor = $(this);
var swatchTitle = swatchColor.attr('title');
var swatchTitleInsert = swatchColor.closest('.carousel').next();
$(this).mouseenter(function(){
swatchTitleInsert.html(swatchTitle);
$(this).mouseleave(function(){
if($(this).parent().hasClass('selected')){
return false;
} else {
var swatchTitle = $(this).closest('.producttile_swatches').find('.swatches ul li a.selected span.swatch_color').attr('title');
swatchTitleInsert.html(swatchTitle);
}
});
});
});
span {display:block;margin-bottom:10px;width:50px;height:50px;background:#ccc;}
.swatch-title-insert {width:300px;height:50px;background:blue;color:#fff;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="carousel producttile_swatches">
<div class="swatches">
<ul>
<li class="product_swatch_list_item">
<a href="#" class="selected">
<span class="swatch_color" title="red"></span>
</a>
</li>
<li class="product_swatch_list_item">
<a href="#">
<span class="swatch_color" title="white"></span>
</a>
</li>
<li class="product_swatch_list_item">
<a href="#">
<span class="swatch_color" title="blue"></span>
</a>
</li>
</ul>
</div>
</div>
<div class="swatch-title-insert"></div>
<div class="carousel producttile_swatches">
<div class="swatches">
<ul>
<li class="product_swatch_list_item">
<a href="#">
<span class="swatch_color" title="red"></span>
</a>
</li>
<li class="product_swatch_list_item">
<a href="#" class="selected">
<span class="swatch_color" title="white"></span>
</a>
</li>
<li class="product_swatch_list_item">
<a href="#">
<span class="swatch_color" title="blue"></span>
</a>
</li>
</ul>
</div>
</div>
<div class="swatch-title-insert"></div>
<div class="carousel producttile_swatches">
<div class="swatches">
<ul>
<li class="product_swatch_list_item">
<a href="#">
<span class="swatch_color" title="red"></span>
</a>
</li>
<li class="product_swatch_list_item">
<a href="#">
<span class="swatch_color" title="white"></span>
</a>
</li>
<li class="product_swatch_list_item">
<a href="#" class="selected">
<span class="swatch_color" title="blue"></span>
</a>
</li>
</ul>
</div>
</div>
<div class="swatch-title-insert"></div>

How to apply classes based on the open linked?

My sidebar menu has the ability to expand and reveal the subsections of a section as shown below. The open section has the open active class and the clicked link has the active class.
All of my links has a different #url.So this will determine the classes.
How can I automatically place the open active and active classes based on the opened link? I can also use PHP.
<ul class="menu-items scroll-content">
<li class="open active">
<a href="javascript:;"><span class="title">first section</span>
<span class="open arrow"></span></a>
<span class="icon-thumbnail">LV</span>
<ul class="sub-menu">
<li class="active">
First Section 1
<span class="icon-thumbnail">au</span>
</li>
<li class="">
First Section 2
<span class="icon-thumbnail">ou</span>
</li>
</ul>
</li>
<li class="">
<a href="javascript:;"><span class="title">Second section</span>
<span class="arrow"></span></a>
<span class="icon-thumbnail">LV</span>
<ul class="sub-menu">
<li class="">
Second Section 1
<span class="icon-thumbnail">au</span>
</li>
</ul>
</li>
</ul>
Try like this:
HTML:
<ul>
<li class="">
<a href="javascript:;"><span class="title">first section</span>
<ul class="sub-menu">
<li class="">
First Section 1
<span class="icon-thumbnail">au</span>
</li>
<li class="">
First Section 2
<span class="icon-thumbnail">ou</span>
</li>
</ul>
</li>
<li class="">
<a href="javascript:;"><span class="title">Second section</span>
<ul class="sub-menu">
<li class="">
Second Section 1
<span class="icon-thumbnail">au</span>
</li>
</ul>
</li>
</ul>
JS:
var href = location.pathname+location.hash;
$('.sub-menu > li > a').each(function() {
if ($(this).attr("href") == href) {
$(this).parent('li').addClass('active');
$(this).parent().parent().parent('li').addClass('open active');
}
});

Detect li hover and slide down child ul

I have this HTML, where .subul is hidden with display: none:
<li class="par cat-item cat-item-2">
<a href="category/environment">
<span class="category-text">Environment</span>
<span class="count"><span class="count-hidden">9</span></span>
</a>
<ul class="subul">
<li class="cat-item cat-item-40">
<a href="category/environment/test">
<span class="category-text">test</span>
<span class="count">
<span class="count-hidden">1</span>
</span>
</a>
</li>
</ul>
</li>
I want when li.par is hovered to slide down its child ul (if it has it), however I can't even seem to get it to just trigger on hover. Here's what I tried:
$('body').on('mouseenter', 'li.par', function() {
if ($(this).children("ul").length) {
alert('code');
}
$(this).children("ul").slideDown();
alert('code');
});
EDIT css
ul.subul {
display: none;
}
Try this:
$('li.par').hover(function(){
$(this).children('ul.subul').slideDown();
},function(){
$(this).children('ul.subul').slideUp();
});
Please Use This :
$('body').on('mouseenter', 'li.par', function() {
$(this).find("ul").slideDown();
});
$('body').on('mouseleave', 'li.par', function() {
$(this).find("ul").slideUp();
});
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.js"></script>
<ul>
<li class="par cat-item cat-item-2">
<a href="category/environment">
<span class="category-text">Environment</span>
<span class="count"><span class="count-hidden">9</span></span>
</a>
<ul class="subul" style="display:none">
<li class="cat-item cat-item-40">
<a href="category/environment/test">
<span class="category-text">test</span>
<span class="count"><span class="count-hidden">1</span></span>
</a>
</li>
</ul>
</li>
<li class="par cat-item cat-item-2">
<a href="category/environment">
<span class="category-text">Environment</span>
<span class="count"><span class="count-hidden">10</span></span>
</a>
</li>
</ul>

Categories