blsn
blsn

Reputation: 1093

a second click to close a toggle div

I’m using the following jQuery for hiding and showing content (toggle), as a tree navigation menu in my website. I found this code extremely useful because by clicking, it displays only one div at a time.

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript">
function show_region(chosen_region) {
     $('.city_div').each(function(index) {
          if ($(this).attr("id") == chosen_region) {
               $(this).slideDown(200);
          }
          else {
               $(this).slideUp(600);
          }  
     });
}
</script>

<style type="text/css">
   .city_div {display: none;}
</style>


<a href="javascript:show_region('box01');">North</a><br>
<div class="city_div" id="box01">Div #01</div>

<a href="javascript:show_region('box02');">Centre</a><br>
<div class="city_div" id="box02">Div #02</div>

<a href="javascript:show_region('box03');">South</a><br>
<div class="city_div" id="box03">Div #03</div>

The problem is that I can close a div only by opening another div.

How to close the div by a second click on it?

Upvotes: 0

Views: 2358

Answers (8)

Gabber
Gabber

Reputation: 5452

You should keep a variable with your old chosen region name

<script type="text/javascript">
    var old_chosen_region="";
    function show_region(chosen_region) {
        $('.city_div').each(function(index) {
            if (($(this).attr("id") == chosen_region)&&(chosen_region!=old_chosen_region)) {
                $(this).slideDown(200);
                old_chosen_region=chosen_region;
            } else {
                $(this).slideUp(600);
            }
        }
        old_chosen_region='';
    });
</script>

This allows you to 'remember' which region you chose last and, if the chosen one equals the last you close it.

You should set old_chosen_region='' in the end to let the tab reopen.

Upvotes: 0

Ry-
Ry-

Reputation: 224877

First of all, don't use inline event handlers.

<script type="text/javascript">
$(document).ready(function() {
    var boxes = $('.city_div');

    $('.city-toggle').click(function(e) {
        var box = $(this).next();
        var isHidden = box.is(':hidden');

        boxes.slideUp(600);

        if(isHidden) {
            box.slideDown(200);
        }

        e.preventDefault();
    });
});
</script>

<style type="text/css">
   .city_div {display: none;}
</style>


<a href="something-meaningful-like-north.html" class="city-toggle">North</a>
<div class="city_div" id="box01">Div #01</div>

<a href="ditto.html" class="city-toggle">Centre</a>
<div class="city_div" id="box02">Div #02</div>

<a href="same.html" class="city-toggle">South</a>
<div class="city_div" id="box03">Div #03</div>

Also, if your links don't go anywhere meaningful, use # as the href and make sure the boxes are visible by default. (Hide them using boxes.hide(); right at the start.)

Also also, <br> isn't what you should use there. <div>s are already block-level elements. If you want more padding, give them a top margin.

Upvotes: 2

musefan
musefan

Reputation: 48415

Because you are using an animation it is best to keep track of the div that is currently shown. If you don't, then you will start to see multiple divs showing if you click links in quick succession.

You can use this:

$(function() {
    $("a").click(function(e) {
        e.preventDefault();
        var selectedDiv = $("#" + $(this).attr("href"));
        var hide = selectedDiv.data("shown");

        $(".city_div").slideUp(600);
        $(".city_div").data("shown", false);

        if (hide) {
            selectedDiv.data("shown", false);
        }
        else {
            selectedDiv.data("shown", true);
            selectedDiv.slideDown(200);
        }
    });
});​

Here is a working example

Upvotes: 0

CaffGeek
CaffGeek

Reputation: 22054

First, why are you using such an old version of jQuery?

Second, your JavaScript can be simplified. jQuery works on sets; you don't need the .each, or loops.

Here is a working example: http://jsfiddle.net/gibble/25P9z/

Simplified HTML:

<a href="#" data-contentDiv="box01">North</a><br>
<div class="city_div" id="box01">Div #01</div>

<a href="#" data-contentDiv="box02">Centre</a><br>
<div class="city_div" id="box02">Div #02</div>

<a href="#" data-contentDiv="box03">South</a><br>
<div class="city_div" id="box03">Div #03</div>​

New JavaScript:

function show_region(e) {
    var $target = $(e.target);
    var chosen_region = $target.attr('data-contentDiv');

    var openDiv = $('#' + chosen_region);

    openDiv.slideDown(200);
    $('.city_div').not(openDiv).slideUp(600);
}

Last, attach events, don't inline them in your HTML.

$('a[data-contentDiv]').click(show_region);​

Upvotes: 0

Laoujin
Laoujin

Reputation: 10229

Keep track of the div you have clicked last:

var globalLastClickedButtonId;
$("div.city_div").click(function() {
    if (globalLastClickedButtonId == $(this).attr("id")) {
        $(this).hide();
    } else {
        var box = $(this).next().next();
        var clickedId = $(this).attr("id");
        $("div.city_div").each(function() {
           if ($(this).attr("id") == clickedId)
              box.slideDown(200);
           else
              box.slideUp(600);
        }
    }
    globalLastClickedButtonId = $(this).attr("id");
});

Upvotes: 0

Blake Simpson
Blake Simpson

Reputation: 1088

Since you are using jQuery you could try using the jQuery.toggle function.

function show_region(chosen_region) {
     $('#' + chosen_region).toggle('slide');
     return false;
}

Upvotes: 0

Mihai Iorga
Mihai Iorga

Reputation: 39704

You can use slideToggle, change from slideDown to slideToggle:

function show_region(chosen_region) {
     $('.city_div').each(function(index) {
          if ($(this).attr("id") == chosen_region) {
               $(this).slideToggle(200); // instead of slideDown
          }
          else {
               $(this).slideUp(600);
          }  
     });
}

Upvotes: 4

NinJoel
NinJoel

Reputation: 29

try this:

$(document).ready(function(){
    $('.city_div').click(function(){
        $(this).hide(); //or whatever code you want to hide it
    });
});

that way when you click on a div, it will hide it.

Upvotes: 0

Related Questions