Nurzhan Nogerbek
Nurzhan Nogerbek

Reputation: 5246

Bootstrap collapse change icon

Can someone help me to fix little bug. I use bootstrap 4 alpha 6. Below you can see picture. enter image description here As you see I have several collapse blocks in my page. One of this collapse block inside other collapse block. When I click the button to open that internal block (with inside data-toggle) it changes the icon of top data-toggle. Whats wrong I did in my JS?

HTML:

<div class="card">
   <div class="card-header">
      <div class="d-flex align-items-center justify-content-between">
          <button data-toggle="collapse" data-target="#collapse-group-task" aria-expanded="false" aria-controls="collapse-group-task">
              <i class="fa fa-eye" aria-hidden="true"></i>
          </button>
      </div>
   </div>

   <div class="card-block">
      <div class="collapse" id="collapse-group-task">
         <div class="list-group">
            <div class="d-flex w-100 justify-content-end custom-d-flex">
               <a data-toggle="collapse" href="#collapse-group-task-1" aria-expanded="false" aria-controls="collapse-group-task-1">
                  <i class="fa fa-comments-o" aria-hidden="true"></i>&#9;<span>Comments</span>
               </a>
            </div>

            <div class="collapse w-100 comment-list-block" id="collapse-group-task-1">
                  ***SOME TEXT***
            </div>
         </div>
      </div>
   </div>

</div>
</div>

JS:

$(document).ready(function () {
    $('.collapse')
        .on('shown.bs.collapse', function() {
            $(this)
                .parent().parent()
                .find(".fa-eye")
                .removeClass("fa-eye")
                .addClass("fa-eye-slash");
        })
        .on('hidden.bs.collapse', function() {
            $(this)
                .parent().parent()
                .find(".fa-eye-slash")
                .removeClass("fa-eye-slash")
                .addClass("fa-eye");
        });
});

Upvotes: 3

Views: 8621

Answers (2)

azs06
azs06

Reputation: 3517

Your current jQuery will listen to all collapse event on a page, and as you added accordion inside accordion, they all have same event. You could use stopPropagation() as mentioned in the other answer, or you could check event.target or you could add a unique class to your parent accordion and add event listener using that class, all will solve your problem.

Here is a solution, using event.target to only make changes if parent accordion is opened or closed.

$(document).ready(function () {
    $('.collapse')
        .on('shown.bs.collapse', function(e) {
		if(e.target.id !== 'collapse-group-task'){return}
            $(this)
                .parent().parent()
                .find(".fa-eye")
                .removeClass("fa-eye")
                .addClass("fa-eye-slash");
        })
        .on('hidden.bs.collapse', function(e) {
		if(e.target.id !== 'collapse-group-task'){return}
            $(this)
                .parent().parent()
                .find(".fa-eye-slash")
                .removeClass("fa-eye-slash")
                .addClass("fa-eye");
        });
});
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">	
</head>
<body>

<section class="container">
	<section class="row">
<div class="card">
   <div class="card-header">
      <div class="d-flex align-items-center justify-content-between">
          <button data-toggle="collapse" data-target="#collapse-group-task" aria-expanded="false" aria-controls="collapse-group-task">
              <i class="fa fa-eye" aria-hidden="true"></i>
          </button>
      </div>
   </div>

   <div class="card-block">
      <div class="collapse" id="collapse-group-task">
         <div class="list-group">
            <div class="d-flex w-100 justify-content-end custom-d-flex">
               <a data-toggle="collapse" href="#collapse-group-task-1" aria-expanded="false" aria-controls="collapse-group-task-1">
                  <i class="fa fa-comments-o" aria-hidden="true"></i>&#9;<span>Comments</span>
               </a>
            </div>

            <div class="collapse w-100 comment-list-block" id="collapse-group-task-1">
                  ***SOME TEXT***
            </div>
         </div>
      </div>
   </div>

</div>		
	</section>
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>		
</body>
</html>

Jsbin of the above snippet https://jsbin.com/libege/edit?html,js,output

Upvotes: 2

Teuta Koraqi
Teuta Koraqi

Reputation: 1898

This happens because you have accordion inside accordion, they all have same class collapse, same event. A solution is to stop event of parent element with stopPropagation().

Here I made a fiddle: fiddle link.

Hope this helps!

Upvotes: 2

Related Questions