F1234k
F1234k

Reputation: 69

Elegant way to toggle visibility of divs in the same display area

I have 3 divs that contain a hidden field each:

<div class="item-wrapper">
  <div class="item-title">Button 1</div>
  <div class="hidden-field>Some hidden data</div>
</div>
<div class="item-wrapper">
  <div class="item-title">Button 2</div>
  <div class="hidden-field>Some more hidden data</div>
</div>
<div class="item-wrapper">
  <div class="item-title">Button 3</div>
  <div class="hidden-field>Even more hidden data</div>
</div>

My jQuery looks like this:

$( ".item-title" ).click(function() {
  $( this ).next().slideToggle( "slow" );
  $( this ).toggleClass( "item-active" );
});

The hidden-field divs have an absolute position and are displayed below the three wrappers. I want to find a way to show only one hidden field at a time, which basically means that if any hidden-field is visible at the time of the click, it needs to be hidden first.

Is there an elegant way of doing this or will I have to switch from slideToggle() to hide() and show() with conditionals?

Upvotes: 1

Views: 107

Answers (1)

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93601

Toggle is not always a good option. It is only useful for simple open/close items.

Try something that operates specifically on the chosen item and all the unselected ones (using not).

http://jsfiddle.net/gu6w8Lxb/

$( ".item-title" ).click(function() {
    var $this = $(this);
    $( ".item-title" ).not($this).removeClass("item-active").next().slideUp();
    $this.addClass("item-active").next().slideDown();
});

Which can shorten further to:

var $items = $(".item-title");
$items.click(function() {
    var $this = $(this);
    $items.not($this).removeClass("item-active").next().slideUp();
    $this.addClass("item-active").next().slideDown();
});

if you want the current item to toggle open/closed, test for its active class:

http://jsfiddle.net/gu6w8Lxb/1/

var $items = $(".item-title");
$(".item-title").click(function () {
    var $this = $(this);
    if ($this.hasClass("item-active")) {
        $this.removeClass("item-active").next().slideUp();
    } else {
        $items.not(this).removeClass("item-active").next().slideUp();
        $this.addClass("item-active").next().slideDown();
    }
});

Upvotes: 1

Related Questions