views:

335

answers:

2

Howdy folks,

My problem is that when a user clicks on the <h4> it opens the hidden <div> below it. That's great - works as expected. However when a user clicks back on the same <h4> - it closes the <div> and reopens it instantly.

I need the <div> to stay closed. I also need the remaining functionality to stay in place.

This is my jQuery:

$(document).ready(function() {
        $('div#winners-table div').hide();
        $('div#winners-table h4').click(function(){
            $('div#winners-table h4.open').each(function() {
                $(this).attr('class', 'closed');
                $(this).siblings('div').slideUp();
                });
            $(this).toggleClass('open');
            $(this).siblings('div').slideToggle();
            });
        });

EDIT This is my HTML:

<div id="winners-table">
        <h3>...</h3>
        <ul>
            <li>
                <h4>...</h4>
                <div>...</div>
            </li><!-- ENDS -->
                    <li>
                <h4>...</h4>
                <div>...</div>
            </li><!-- ENDS -->
                    <li>
                <h4>...</h4>
                <div>...</div>
            </li><!-- ENDS -->
                    <li>
                <h4>...</h4>
                <div>...</div>
            </li><!-- ENDS -->
        </ul>
</div>
+2  A: 

After trying it with your edited question, i got it to working using this js:

$(document).ready(function() {
        $('div#winners-table div').hide();
        $('div#winners-table h4').click(function(){
            $('div#winners-table h4.closed').removeClass('closed');
            $('div#winners-table h4.open').each(function(){
                $(this).attr('class', 'closed').siblings('div').slideUp();
            });

            if(!$(this).hasClass('open') && !$(this).hasClass('closed')){
              $(this).addClass('open');
              $(this).siblings('div').slideDown();
            }else{
               $(this).removeClass('open');
            }

       });
});
munch
This doesn't work - well that's not true actually - it does mean that the `<div>` slides back up when the `<h4>` is clicked.However, removing the line `$(this).siblings('div').slideUp();` stops the other `<div>`s from closing - only one needs to be visible at a time. Also, removing the each loops - leaves the class `open` active when clicking on the `<h4>`
Jonny Haynes
It would probably be more helpful if you included your HTML markup as well. Your question implies it's a single `<div>` within the `<h4>`
munch
I've added ion the HTML, apologies.
Jonny Haynes
Something funky's going on with the way you're classes are being called. Once the 'closed' class was added, it was never being removed, and toggleClass was also active counter-intuitively, so I just went old school. Hope it works the way you expect it to.
munch
Looks like this is the way to go (using `addClass`/`removeClass`). `attr('class', 'closed')` seems to act like `addClass`.
Nikki Erwin Ramirez
Might be old school but works exactly as expected. Thanks for your help Munch.
Jonny Haynes
+2  A: 

Your problem is because, after closing all h4.open, you still slideToggle() the clicked h4.

$(document).ready(function() {
        $('div#winners-table div').hide();
        $('div#winners-table h4').click(function(){
            var clicked = this;
            $('div#winners-table h4.open').each(function() {
                $(this).attr('class', 'closed');
                if (clicked != this) {
                    $(this).siblings('div').slideUp();
                    }
                });
            $(this).toggleClass('open');
            $(this).siblings('div').slideToggle();
            });
        });

^ I added a check where the clicked h4 wouldn't slideUp(), so the slideToggle() would do its job as expected.


EDIT

Here's my entire HTML file:

<html>
<head>
<title>Test</title>
<script type="text/javascript" src="jquery.js"></script>
<script>
$(document).ready(function() {
        $('div#winners-table div').hide();
        $('div#winners-table h4').click(function(){
            var clicked = this;
            $('div#winners-table h4.open').each(function() {
                $(this).attr('class', 'closed');
                if (clicked != this) {
                    $(this).siblings('div').slideUp();
                    }
                });
            $(this).toggleClass('open');
            $(this).siblings('div').slideToggle();
            });
        });
</script>
</head>
<body>
<div id="winners-table">
        <h3>h3</h3>
        <ul>
            <li>
                <h4>H4</h4>
                <div>div1</div>
            </li><!-- ENDS -->
                    <li>
                <h4>h4 2</h4>
                <div>div 2</div>
            </li><!-- ENDS -->
                    <li>
                <h4>h4 3</h4>
                <div>div 3</div>
            </li><!-- ENDS -->
                    <li>
                <h4>h4 4</h4>
                <div>div 4</div>
            </li><!-- ENDS -->
        </ul>
</div>
</body>
</html>

As you can see, I copied your HTML and only replaced the ellipses. Tested on Firefox 3.5, Chrome 4 (dev channel), Opera 10, IE6 (via IEs4Linux) on Ubuntu.

Nikki Erwin Ramirez
Sorry, this doesn't work - it requires the user to click twice on the `<h4>`. It also doesn't close the previous `<div>` when clicking on another `<h4>`.
Jonny Haynes
Then you might have omitted something essential from your HTML. "It works on my machine." :p Maybe more details on what you have on your web page? :)
Nikki Erwin Ramirez
Right. Safari Mac: Requires user to click twice on the `<h4>`. It also doesn't close the previous `<div>` when clicking on another `<h4>`. FF Mac, Opera Mac, IE6 WinXP, IE7 WinXP: Doesn't remove the class 'open' off of the `<h4>`.
Jonny Haynes
My code is exactly the same and it's very buggy cross browser/os
Jonny Haynes