jQuery set class not working after its already been set - javascript

trying to make a simple expanding heading script.
I don't wish to use accordions and just looking for a light weight home made solution. As i enjoy writing and learning things myself.
In my eyes, what i have should work. But it doesnt.
The aim is:
When a heading is clicked, all of the content is hidden and then the next content element after the heading is shown. This prevents more than one content being shown at any time.
After this, the div class gets changed to be a 'selected' state.
This works okay.
However, the next part runs if the heading class is the selected state, and if so it SHOULD change its class back to the normal and also hide the next element content.
The aim is to allow the hide / show options.
The latter part of changing back the class doesnt work however. I also know there is a much for efficient way of writing this, but not sure how.
JS:
$(function() {
$('.headingHelp').click(function(){
$('.infoHelp').fadeOut();
$(this).next('.infoHelp').fadeIn();
$(this).attr('class', 'headingHelp_sel');
});
$('.headingHelp_sel').click(function(){
$(this).next('.infoHelp').fadeOut();
$(this).attr('class', 'headingHelp');
});
});
Example HTML:
<p class="headingHelp">Content Heading</p>
<div class="infoHelp">
Content
</div>
<p class="headingHelp">Content Heading 2</p>
<div class="infoHelp">
Content 2
</div>
JSFiddle: http://jsfiddle.net/C7bHn/1/
Thanks in advance!

Since your "selected" class is added after the DOM is loaded, jQuery is not aware of it.
I suggest using jQuery's on() for delegated events. This will allow you to select dynamically generated classes:
$(document).on('click','.headingHelp',function(){
$('.infoHelp').fadeOut();
$(this).next('.infoHelp').fadeIn();
$(this).attr('class', 'headingHelp_sel');
});
$(document).on('click','.headingHelp_sel',function(){
$(this).next('.infoHelp').fadeOut();
$(this).attr('class', 'headingHelp');
});
Working Example (jsfiddle)
Edit:
Here's another method without using delegation. It just adds/removes a "sel" class rather than changing the class completely.
$('.headingHelp').click(function(){
// save clicked element in a variable for use below
$this=$(this);
// remove / add "selected" class
$('.headingHelp').removeClass('sel');
$this.addClass('sel');
// fade in / out content
$('.infoHelp').fadeOut();
$this.next('.infoHelp').stop().fadeIn();
});
.infoHelp {
display: none;
}
.headingHelp {
background-color:#999;
padding: 1%;
cursor: pointer;
color: white;
}
.headingHelp:hover,
.headingHelp.sel {
background-color:#666;
}
Working Example (jsfiddle)

jQuery selector working "AT CURRENT MOMENT" . Your selector $('.headingHelp_sel') empty when running this code.
Best code:
$(function() {
$('.headingHelp').click(function(){
var open = $(this).next('.infoHelp').is(':visible');
$('.infoHelp').fadeOut();
if(!open)
{
$(this).next('.infoHelp').fadeIn();
}
});
});

Related

Hide or remove div with dynamic class name

I had a problem that a new dynamic div is added with the dynamic class name while the page is refreshed every time.
For example
<div class="ABGeGGCcJeBCDEGD" data-app-name="">
Here the class=" ABGeGGCcJeBCDEGD", when I reload the page the class name is changed automatically.
So, I need to remove or hide that div.
Note
The div is not present in the code side, but it is created dynamically.
Thanks in advance
You should find another way to identify div instead of class name, e.g. DOM tree.
Also you can try to make "white list" of visible divs. Something like
Make ALL divs hidden
Get white list and show divs with these classes.
You can use event on id
Example is here.
$('#testDiv'). remove()
Let me know if this case is not going to work
You have 3 options, as far as I can see.
1. Does the class always start or end the same way?
If so, you can target that in CSS.
div[class^="ABGe"] { display: none; }
div[class$="DEGD"] { display: none; }
2. Does the element have any other classes or attributes that you can target.
If so, you can target them in CSS instead.
div[data-app-name] { display: none; }
3. Can you modify the markup?
If so, you can wrap the element in something that won't change.
<div class="hide-contents">
<div class="ABGeGGCcJeBCDEGD" data-app-name="">
</div>
You can then target that in CSS.
.hide-contents > div { display: none; }
I hope one of those options is useful.

jQuery.toggle() not working on a div

