JSum JSum - 3 months ago 10
jQuery Question

toggle class based on accordion visibility

So I really don't think this should be this hard but I have been working on it for a few hours and have scoured Stack, which has helped get me to this point but not all of the way to where I need to be.

I have an accordion for an FAQ page. This part works. If I open one it closes all other open drop downs, just like I want.

my issue is that I have an arrow on the right hand side of my header, which is being pulled in using font awesome.

Here is my Jquery:



$('.faq_page').find('.faq_header').click(function(){

//Expand or collapse this panel
$(this).next().slideToggle('fast');

$(this).find('.faq_control i').toggleClass('fa-caret-down fa-caret-up');


//Hide the other panels
$(".faq_body").not($(this).next()).slideUp('fast');

});

.width_container:after,
.width_container_small:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}

.width_container,
.width_container_small { display: block; }
/* start commented backslash hack \*/
* html .width_container,
* html .width_container_small { height: 1%; }
.width_container,
.width_container_small { display: block; }
/* close commented backslash hack */

/********** FAQ Page **********/

.faq_page {
margin: 80px 0 80px;
}

.faq_box {
-webkit-box-shadow: 0px 0px 10px 0px rgba(35,31,32,1);
-moz-box-shadow: 0px 0px 10px 0px rgba(35,31,32,1);
box-shadow: 0px 0px 10px 0px rgba(35,31,32,1);
-ms-box-shadow: 0px 0px 10px 0px rgba(35,31,32,1);
-o-box-shadow: 0px 0px 10px 0px rgba(35,31,32,1);

margin-bottom: 40px;
}

.faq_header {
background: #231f20;
padding: 20px 0;
}

.faq_title {
float: left;
width: 95%;
}

.faq_title h2 {
color: #fff;
margin: 0;
font-size: 22px;
font-weight: 300;
text-align: left;
font-family: 'Open Sans', sans-serif;
padding-left: 20px;
}

.faq_control {
float: right;
width: 5%;
}

.faq_control i {
color: #fff;
font-size: 40px;
line-height: 40px;

}

.faq_body {
background: #e8e8e8;
padding: 20px;
display: none;
}

.faq_active {
display: block;
}

.faq_body p {
margin: 0;
font-size: 16px;
line-height: 36px;
letter-spacing: 2px;
font-weight: 400;
}

<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="faq_page">
<div class="width_container_small">

<div class="faq_box">
<div class="faq_header">
<div class="width_container">
<div class="faq_title">
<h2>This is a Frequently Aksed Question?</h2>
</div>
<div class="faq_control">
<i class="fa fa-caret-up" aria-hidden="true"></i>
</div>
</div>
</div>
<div class="faq_body faq_active">
<p>orem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque mollis vitae sapien quis vestibulum. Integer mollis erat et enim placerat ullamcorper. Vivamus malesuada blandit justo, ut scelerisque nibh tempor vel. Cras mattis, erat eget facilisis suscipit, est magna elementum ex, quis facilisis erat tortor et metus. Vestibulum ante This is a</p>
</div>
</div>

<div class="faq_box">
<div class="faq_header">
<div class="width_container">
<div class="faq_title">
<h2>This is a Frequently Aksed Question?</h2>
</div>
<div class="faq_control">
<i class="fa fa-caret-down" aria-hidden="true"></i>

</div>
</div>
</div>
<div class="faq_body">
<p>orem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque mollis vitae sapien quis vestibulum. Integer mollis erat et enim placerat ullamcorper. Vivamus malesuada blandit justo, ut scelerisque nibh tempor vel. Cras mattis, erat eget facilisis suscipit, est magna elementum ex, quis facilisis erat tortor et metus. Vestibulum ante This is a</p>
</div>
</div>

<div class="faq_box">
<div class="faq_header">
<div class="width_container">
<div class="faq_title">
<h2>This is a Frequently Aksed Question?</h2>
</div>
<div class="faq_control">
<i class="fa fa-caret-down" aria-hidden="true"></i>
</div>
</div>
</div>
<div class="faq_body">
<p>orem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque mollis vitae sapien quis vestibulum. Integer mollis erat et enim placerat ullamcorper. Vivamus malesuada blandit justo, ut scelerisque nibh tempor vel. Cras mattis, erat eget facilisis suscipit, est magna elementum ex, quis facilisis erat tortor et metus. Vestibulum ante This is a</p>
</div>
</div>

</div>
</section>





When clicking a single box it will toggle my arrow class like it should. Up for when the content is visible, down for when it is not. However if I have one box open, and click on the next box to open it, the first box will close but the arrow won't change because it's box wasn't clicked on.

This results in the box being closed by the script (not by clicking on it directly) to fall out of line with the arrow direction.

I would like for the arrow to point up if the box is open and down if the box is closed, period. Not sure how to make the class name dependent on whether the box is visible I guess. a few things I have tried made this work but only for the box I was clicking on.

