views:

5133

answers:

7

On the first click, it works as expected:

  1. the class is changed
  2. and the html content is changed from 'Show...' to 'Close...'
  3. the content area is expanded with the slideDown effect,

Good so far.

On the second click, ...

  1. the class changes
  2. the html content is changed from 'Close...' to 'Show...'
  3. The content area does NOT go away as expected.

On the third click, ...

  1. the class is changed
  2. the html content is changed
  3. the already-shown content is re-shown with the slidedown effect.

So everything is working except for the 2nd click when the content is supposed to be hidden again.

Here's the jQuery:

-

$('.open_user_urls').live('click', function() {
 $('#user_urls').slideDown('slow');
 $(this).addClass('close_user_urls');
 $(this).removeClass('open_user_urls');
 $(this).html('Close Search History');
 return false;
});

$('.close_user_urls').live('click', function() {
 $('#user_urls').slideUp('slow');
 $(this).addClass('open_user_urls');
 $(this).removeClass('close_user_urls');
 $(this).html('Show Search History');
 return false;
});

Here's the HTML it's acting on:

<h3 class='open_user_urls'>Show Search History</h3>
<div id='user_urls'>
// an OL tag with content
</div>

And the only applicable CSS:

#user_urls { display: none; }

EDIT - I replaced my jquery code with functionally equivalent code supplied in an answer below, but the problem persists. So the cause must be elsewhere. I do recall this code working originally, but then it stopped. I'm stumped. Time to strip everything else out piece by piece...

EDIT 2 - Since the bug must be elsewhere, I'm accepting a code improvement for my jquery as the answer. Thanks.

Edit 3 - Found the source of the problem.

Inside the #user_urls div I have an series of OLs with the following css:

.url_list {float: left; width: 285px; list-style-position: outside; margin-left: 25px;}

Each OL contains a list of 20 urls and is meant to display in as many multiple columns as required to display all the URLs.

Removing the float: left; on these OL tags causes the problem to go away.

So having a float on the content contained in the DIV thats showing and hiding is causing it not not hide at all. Why would this happen?

EDIT 4: Adding a inside the #user_urls DIV allows the hiding action to work properly.

+4  A: 

Perhaps something like this would be simpler?

$(".open_user_urls").toggle(
    function () {
        $(this).text("Close Search History").siblings(".user_urls").slideDown("slow");
    },
    function () {
        $(this).text("Show Search History").siblings(".user_urls").slideUp("slow");
    }
);

The toggle function is designed for precisely the scenario you're encountering.

Conor McDermottroe
Oddly, the same issue occurs with your function as with my original. The problem must be elsewhere...
Ian
But, I like your code better so I'll accept your answer and change the question somewhat. Thanks
Ian
Thanks. Sorry I didn't get you there.
Conor McDermottroe
+1  A: 

From what I've found, jQuery needs to have the height style set in order to slide it correctly. A work around I've used is to set the height before you slide it closed.

$('#user_urls').css('height', $('#user_urls').height() + 'px');

After you set it once, it should work correctly from then on. Check out this tutorial for a more detailed explanation.

The Reddest
A: 

I think Conor's answer might put you on the right track. I might also suggest slideToggle and toggleClass:

http://docs.jquery.com/Attributes/toggleClass

http://docs.jquery.com/Effects/slideToggle

I could be as easy as:

$("h3.open_user_urls").click(function () { 
      next("div#user_urls").slideToggle(); 
});
superUntitled
A: 

I can't duplicate your bug. I used your exact code and I cannot replicate your issue.

This must be a script error from a different place in your JS code.

wambotron
+2  A: 

To reiterate the problem and resolution to this question...

Inside the #user_urls DIV were a series of OL tags, each floated left. It was the float that was causing the problem.

Adding a <br style='clear: left;' /> inside the #user_urls DIV fixed the problem.

Ian
thanks for updating your answer. That fixed my problem in about 15 seconds (after several hours of head-beating)
cori
fixed the problem for me too... damn that is a WEEEIIIRRDD bug
Jiaaro
A: 

Thanks for this question. It really got me on my way figuring out the problem toggling an element with floated children.

Another resource that really helped and explains the behavior a bit can be found on this Google group discussion.

d12
A: 

Putting a non breaking space in your div is another solution similar to what The Reddest suggested that worked for me on a similar issue.

leaf dev