On a web page we have a list of profiles. On the right hand side of the profile is some text, followed by an arrow img#arrow.
When img#arrow is clicked, we have the following jQuery we hope to run:
However, the corresponding .bottom-sec is not toggling.
jQuery('#arrow').click(function(){
var $parent = $(this).parent();
$($parent).addClass('active');
jQuery($parent +' .bottom-sec').toggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="profile-right">
<h2>Bob Brown</h2>
<h3>Non-Executive Chairman</h3>
<p>Intially showing text.</p>
<div class="bottom-sec" style="display: none;">
<p>Initially hidden text.</p>
</div>
<img id="arrow" src="/wp-content/themes/wtc/images/icons/down-arrow-circle-hi.png">
</div>
Problem
The problem with your code is exactly what the comment on your question is saying, but he didn't explain anything:
You're combining two different ways of selecting elements. One is with selectors, the other is traversing. You're using them in a way which isn't possible (the $parent + ' .bottom-sec' part). The comment linked to a jQuery page about traversing which you should definitely read! It tells you a lot about how to use traversing functions, which you could use!
Solution
There are multiple solutions to this, but I'll write down the one I think is the best:
First of all, change the HTML a bit. I've removed the element style of .bottom-sec and changed the id of the image to a class, because you have multiple images with the same id on the page, which is not a recommended thing to do. Classes can occur more than once, id's cannot.
<div class="profile-right">
<h2>Bob Brown</h2>
<h3>Non-Executive Chairman</h3>
<p>Intially showing text.</p>
<div class="bottom-sec">
<p>Initially hidden text.</p>
</div>
<img class="arrow" src="/wp-content/themes/wtc/images/icons/down-arrow-circle-hi.png">
</div>
I've reduced the JavaScript to the following. Note that is just reduced to one line, where a click on the .arrow element goes searching for the closest .profile-right parent. If, for whatever reason, you decide to change the HTML and the .arrow element is no longer a child of the .profile-right, this code still works. The only thing it does is toggle an active class on the .profile-right.
jQuery(document).on('ready', function() {
jQuery('.arrow').on('click', function(){
jQuery(this).closest('.profile-right').toggleClass('active');
});
});
The document ready listener was added because of OP's comment.
With CSS, we can use the new .active class to show or hide the element.
.profile-right .bottom-sec {
display: none
}
.profile-right.active .bottom-sec {
display: block
}
Original Code Fix
If for some reason you wanted to use your original code, this is how it should be:
// Nothing wrong about this part.
// Your only worry should be that there could be
// multiple elements with the same ID, which is something really bad.
jQuery('#arrow').click(function(){
// This part is correct, no worries
var $parent = $(this).parent();
// Removed the $(...), because $parent is already a jQuery object
$parent.addClass('active');
// Changed the selector to a find function
$parent.find('.bottom-sec').toggle();
});
You could also combine all of the code inside the listener function to just one line:
jQuery('#arrow').click(function(){
$(this).parent().addClass('active').find('.bottom-sec').toggle();
});
Change your js code like below.
jQuery('#arrow').click(function(){
var $parent = $(this).parent();
$($parent).addClass('active');
jQuery($parent).find('.bottom-sec').toggle();
});
In your event listener you can catch the element (the down arrow) that triggered the event. It will be referred as this.
Then you can go through the DOM tree using .next() and .parent() to access the <div> to toggle.
Note: you may need more functions than the one I explained above.
Note 2: without code or more detailed information, we can't help you further, I will edit this answer if you add details.

JavaScript: How can I change the class of a div by clicking another div?

I want to make a div appear when I click on another div. I was thinking of doing this by using JavaScript to change the class of the div when the other div is clicked on.
This is the HTML of the div I want to appear:
<div id="menutext1" class="hidden"></div>
This is the HTML of the control div (the one to click on to make the above div appear):
<div id="menu1"></div>
This is the CSS:
.hidden { display: none; }
.unhidden { display: block; }
I've looked everywhere and nothing seems to work for me!
I don't have much experience with JavaScript or JQuery but I can understand it.
Thanks in advance :))
.addClass(), .removeClass() should do what you need. .toggleClass() might also be useful. You want to do something like this in your onClick() method:
$('#menu1').click(function() {
$('#menutext1').addClass('unhidden')
});
Swap in toggleClass() if you want to be able to hide/unhide. I should add that these are JQuery functions so make sure to include JQuery in your project.
You have several options to achieve this:
$('#menu1').on('click', function(){
$('#menutext1').show();
// OR
$('#menutext1').toggleClass('hidden unhidden');
// OR
$('#menutext1').removeClass('hidden ').addClass('unhidden');
});
Demo
Note: When working with jQuery and DOM-Manipulation have a look at the .ready() function.
Reference
.on()
.toggleClass()
.removeClass()
.addClass()
.show()
You can do it without JQuery using the classList.toggle method. And you don't really need the unhidden class. When the hidden class is toggled off, the div should return to its default display (block).
// get the element you want to click on
var controlDiv = document.getElementById('menu1');
// assign a function to run when it is clicked
controlDiv.addEventListener('click', function() {
// turn the hidden class off or on
document.getElementById('menutext1').classList.toggle('hidden');
});

