javascript – Bootstrap 4: what is the best way to swap one icon with another inside of a foreach loop?-ThrowExceptions

Exception or error:

I want to swap fa fa-plus for fa fa-minus when using collapse, without every icon toggling at the same time while using a foreach loop.

here’s a demo of my code.

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>

<div class="container h-100">

	<div class="row no-gutters border-0 rounded align-items-center mt-3">
		<div class="col-sm-4">demo 1</div>
		<div class="col-sm-4">demo 1</div>
		<div class="col-sm-3">demo 1</div>
		<div class="col-sm-1 ">
			<a class="fa fa-plus" data-toggle="collapse" href="#collapse1" aria-expanded="true" aria-controls="collapse1"></a>
		</div>
	</div><!--row-->

	<div class="collapse" id="collapse1">
		<div class="row no-gutters border-0 rounded align-items-center mt-3">
			<div class="col-sm-4">demo 1</div>
			<div class="col-sm-4">demo 1</div>
			<div class="col-sm-4">demo 1</div>
		</div><!--collapse-->
	</div>

	<div class="row no-gutters border-0 rounded align-items-center mt-3">
		<div class="col-sm-4">demo 2</div>
		<div class="col-sm-4">demo 2</div>
		<div class="col-sm-3">demo 2</div>
		<div class="col-sm-1 ">
			<a class="fa fa-plus" data-toggle="collapse" href="#collapse2" aria-expanded="true" aria-controls="collapse2"></a>
		</div>
	</div><!--row-->

	<div class="collapse" id="collapse2">
		<div class="row no-gutters border-0 rounded align-items-center mt-3">
			<div class="col-sm-4">demo 2</div>
			<div class="col-sm-4">demo 2</div>
			<div class="col-sm-4">demo 2</div>
		</div><!--collapse-->
	</div>

	<div class="row no-gutters border-0 rounded align-items-center mt-3">
		<div class="col-sm-4">demo 3</div>
		<div class="col-sm-4">demo 3</div>
		<div class="col-sm-3">demo 3</div>
		<div class="col-sm-1 ">
			<a class="fa fa-plus" data-toggle="collapse" href="#collapse3" aria-expanded="true" aria-controls="collapse3"></a>
		</div>
	</div><!--row-->

	<div class="collapse" id="collapse3">
		<div class="row no-gutters border-0 rounded align-items-center mt-3">
			<div class="col-sm-4">demo 3</div>
			<div class="col-sm-4">demo 3</div>
			<div class="col-sm-4">demo 3</div>
		</div><!--collapse-->
	</div>
</div><!--container-->

https://codepen.io/benwhittaker25/pen/rNVWyby

What is the best way to achieve this in bootstrap 4.4?

How to solve:

You can do it using the events Bootstrap triggers when clicking on the button:

