Toggle only when parent list items is clicked - javascript

I have a simple ol li based list which toggles when i click on parent item or child item. I want it to toggle only when parent item is clicked.
$("#expList > li").click(function () {
$(this).find("ol").slideToggle();
});
https://jsfiddle.net/k2jqqbbk/3/
I tried to target it with $("#expList ol li") but this is not working. I tried few other options which didn't work either.

You could use the event.target to check whether its closest li contains an ol, and only toggle if it does:
$('#expList > li').click(function(evt) {
if ($(evt.target).closest('li').has('ol').length) {
$(this).find("ol").slideToggle();
}
});
Here's a fiddle

You need to target the a tag. Because the ol is the next child, the find call has been replaced with a call to next:
$("#expList > li > a").click(function () {
$(this).next().slideToggle();
});
If you want the functionality to extend to children of children, just omit #expList from the selector:
$("li > a").click(function () {
$(this).next().slideToggle();
});
Fiddle

Try to add the following code :
$("#expList > li").click(function () {
$(this).find("ol").slideToggle();
});
$("#expList > li ol li").click(function () {
return false;
});

The click event bubbles up to ancestor elements. So the click is fired first against the second-level list items, then bubbles up to the first-level list items. This is why you're seeing the toggling happen.
All you need to do is stop the click event bubbling up the element chain from the second-level list items.
Add this to fix:
$("#expList ol li").click(function(e) {
e.stopPropagation();
});
Here's the example: https://jsfiddle.net/sxn5bg3x/

Related

Jquery only allow one menu item to be expanded

So I have this code from a previous question: http://jsfiddle.net/928Dj/4/
$("ul.opt").addClass("hidden");
$('#filter > li > a').on("click", function(e) {
$(this).next('ul').toggle();
});
I was wondering if anyone could tell me how I allow it to still be toggled open and closed, but also make it so if one menu is open and I click to open another menu, it closes the first one, meaning only one menu can be open at any time.
Try to hide the opened ul elements first and then toggle the current element,
$("ul.opt").addClass("hidden");
$('#filter > li > a').on("click", function (e) {
var cache = $(this).next('ul');
$('#filter ul:visible').not(cache).hide();
cache.toggle();
});
DEMO
You can hide all the visible submenus before showing the current one as follows
$("ul.opt").addClass("hidden");
$('#filter > li > a').on("click", function(e) {
var ul = $(this).next('ul');
$('ul li ul:visible').not(ul).hide();
ul.toggle();
});
Demo
This is the best way. You can also try this:
$("ul.opt").addClass("hidden");
$('#filter > li > a').on("click", function(e) {
$(this).next('ul').toggle();
$(this).parent().siblings().find('.opt').hide();
});
Fiddle

Adding and removing click/hover event handlers jQuery