Changing CSS class in jQuery

I'm trying to change the CSS class of a couple DIVs, Linked below is my jFiddle
The only change is that the -selected class actually has a background image which seems to have the background color of the -non-selected class.
The other problem is after selecting another div, you can't select the first one again. What exactly is jQuery doing with the classes? When I add the -non-selected class to it, it should become select-able again, right?
http://jsfiddle.net/9FZcz/
jQuery
$(".selector-box").click(function () {
$(".selector-box-selected").removeClass("selector-box-selected").addClass("selector-box");
$(this).removeClass("selector-box").addClass("selector-box-selected");
});
HTML
<div class="selector-box-selected"></div>
<div class="selector-box"></div>
<div class="selector-box"></div>
<div class="selector-box"></div>
CSS
.selector-box{
margin-bottom:2px;
width:328px;
height:46px;
background-color:rgba(255,255,255,.25);
}
.selector-box-selected{
margin-bottom:2px;
width:351px;
height:46px;
background-image:url(../images/layout/SelectedArrow.png);
}
You should try another way to adding and removing classes, try this one :
$(".selector-box").click(function () {
$('.selector-box').removeClass("selected");
$(this).addClass("selected");
});
Updated JsFiddle
The problem with not being able to select the first one again is that the click event is not being linked to it, since you only apply it to the <div> elements with the class .selector-box. Apart from that, CSS seems fine, check the fiddle: http://jsfiddle.net/9FZcz/2/
I change your code abit
<div name="ss" class="selector-box-selected"></div>
<div name="ss" class="selector-box"></div>
<div name="ss" class="selector-box"></div>
<div name="ss" class="selector-box"></div>
$("div[name=ss]").click(function () {
$("div[name=ss]").removeClass("selector-box-selected").addClass("selector-box");
$(this).removeClass("selector-box").addClass("selector-box-selected");
});
don't mind a name SS, change it to what you want :D
There are already answers posted that suggests solutions that requires some refactoring, like adding a selected class to selected elements rather than having seperate selector-box-selected and selector-box classes.
While I think you should perform the refactoring since it makes the overall design better and leads to less CSS code duplication, here's a solution without refactoring the code.
I kept track of the last selected element to avoid looping over all of boxes to remove the selected class.
DEMO
var selectedBox = $('.selector-box-selected').get();
$('.selector-box').add(selectedBox).click(function () {
if (selectedBox === this) return;
selectedBox = $([this, selectedBox])
.toggleClass('selector-box-selected')
.toggleClass('selector-box')
.get(0);
});

jQuery toggle - Close all except this

I have found this code (jQuery):
$('.toggle').click(function() {
$('.container').eq($(this).index()).toggle('fast');
});
This is my HTML:
<h4 class="toggle">Title1</h4>
<h4 class="toggle">Title2</h4>
<h4 class="toggle">Title3</h4>
<div class="container">Content1</div>
<div class="container">Content2</div>
<div class="container">Content3</div>
CSS
.container {
display: none;
}
I can toggle what I want with it.
The problem
When I click the toggle-class I want to close all open container-classes BUT NOT the current container-class (because it should be toggled).
The current container-class should toggle. That means that all elements could be closed BUT ONLY ONE could be opened at the same time.
I tried to just put jQuery hide before the script but that makes the container-class impossible to close (because when toggle hide is equal to show).
Code guess hide all .container except this
Using David's answer as a starting point, we can use .siblings to accomplish what you want:
$('.toggle').click(function() {
var index = $(this).index();
$('.container').eq(index).toggle().siblings('.container').hide();
});
See: http://www.jsfiddle.net/85zCp/
As an aside, you might want to use JavaScript to hide all elements initially instead of CSS because users with JavaScript disabled won't be able to see any content if you use CSS to hide them. Also, you would probably want to have each h4 heading in front of the contents instead of it put together like you're doing right now.
$('.toggle').click(function () {
$('.container').hide('fast');
$('.container').eq($(this).index()).show('fast');
});
I don't know exactly but I think this is what you're looking for...
Cheers...
This is a little verbose, but its use should be fairly obvious:
$('.toggle').click(
function(){
var index = $(this).index();
$('.container').hide().eq(index).show();
});
JS Fiddle demo.

Categories

Resources