Answer

I've updated your js a bit and split the accordion toggling functionality out into a jQuery function. The idea here is to separate out the code that actually does the toggle from the event so that we can manipulate the accordions without the direct click interaction.

In the click handler, I'm calling the toggle function and then finding all other open accordions (denoted by '.faq_body:visible') and calling the toggle function on them as well, which will close them and maintain the correct icon.

$('.faq_page').find('.faq_header').click(function(){
      $(this).toggleAccordion();

      //Hide the other panels
      //:visible finds all open panels, .prev finds their headers, 
      //.not ensures we aren't closing the one we just opened
      $(".faq_body:visible").prev('.faq_header').not($(this)).toggleAccordion();
    });

$.fn.toggleAccordion = function() {
  //Expand or collapse this panel
  $(this).next().slideToggle('fast');

  $(this).find('.faq_control i').toggleClass('fa-caret-down fa-caret-up');
}
.width_container:after,
.width_container_small:after {
    visibility: hidden;
    display: block;
    font-size: 0;
    content: " ";
    clear: both;
    height: 0;
}

.width_container,
.width_container_small { display: block; }
/* start commented backslash hack \*/
* html .width_container,
* html .width_container_small { height: 1%; }
.width_container,
.width_container_small { display: block; }
/* close commented backslash hack */

/********** FAQ Page **********/

.faq_page {
	margin: 80px 0 80px;
}

.faq_box {
	-webkit-box-shadow: 0px 0px 10px 0px rgba(35,31,32,1);
-moz-box-shadow: 0px 0px 10px 0px rgba(35,31,32,1);
box-shadow: 0px 0px 10px 0px rgba(35,31,32,1);
-ms-box-shadow: 0px 0px 10px 0px rgba(35,31,32,1);
-o-box-shadow: 0px 0px 10px 0px rgba(35,31,32,1);

	margin-bottom: 40px;
}

.faq_header {
	background: #231f20;
	padding: 20px 0;
}

.faq_title {
	float: left;
	width: 95%;
}

.faq_title h2 {
	color: #fff;
	margin: 0;
	font-size: 22px;
	font-weight: 300;
	text-align: left;
	font-family: 'Open Sans', sans-serif;
	padding-left: 20px;
}

.faq_control {
	float: right;
	width: 5%;
}

.faq_control i {
	color: #fff;
	font-size: 40px;
	line-height: 40px;

}

.faq_body {
	background: #e8e8e8;
	padding: 20px;
	display: none;
}

.faq_active {
	display: block;
}

.faq_body p {
	margin: 0;
	font-size: 16px;
	line-height: 36px;
	letter-spacing: 2px;
	font-weight: 400;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="faq_page">
		<div class="width_container_small">

			<div class="faq_box">
				<div class="faq_header">
					<div class="width_container">
						<div class="faq_title">
							<h2>This is a Frequently Aksed Question?</h2>
						</div>
						<div class="faq_control">
							<i class="fa fa-caret-up" aria-hidden="true"></i>
						</div>
					</div>
				</div>
				<div class="faq_body faq_active">
					<p>orem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque mollis vitae sapien quis vestibulum. Integer mollis erat et enim placerat ullamcorper. Vivamus malesuada blandit justo, ut scelerisque nibh tempor vel. Cras mattis, erat eget facilisis suscipit, est magna elementum ex, quis facilisis erat tortor et metus. Vestibulum ante This is a</p>
				</div>
			</div>

			<div class="faq_box">
				<div class="faq_header">
					<div class="width_container">
						<div class="faq_title">
							<h2>This is a Frequently Aksed Question?</h2>
						</div>
						<div class="faq_control">
							<i class="fa fa-caret-down" aria-hidden="true"></i>

						</div>
					</div>
				</div>
				<div class="faq_body">
					<p>orem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque mollis vitae sapien quis vestibulum. Integer mollis erat et enim placerat ullamcorper. Vivamus malesuada blandit justo, ut scelerisque nibh tempor vel. Cras mattis, erat eget facilisis suscipit, est magna elementum ex, quis facilisis erat tortor et metus. Vestibulum ante This is a</p>
				</div>
			</div>

			<div class="faq_box">
				<div class="faq_header">
					<div class="width_container">
						<div class="faq_title">
							<h2>This is a Frequently Aksed Question?</h2>
						</div>
						<div class="faq_control">
							<i class="fa fa-caret-down" aria-hidden="true"></i>
						</div>
					</div>
				</div>
				<div class="faq_body">
					<p>orem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque mollis vitae sapien quis vestibulum. Integer mollis erat et enim placerat ullamcorper. Vivamus malesuada blandit justo, ut scelerisque nibh tempor vel. Cras mattis, erat eget facilisis suscipit, est magna elementum ex, quis facilisis erat tortor et metus. Vestibulum ante This is a</p>
				</div>
			</div>

		</div>
	</section>