1

I am trying to toggle a div by clicking on a different div. The only relation that two divs share is that they are inside the same div. I have a DIV class comment which holds DIV class button that is supposed to toggle DIV class box when clicked. The box DIV is also inside the comment DIV. I am trying to use jQuery(this).find(".box").toggle();, but it is not working. I am triggering it with $( ".button" ).click(function(). The script is currently at the bottom of my body.

Could anyone please tell me what am I doing wrong here? I've been playing around with the function for a while now, but with no luck at all. Thank you in advance for your replies.

JSFIDDLE here

HTML

<div class="comment">
    <div class="button">
        show/hide .box with text1
    </div>

    <div class="box">
        text 1
    </div>
</div>

<div class="comment">
    <div class="button">
        show/hide .box with text2
    </div>

    <div class="box">
        text 2
    </div>
<div>

jQuery

$( ".button" ).click(function() {
    jQuery(this).find(".box").toggle();
});
SpYk3HH
  • 22,272
  • 11
  • 70
  • 81
Cream Whipped Airplane
  • 1,305
  • 3
  • 13
  • 31
  • Updated answer with prolly more explanation than you want, but should give you full idea of what is going on and how to make better use of this information in the future. Hope it helps! – SpYk3HH Jan 20 '14 at 20:30

3 Answers3

0

In short, change:

jQuery(this).find(".box").toggle();

To ONE of the following lines:

$(this).parent('.comment').find(".box").toggle();
$(this).closest('.comment').find(".box").toggle();
$(this).siblings(".box").toggle();

Full Explanation:

The reason it's not working is due to the call. Let's break down your call and see what exactly it's doing.

First we see a simple jQuery selector. This tells jQuery to look for a div containing the class button. Keep in mind, jQuery makes use of any CSS selector. So selecting an item in jQuery is as simple as using it's CSS selector!

$( ".button" )

Next you are assigning an event. In this case, that event is click, meaning you're telling a div having the class button to do something every time it is clicked. Keep in mind, however, not including a callback function is an easy way to trigger this event as well.

$( ".button" ).click(function() {

Now this next line is where your mistake takes place.

jQuery(this).find(".box").toggle();

The first mistake is the use of jQuery. after you're already making use of it's short sign, $. You only need use the elongated name if you are using jQuery's noconflict because another JS library you include might use $. In other words, if $('.button') works and is a jQuery object when used, then you don't need to use jQuery.. See more about this here.

Now, that aside, we can look at jQuery(this) as $(this). Whenever you use $(this) in an Event's callback method, you're referring to the element that the event was tied too. That means that $(this) in your function refers to $('.button'). The problem here is that you then want it to find an inner element containing the class box. Well according to your HTML, that can't happen since .box is a sibling, it is not within the inner HTML of .button. Thus you need to make a different call before you can find .box.

There are actually several solutions here. No solution is more "correct" than another, just simply different and possibly causes a different amount of "time" to run. Now I went with what I saw as being the most simple in that it gives you control over the parent element which contains ALL relevant elements to this function. I'll talk about possible alternatives in a minute.

$(this).closest('.comment')

The above line simply tells .button:clicked to look for the first parent element that contains the class .comment. In other words, this won't find any children or siblings, it will only go up from the current element. This allows us to grab the block that contains all relevant elements and information and thus make maneuvers as needed. So, in the future, you might even use this as a variable in the function, such as:

$('.button').click(function(e) {
    var container = $(this).closest('.comment');

Now you can find anything within this element block. In this case you want to find box and toggle it. Thus:

$(this).closest('.comment').find(".box").toggle();
//  Or with our variable I showed you
container.find(".box").toggle();

Now, there are plenty of alternatives based on your HTML layout. This example I've given would be good even if .box was buried inside more elements inside .comment, however, given your exact HTML, we see that .button and .box are siblings. This means that you could make this call different entirely and get the same result using something like:

$(this).siblings(".box").toggle();

This will allow our currently clicked and selected button element to look for ANY and ALL siblings having class box. This is a great solution and simple if your HTML is that simple.

However, many times, for "comment" type setups, our HTML is not so simple, nor is it static. It's usually something loaded after the page load. This means our general assignment of .click will not work. Given your exact HTML and not knowing a static Parent ID, I would probably write your code as:

$(document).on('click', '.button', function(e) {
    $(this).siblings('.box').toggle();
});

What this does is allow for this click event to be assigned to ANY element containing .button for a class, whether loaded with page or even ten minutes after the page is up. However, the caveat often seen here is the assignment is placed on document. Should we assign a lot of events to document it could become quite convoluted and possibly slow down the client's browser. Not to mention the arguments held over all the other headaches this could cause. So here's my recommendation, make a static (loads with page, is a part of page's main HTML) loading area and do our dynamic assignment to that. For instance:

<div id"Comments"><!-- load comments --></div>

Then you can do the assignment as such:

$('#Comments').on('click', '.button', function(e) {
    $(this).siblings('.box').toggle();
});

If you have any more questions, just comment!

Side Note .on is for jQuery versions 1.7+. If using older jQuery, use .live or .bind

Community
  • 1
  • 1
SpYk3HH
  • 22,272
  • 11
  • 70
  • 81
0

You can use the jQuery selector .siblings() to re-write your function like this:

$( ".button" ).click(function() {
    $(this).siblings().toggle();
});

Here's a working fiddle to demonstrate.

Dpeif
  • 532
  • 1
  • 6
  • 18
0

All you really need to do is this:

  $(this).parent().find(".box").toggle();
Dylan Cross
  • 5,918
  • 22
  • 77
  • 118