Why can't jquery remove these classes? - javascript

I have created a series of elements that when you click on any one of them, they will expand, pushing the other elements out of the way. Initially if you clicked on it again the element would contract, but now I want to take the close functionality and put it in a button with in the element.
Initially when you click on the element, I use jQuery to add a number of classes to a variety of elements.
$(".left > .elem").click(function () {
$(this).addClass("expand");
$(this).parent().addClass("WithLarge");
$(this).children(".bar").addClass("visible");
$(this).children(".reduce_button").addClass("visible");
$(".right").addClass("shift_right");
});
When I click the close button I would like to remove those classes.
$(".reduce_button").click(function () {
$(this).parent().removeClass('expand');
$(this).parent().removeClass("WithLarge");
$(this).parent().children(".bar").removeClass("visible");
$(this).parent().children(".reduce_button").removeClass("visible");
}
The problem is, those classes aren't budging.
You can try it out on the JSFiddle
Click on the yellow box(".left > .elem"), it expands pushing the others out of the way, click on the red box(".reduce_button"), and nothing happens. I tried
console.log($(this).parent().hasClass('expand'));
$(this).parent().removeClass('expand');
console.log($(this).parent().hasClass('expand'));
to see if it has been removed. It returns false, even though the class is still there.
Why can't I remove these classes?

You ARE removing the class. But, the click on the .reduce_button is also triggering the .elem click event, which adds the class back again.
EDIT:
As commented below by j08691, you can add stopPropagation to keep the event of going on to the next listener, like:
$(".reduce_button").click(function (e) {
$(this).parent().removeClass('expand');
e.stopPropagation();
...
Here is your fiddle updated: http://jsfiddle.net/HybHK/9/

Related

Jquery open and close within a parent div

The title does not explain that well, essentially I have 8 divs the same, with the same class for css styling.
They all have hidden content, I want to be able to only expand one div at a time without using different classes or identifiers for each div and hidden content.
I have tried to display this on Jsfidle using two divs the same , however I can't even get it to fire on jsfiddle for some reason
http://jsfiddle.net/dAXJ2/8/
$(document).on('click',".servicereadmore",function() {
//var x = $(this).closest('div').attr('class')
//$('.hiddenservices').parent(x).slideDown(1000);
$('.hiddenservices').slideDown(1000);
$(this).html("Read less");
$(this).removeClass("servicereadmore");
$(this).addClass("servicereadless");
});
$(document).on('click', ".servicereadless" ,function() {
$('.hiddenservices').slideUp(1000);
$(this).html("Read more");
$(this).removeClass("servicereadless");
$(this).addClass("servicereadmore");
});
That currently works above but opens all the hidden text as stated, the comments are were I have been trying to only expand within the parent div of the button I pressed
Your clickable <a> tags should probably be buttons, since that's the role they're in. Also, your functions aren't working currently because you've added
return false;
as the first statement of each one. That prevents any of the code after that from ever running. Instead of that, either change those <a> links to <button type=button> or else add a parameter to the handlers ("e" or "event") and call
e.preventDefault();
in the handler.
To affect only the portion of the page relevant to the "Read More" links, you just need to navigate the DOM:
$(this).closest('.myinfo').find('.hiddenservices').slideDown(1000);
That means: "staring from the clicked element, climb up the DOM to find the closest element with class 'myinfo', and then from that point down find all the elements with class 'hiddenservices' and slide them down."
A couple of other problems: you'll need to start the "hiddenservices" sections off as hidden, or otherwise not visible somehow. Also, another issue with your jsfiddle was that you didn't have jQuery selected. That's something you could quickly learn just by checking the error console.
Here is a repaired jsfiddle.
You dont have to use that much of code for this purpose. USe simply like
$(document).on('click', ".servicereadmore", function (e) {
e.preventDefault();
if ($(this).parent().find('.hiddenservices').is(":visible")) {
$(this).html("Read more");
} else {
$(this).html("Read less");
}
$(this).parent().find('.hiddenservices').slideToggle(1000);
});
Instead of adding and removing the class name, you can just use slideToggle().
Demo

Jquery click function exclude children

Hey I'm having an issue figuring this one out.
JS
$('.jrm-menu-categories,#overlay-2').click(function() {
$('#overlay-2').toggle();
$('#overlay-3').hide();
});
HTML
<ul id="megaUber" class="megaMenu">
<li id="menu-item-1459" class="jrm-menu-categories">
<ul class="sub-menu sub-menu-1">
So basically what my JS does is create an overlay/modal effect when a sub menu is opened via click. I have the code repeated a few times with different classes and overlay ids hence the last line of code (needed so that only one overlay is shown at a time). Quickest and simplest way for a beginner like me, but that's not the subject.
When a sub-menu is open, and a user clicks anywhere in the sub-menu it toggles the overlay. I'm assuming this is because when I selected .jrm-menu-categories in the JS, it also selected the child elements, which happen to be .sub-menu
I'm thinking I need to use the .not() function, but can't figure it out.
can you guys help me with this? if possible write the code so I can try it out
Thanks!
You can try adding a second click handler to the children that will always return false. That way the click won't propagate up and dismiss:
$('.jrm-menu-categories').children('.sub-menu').click(function (e) {
e.stopPropagation(); // prevent click propagation, so parent click never fires.
})
You can test for the clicked item.
$('.jrm-menu-categories,#overlay-2').click(function(e) {
if (this == e.target){
$('#overlay-2').toggle();
$('#overlay-3').hide();
}
});

onclick dropdown menu with a form, click outside to close

ive got a drop down menu with form elements. the menu element gets set to
display:none
when anything outside the element is clicked ... or at least so i thought.
Here's my little function
$(function(){
$('#loginAcc').click( function(event){
event.stopPropagation();
//show
$('#auth-menu').css('display', 'block');
});
$(document).click( function(){
//hide when click anywhere out the menu
$('#auth-menu').hide();
});
})
the problem i have is that it also closes when i click inside the element, which makes it very difficult, pretty much impossible to complete a form.
#loginAcc
is a horizontal list item that gets clicked, and
#auth-menu
is
if i were to hazard a guess, i would like to think that .toggle() is the culprit, but that's a sheer guess and i wouldn't even know where to start if i were to reimplement it (a little bird told me that it's getting taken out of the spec anyway).
what i would like to happen is that when you click on the #loginAcc list item, the #auth-menu gets set to display:block, and can only be closed if you reclick #loginAcc or anywhere else outside of #auth-menu.
any help would be amazing. thanks
Use a not() selector to exclude the menu:
$(document).not('#auth-menu').click( function(){
//hide when click anywhere out the menu
$('#auth-menu').hide();
});

Change Div Class on click takes multiple clicks before it works

I used the methods in this question:
change div class onclick on another div, and change back on body click
So here's my jQuery function:
jQuery('.checkbox_wrapper').on('click', function(e){
jQuery(this).parent()
.toggleClass('not_selected')
.toggleClass('selected');
});
However it doesn't seem to be working properly. It takes multiple clicks before the class changes.
See my jsfiddle:
http://jsfiddle.net/7A3vw/
I cut it down to the bare essentials thinking it might be conflicting javascript, but even with the single function it takes multiple clicks before the class actually changes. Because the production environment has 1 click toggle a hidden checkbox, multiple clicks is not reasonable.
Could someone help me figure out what's causing this issue?
The click function fires twice, once for the image, and once for the input, as both will bubble to the parent element, and firing twice reverts the classes again (proof).
Just target the image instead, as that is what you're really trying to click, not the parent :
jQuery('.deck_card img').on('click', function (e) {
jQuery(this).closest('div').parent().toggleClass('not_selected selected')
});
FIDDLE
i guest you need the checkbox checked together with the toggling of your div.
$(document).ready(function(e) {
$('.checkbox_wrapper').on('click', function(e){
var checked = $(this).find('input[type="checkbox"]').is(":checked");
if(checked){
jQuery(this).parent().addClass('selected').removeClass('not_selected');
}else{
jQuery(this).parent().addClass('not_selected').removeClass('selected');
}
});
});
Your code is triggering click event twice. So use .preventDefault()
This makes the default action of the event will not be triggered.
$('.checkbox_wrapper').on('click', function(e){
$(this).parent()
.toggleClass('not_selected')
.toggleClass('selected');
e.preventDefault(); // prevent the default action to be
}); // triggered for next time
Check this JSFiddle
try this
jQuery(document).on("click",'.checkbox_wrapper', function(e){
jQuery(this).parent()
.toggleClass('not_selected')
.toggleClass('selected');
});
Multiple Clicks are getting triggered because you are using class selector. You need to use not to exclude extra elements :
jQuery("div.checkbox_wrapper :not('div.checkboxdiv')").on('click', function(e){
jQuery(this).parent()
.toggleClass('not_selected selected')
});
Here is a FIDDLE.

change div class onclick on another div, and change back on body click

Let me define the problem a little bit more:
i have
<div class="contact">
<div id="form"></div>
<div id="icon"></div>
</div>
i want onclick on #icon, to change the class of .contact to .contactexpand( or just append it).
Then i want that the on body click to change the class back, but of course that shouldnt happen when clicking on the new class .contactexpand, and if possible that clicking on icon again changes the class back again.
I tried numerous examples and combinations but just couldn't get the right result and behavior.
Check this: Working example
Let's go step by step
I want onclick on #icon, to change the class of .contact to .contactexpand( or just append it). […] and if possible that clicking on icon again changes the class back again.
You want to use the toggleClass() method to achieve this. Simply:
$('#icon').on('click', function(e){
$(this).parent()
.toggleClass('contact')
.toggleClass('contactexpand');
});
Then i want that the on body click to change the class back
You will have to make sure that body removes contactexpand class and adds contact. At this point I would just give the container element an id (or class if you prefer), just to make things simpler. Then what you do is pretty simple:
$('body').on('click', function(e){
$('#thisdiv')
.removeClass('contactexpand')
.addClass('contact');
});
but of course that shouldnt happen when clicking on the new class .contactexpand.
This is the step that the other answers missed, I think. Since everywhere you click, you also click on the body element, you will always trigger the click event on the body, hence removing the contactexpand class and adding the contact one.
Enter event.stopPropagation(). This method will make sure that the events doesn't bubble up the DOM, and will not trigger the body click.
$('#thisdiv').on('click', function(e){
e.stopPropagation();
});
Working example
You can add a class to parent element like the following code.
$(".contact #icon").click(function(){
var element = $(this).parent(".contact");
element.removeClass("contact").addClass("contactexpand");
});
I like to the jQuerys toggleClass function like so:
$('#icon').click(function(){
$('#contactbox').toggleClass('contact');
$('#contactbox').toggleClass('contactexpand');
});
Or you could use addClass('className') and removerClass('className') if you would like to apend it rather than toggle it :)
Here is an example: http://jsfiddle.net/aUUkL/
You can also add an onclick event to the body of the page and use hasClass('className') to see whether or not to toggle the class when the body is clicked. You could use something like this (Although I havent tested this bit!):
$('body').click(function(){
if( $('#contactbox').hasClass('contactexpand') ){
$('#contactbox').addClass('contact');
$('#contactbox').removeClass('contactexpand');
}
});
You can do this
$('body').on('click', function(event) {
if ($(event.target).attr('id') == 'icon') {
$(event.target).parent().toggleClass('contactexpand');
} else {
$('.contact').removeClass('contactexpand');
}
});
Check out this jsfiddle
var $contact = $('.contact');
$contact.find('#icon').click(function(e, hide) {
e.stopPropagation();
$contact[hide ? 'removeClass' : 'toggleClass']('contactexpand');
});
$(document).on('click', function(e) {
if (e.srcElement === $contact[0]) return;
$contact.find('#icon').trigger('click', true);
});
http://jsfiddle.net/kZkuH/2/

Categories

Resources