3

I'm trying to have a div get a new class (which makes it expand) when being clicked, and get it back to the old class (which makes it close) when clicking on a cancel link inside that div.

<div class="new-discussion small">
    <a class="cancel">Cancel</a>
</div>

<script>
    $('.new-discussion.small').click(function() {
        $(this).addClass("expand").removeClass("small");
    });
    $('a.cancel').click(function() {
        $('.new-discussion.expand').addClass("small").removeClass("expand");
    });
</script>

Now, adding the expand class works flawlessly, but closing the panel after clicking on the cancel link only works when I remove this code:

$('.new-discussion.small').click(function() {
    $(this).addClass("expand").removeClass("small");
});

So I guess this must be preventing the second function to work, but I really can't figure out why.

Any ideas? Thanks!

Sachin Jain
  • 21,353
  • 33
  • 103
  • 168
Lennart
  • 327
  • 1
  • 5
  • 10
  • 1
    You know you can use `.toggleClass` instead of both adding and removing, right? – VoidKing Apr 19 '13 at 21:18
  • Yep, doesn't work either though. – Lennart Apr 19 '13 at 21:19
  • Speculation: Since `'a.cancel'` is within `'.new-discussion.small'` is it registering the `$('.new-discussion.small').click` even when you are clicking the `a.cancel`? – VoidKing Apr 19 '13 at 21:23
  • In my above comment, I am probably wrong, but thought it might be something to check, since you say that it works when you remove `$('.new-discussion.small').click(function() { $(this).addClass("expand").removeClass("small"); });` – VoidKing Apr 19 '13 at 21:24
  • Yeah, I thought about that. However, when clicking cancel, the panel is already open, so the 'small' class has already been removed - therefore, that event shouldn't register. Or does it? It would be a logical explanation. – Lennart Apr 19 '13 at 21:26

3 Answers3

5

Try this

$('a.cancel').click(function() {
    $('.new-discussion.expand').addClass("small").removeClass("expand");
    return false;
});

Reason may be your click event is getting propagated to parent which is also listening to click event.

Sachin Jain
  • 21,353
  • 33
  • 103
  • 168
  • this answer and plalxs make me think this is relevant: http://stackoverflow.com/questions/1357118/event-preventdefault-vs-return-false – user2264587 Apr 19 '13 at 21:32
  • Note that `return` false is the same as calling both `e.preventDefault()` and `e.stopPropagation()`, but only stops the event from bubbling up in the context of a **jQuery** handler. – plalx Apr 19 '13 at 21:36
  • @user2264587 Thanks!! This link is in one of my favs ;) In this case, I think since it is an anchor tag and might have an href attribute associated with it sometime so its better to return false. Anyways its upto you. e.stopPropagation() will work here too. – Sachin Jain Apr 19 '13 at 21:40
5

Since your a element is inside the .new-discussion element, when you click on the a, it also fires the click event on the parent element because the event is bubbling up.

To fix it, you can stop the propagation of the event by calling e.stopPropagation();. That will prevent any parent handlers to be executed.

$('a.cancel').click(function(e) {
    e.stopPropagation();
    $('.new-discussion.expand').addClass("small").removeClass("expand");
});
plalx
  • 42,889
  • 6
  • 74
  • 90
0

Since the link is inside the <div>, it's using both click methods at once. It might help to do a check to see if the container is already open before proceeding:

<script>
    $('.new-discussion.small').click(function() {
        if ($(this).hasClass("small")) {
            $(this).addClass("expand").removeClass("small");
        }
    });
    $('a.cancel').click(function() {
        $(this).parent('.expand').addClass("small").removeClass("expand");
    });
</script>
David Millar
  • 1,858
  • 1
  • 14
  • 23