jQuery Slide Toggle with content already open

Hi there,

I’m putting together a slide toggle for a FAQ-type page and think there is a much more efficient way of using jQuery to show/hide the elements - possibly using toggle class or toggle slide? Note that I’ll still need to use CSS to apply styling to any open/closed elements such as a change in the plus/minus icon used to indicate it is open/closed.

One other problem is if I want an element to be already open on page load and how I accommodate this within my jQuery?

EDIT: Please see updated code in following post

Any thoughts?

Cheers,

Andrew

Hi there,

Have modified the code so that it also removes the selected class from the filter-toggle element.
This is needed so that I can update the plus/minus styling and accommodate for elements which have the selected class applied on load:

<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {

	$('.filter-toggle').click(function(e) {
		e.preventDefault();
		var $this = $(this);
		if ($this.next().hasClass('selected')) {
			$this.next().removeClass('selected');
			$this.removeClass('selected');
			$this.next().addClass('unselected');
			$this.addClass('unselected');
			$('.filter-content').slideUp(200);
			$this.next().slideUp(200);
		} else {
			$('.filter-content').removeClass('selected');
			$('.filter-toggle').removeClass('selected');
			$this.next().removeClass('unselected');
			$this.removeClass('unselected');
			$this.next().addClass('selected');
			$this.addClass('selected');
			$('.filter-content').slideUp(200);
			$this.next().slideDown(200);
		}
	});
	
});
</script>
<style type="text/css">
	ul{
		margin:0;
		padding:0;	
	}

	ul.filter-accordion li{
		margin-right:-1px; 
		margin-bottom:-1px;
		display:block;
		border:0;
		border-bottom:1px solid #cacdd3;
		list-style-type:none;
	}

	ul.filter-accordion li:nth-child(1){
		margin-right:-1px; 
		margin-top:-1px;
		border-top: 1px solid #cacdd3;
	}

	ul.filter-accordion li .filter-toggle h3{
		font-size:1rem;
		text-transform:none;	
	}
	
	ul.filter-accordion li .filter-content{
		overflow: hidden;
		display: none;	
	}
	
	ul.filter-accordion li .filter-content.selected{
		display:block;	
	}
</style>
<div>
    <ul class="filter-accordion">
        <li>
            <a class="filter-toggle selected" href="javascript:void(0);">
                <ul>
                    <li><h3>Filter option 1</h3></li>
                </ul>
            </a>
            <div class="filter-content selected">
                <p>Filter option 1 content</p>
            </div>
        </li>
        <li>
            <a class="filter-toggle" href="javascript:void(0);">
                <h3>Filter option 2</h3>
            </a>
            <div class="filter-content">
                <p>Filter option 2 content</p>
            </div>
        </li>
    </ul>
</div>

Cheers,

Andrew

Hi,

This looks a little neater but I’m sure it could be improved a lot :slight_smile:

<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
ul {
	margin:0;
	padding:0;
	list-style:none;
}
ul.filter-accordion {
	border-top:1px solid #cacdd3;
}
ul.filter-accordion li {
	display:block;
	border-bottom:1px solid #cacdd3;
	position:relative;
}
ul.filter-accordion li:nth-child(odd) .filter-toggle {
	background:#f9f9f9;
}
.filter-toggle {
	font-size:1rem;
	text-transform:none;
	margin:0;
	padding:1em 45px 1em 0;
	cursor:pointer;
	position:relative;
}
.filter-content {
	overflow: hidden;
	display:none
}
.filter-toggle .close {
	position:absolute;
	right:20px;
	top:18px;
	font-size:18px;
	font-weight:bold;
	transition:.5s ease-in-out;
}
.selected .filter-toggle .close {
	transform:rotate(135deg)
}
</style>
</head>

<body>
<div>
  <ul class="filter-accordion">
    <li class="selected">
      <h3 class="filter-toggle" >Filter option 1 <span class="close">+</span> </h3>
      <div class="filter-content" style="display:block">
        <p>Filter option 1 content</p>
      </div>
    </li>
    <li>
      <h3 class="filter-toggle" >Filter option 2 <span class="close">+</span> </h3>
      <div class="filter-content">
        <p>Filter option 2 content</p>
      </div>
    </li>
    <li>
      <h3 class="filter-toggle" >Filter option 3 <span class="close">+</span> </h3>
      <div class="filter-content">
        <p>Filter option 3 content</p>
      </div>
    </li>
  </ul>
</div>

<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script> 
<script type="text/javascript">
$(document).ready(function() {
    $('.filter-toggle').click(function(e) {
        var $accordion = $('.filter-accordion'),
            $parent = $(this).closest('li');
        if ($parent.hasClass('selected')) {
            ($parent).removeClass('selected');
            $parent.find('.filter-content').slideUp(200);
        } else {
            $accordion.find('.selected .filter-content').slideUp(200)
            $accordion.find('.selected').removeClass('selected');
            $parent.addClass('selected');
            $parent.find('.filter-content').slideDown(200);
        }
    });
});
</script>
</body>
</html>

Hi Paul,

Apologies for not getting back sooner - bit of a busy weekend!
Thanks very much for looking into this - it’s much cleaner than I had and works perfectly.

I’ve learnt something new about jQuery too - using closest! Also a great idea to use parent rather than just relying on classes.

Cheers,

Andrew

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.