$('.collapse').on('show.bs.collapse hide.bs.collapse', function () {
  // Find the corresponding button
  var $btn = $('[data-toggle="collapse"][href="#' + this.id + '"]');
  // Find the corresponding row
  var $row = $btn.closest('.row');
  
  // Toggle classes
  $btn.toggleClass('fa-minus fa-plus');
  $row.toggleClass('rounded rounded-top');
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>

<div class="container h-100">

	<div class="row no-gutters border-0 rounded align-items-center mt-3">
		<div class="col-sm-4">demo 1</div>
		<div class="col-sm-4">demo 1</div>
		<div class="col-sm-3">demo 1</div>
		<div class="col-sm-1 ">
			<a class="fa fa-plus" data-toggle="collapse" href="#collapse1" aria-expanded="true" aria-controls="collapse1"></a>
		</div>
	</div><!--row-->

	<div class="collapse" id="collapse1">
		<div class="row no-gutters border-0 rounded align-items-center mt-3">
			<div class="col-sm-4">demo 1</div>
			<div class="col-sm-4">demo 1</div>
			<div class="col-sm-4">demo 1</div>
		</div><!--collapse-->
	</div>

	<div class="row no-gutters border-0 rounded align-items-center mt-3">
		<div class="col-sm-4">demo 2</div>
		<div class="col-sm-4">demo 2</div>
		<div class="col-sm-3">demo 2</div>
		<div class="col-sm-1 ">
			<a class="fa fa-plus" data-toggle="collapse" href="#collapse2" aria-expanded="true" aria-controls="collapse2"></a>
		</div>
	</div><!--row-->

	<div class="collapse" id="collapse2">
		<div class="row no-gutters border-0 rounded align-items-center mt-3">
			<div class="col-sm-4">demo 2</div>
			<div class="col-sm-4">demo 2</div>
			<div class="col-sm-4">demo 2</div>
		</div><!--collapse-->
	</div>

	<div class="row no-gutters border-0 rounded align-items-center mt-3">
		<div class="col-sm-4">demo 3</div>
		<div class="col-sm-4">demo 3</div>
		<div class="col-sm-3">demo 3</div>
		<div class="col-sm-1 ">
			<a class="fa fa-plus" data-toggle="collapse" href="#collapse3" aria-expanded="true" aria-controls="collapse3"></a>
		</div>
	</div><!--row-->

	<div class="collapse" id="collapse3">
		<div class="row no-gutters border-0 rounded align-items-center mt-3">
			<div class="col-sm-4">demo 3</div>
			<div class="col-sm-4">demo 3</div>
			<div class="col-sm-4">demo 3</div>
		</div><!--collapse-->
	</div>
</div><!--container-->

###

The elegant way would be to do the jquery way shown by blex. But you can also bind a click function as well like below the javascript way:

function toggleClass(item){
	if(item.classList.contains('fa-plus')){
			item.classList.remove('fa-plus');
			item.classList.add('fa-minus');
	}else{
		item.classList.remove('fa-minus');
			item.classList.add('fa-plus');
	}
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>

<div class="container h-100">
<div class="container h-100">

	<div class="row no-gutters border-0 rounded align-items-center mt-3">
		<div class="col-sm-4">demo 1</div>
		<div class="col-sm-4">demo 1</div>
		<div class="col-sm-3">demo 1</div>
		<div class="col-sm-1 ">
			<a class="fa fa-plus" data-toggle="collapse" href="#collapse1" aria-expanded="true" aria-controls="collapse1" onClick="toggleClass(this)"></a>
		</div>
	</div><!--row-->

	<div class="collapse" id="collapse1">
		<div class="row no-gutters border-0 rounded align-items-center mt-3">
			<div class="col-sm-4">demo 1</div>
			<div class="col-sm-4">demo 1</div>
			<div class="col-sm-4">demo 1</div>
		</div><!--collapse-->
	</div>

	<div class="row no-gutters border-0 rounded align-items-center mt-3">
		<div class="col-sm-4">demo 2</div>
		<div class="col-sm-4">demo 2</div>
		<div class="col-sm-3">demo 2</div>
		<div class="col-sm-1 ">
			<a class="fa fa-plus" data-toggle="collapse" href="#collapse2" aria-expanded="true" aria-controls="collapse2" onClick="toggleClass(this)"></a>
		</div>
	</div><!--row-->

	<div class="collapse" id="collapse2">
		<div class="row no-gutters border-0 rounded align-items-center mt-3">
			<div class="col-sm-4">demo 2</div>
			<div class="col-sm-4">demo 2</div>
			<div class="col-sm-4">demo 2</div>
		</div><!--collapse-->
	</div>

	<div class="row no-gutters border-0 rounded align-items-center mt-3">
		<div class="col-sm-4">demo 3</div>
		<div class="col-sm-4">demo 3</div>
		<div class="col-sm-3">demo 3</div>
		<div class="col-sm-1 ">
			<a class="fa fa-plus" data-toggle="collapse" href="#collapse3" aria-expanded="true" aria-controls="collapse3" onClick="toggleClass(this)"></a>
		</div>
	</div><!--row-->

	<div class="collapse" id="collapse3">
		<div class="row no-gutters border-0 rounded align-items-center mt-3" >
			<div class="col-sm-4">demo 3</div>
			<div class="col-sm-4">demo 3</div>
			<div class="col-sm-4">demo 3</div>
		</div><!--collapse-->
	</div>
</div><!--container-->

Leave a Reply

Your email address will not be published. Required fields are marked *