Run into issues mixing click and hover events.
Clicking an inactive li a element toggles an active class and binds a hover event.
Hovering over now active element displays a previously hidden block (span.rate)
Clicking the hovered element is supposed to hide it, remove hover event and toggle the active class on the parent so it is no longer 'active'.
Clicking the hovered event does not remove the events and toggle active. There is some other logic in there regarding mutually exclusive options, this all works fine though.
jsfiddle of how it all sits together:
http://jsfiddle.net/65yY3/15/
Current js:
ps = {
psToggle: 0,
init: function () {
$(document).ready(function () {
$('.example li a)').on('click', function(e) {
e.preventDefault();
var that = $(this);
if (that.parent().hasClass('paired')) {
if (rm.psToggle === 0) {
that.toggleClass('active');
that.find('.rate').fadeToggle(50);
rm.psToggle = 1;
} else {
if (that.hasClass('active')) {
that.toggleClass('active');
that.find('.rate').fadeToggle(50);
rm.psToggle = 0;
} else {
$('.paired a').toggleClass('active');
that.find('.rate').fadeToggle(50);
//Call message function
}
}
rm.pControl();
} else {
that.toggleClass('active');
that.find('.rate').fadeToggle(50);
rm.pControl();
}
});
});
},
pControl: function () {
//Unbind events to all control items excluding 1st item.
$('.example li a').off('hover');
$('.example li a .rate').off('click');
$('.example .active').each(function(i) {
$(this).on('hover', function() {
$(this).find('.rate').fadeToggle(50);
});
});
$('.example li a.active .rate').on('click', function() {
//Remove hover/hide and toggle active state
$(this).off('hover');
$(this).hide();
$(this).parent().toggleClass('active');
rm.pControl(); //rebind new active classes
});
}
};
ps.init();
Check the below demos.
Both the click events were getting fired as ,.rate is the child of a.
$('.example li a.active .rate').on('click'... and
$('.example li a').on('click'...
So you can either remove the click on .rate. Demo1
Or add e.stopPropagation(); to the child to stop event bubbling from parent to child. Demo2
$('.example li a.active .rate').on('click', function(e) {
e.stopPropagation();
//Remove hover/hide and toggle active state
$(this).off('hover');
$(this).hide();
$(this).parent().toggleClass('active');
ps.pControl(); //rebind new active classes
});
enter link description hereCorrect
$('.example li a') instead of $('.example li a)')
update here is the link

Watch elements count by class using jQuery

I have simple HTML:
ul > li > button
And have some JavaScript code:
$('.side-filters .filters_list li').each(function(){
$(this).find('button').click(function(){
var arrList = $('.side-filters .filters_list li .active').map(function(){
return $(this).attr('id');
}).get();
if($(this).hasClass('active')) {
$(this).removeClass('active');
} else {
$(this).addClass('active');
}
});
});
If I click on a button, add class 'active' to the button, and if clicked again, remove class.
I need live count elements witn class 'active'. If there is at least one given ul class 'someclass' and if I click again and have no elements with class active, remove 'someclass' from the Ul.
How can I do this?
There is no need to loop through the elements and add a click to every button. Add one listener.
//listen for click on a button
$('.side-filters', "click", ".filters_list li button", function(){
//toggle the active class on the button
var button = $(this).toggleClass("active");
//see if anything is selected
var hasSelection = $('.side-filters .filters_list li .active').length > 0;
//toggle a class on the closest ul based on if anything is selected.
button.closest("ul").toggleClass("someclass", hasSelection);
});
References:
toggleClass(class [, switch])
.closest( selector )
You can add this function ()
function someclass () {
var count = $('.active').length;
if (count >= 1) {
$('ul').addClass('clasHere')
} else {
$('ul').removeClass('clasHere')
}
}

How to prevent assigning click event on child items?

I made an click event for .menu li which has ul in it using $(".menu li:has(ul)"). It works but it also assigns the same event to .menu li ul li. I tried using e.stopPropagation();, e.PreventDefault(); and return false; inside function but that didn't worked at all. How to prevent that?
Here's the fiddle to show up actual problem.
jQuery I used:
$(".menu li:has(ul)").click(function() {
console.log('has ul');
if($(this).children("ul").is(':visible')){
$(this).children("ul").slideUp();
}else{
$(this).children("ul").slideDown();
}
});
Try this instead:
$('.menu a').click(function() {
var next=$(this).next();
if(next.prop('tagName')=='UL') {
if(next.is(':visible')){
next.slideUp();
}else{
next.slideDown();
}
}
});
It's Works now Fiddle you need to add return false on child UL

How to add a class onto the selected li element and make li full-sized-clickable

I want to add a class to the selected 'li' and at the same time, remove the class:selected from previous selected li element.
I have worked on it hours and still haven't got any luck. I also checked others questions, but their solutions don't work for me.
Help please....
<ul id='mainView' class='menu' style='float: left; clear: both;'>
<li>Patient</li>
<li>Recommendations</li>
</ul>
<script type="text/javascript">
$(document).ready(function () {
$('.menu ul a').on('click', function (event) {
$('.menu ul a.selected').className = '';
alert($(this).attr('id'));
$(this).attr('class') = 'selected';
});
});
// $('.menu li').on('click', function () {
// $('.menu li.selected').className = '';
// this.className = 'selected';
// });
</script>
Update:
I did put a inside li, but if I click on the li not the a inside of the li, the webpage does not redirect. That's the reason why I do it in a reversed way.
Update 2
The reason why the selected li does not get the "selected" class is because the whole webpage is redirected to a new page which has the same navigation bar.
So now the question is how to highlight the selected li(it was selected on the previous page) on the new webpage.
Inside an UL everybody (even a browser) is expecting to see a LI
so your HTML:
<ul>
<li>Patient</li>
<li>Recommendations</li>
</ul>
And your jQ:
$('ul li').click(function(){
$(this).addClass('selected').siblings().removeClass('selected');
});
Building web pages you should know how to treat LI elements. Simple, like dummy containers with minimal styling.
That means that you rather add a display:block ... float:left and other cool stuff to the <A> elements, than setting a padding there you go with your full-sized-clickable A elements.
Additionally (if you don't have time to play with CSS) to make a LI fully clickable use:
$('ul li').click(function(){
var goTo = $(this).find('a').attr('href');
window.location = goTo ;
// $(this).addClass('selected').siblings().removeClass('selected'); // than you don't need this :D
});
After the OP late edit - and to answer the question
After the pages refreshes to get which one is the active one use:
// ABSOLUTE PATH
var currentPage = window.location;
// RELATIVE PATH
// var currentPage = window.location.pathname;
$('li a[href="'+ currentPage +'"]').addClass('selected');
<script type="text/javascript">
$(document).ready(function () {
$('.menu ul a').on('click', function (event) {
$('.menu ul a.selected').removeClass('selected');
alert($(this).attr('id'));
$(this).addClass('selected')
});
});
</script>
Try addClass and removeClass, they're jQuery functions:
$(document).ready(function () {
$('.menu ul a').on('click', function (event) {
$('.menu ul a.selected').removeClass("selected");
$(this).addClass('selected');
});
});

Categories

Resources