I use bootstrap 4 alpha 6 version. In my page I have several collapse blocks. I want to change icon when user open/close that block. As I have several of these blocks I used class but it didnt work. Whats wrong I did? P.S. When I use id in JS works fine, but as you see I have several collapse block and dont want to "copy & paste".
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-projects" aria-expanded="false" aria-controls="collapse-projects">
<i class="fa fa-eye" aria-hidden="true"></i>
</button>
</div>
</div>
<div class="card-block">
<div class="collapse" id="collapse-projects">
***SOME CONTENT***
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<div class="d-flex align-items-center justify-content-between">
<button data-toggle="collapse" data-target="#collapse-tasks" aria-expanded="false" aria-controls="collapse-tasks">
<i class="fa fa-eye" aria-hidden="true"></i>
</button>
</div>
</div>
<div class="card-block">
<div class="collapse" id="collapse-tasks">
***SOME CONTENT***
</div>
</div>
</div>
JS:
$(document).ready(function () {
$('.collapse')
.on('shown.bs.collapse', function() {
$(this)
.parent()
.find(".fa-eye")
.removeClass("fa-eye")
.addClass("fa-eye-slash");
})
.on('hidden.bs.collapse', function() {
$(this)
.parent()
.find(".fa-eye-slash")
.removeClass("fa-eye-slash")
.addClass("fa-eye");
});
});
The problem is: all your button
and .collapse
elements are in the same DOM level, which means when .collapse
's shown.bs.collapse
or hidden.bs.collapse
event is fired, the $(this).parent()
in the event handler point to .collapse
's parent -- the most outside one that is not displayed in your code. Let's make it as OUTER
. Then, when you invoke find
, removeClass
and addClass
on OUTER
, all icons will be changed, which is why "it didn't work".
To fix this issue, you need to make a unit wrapper which contains a group of button
and .collapse
elements. In this way, $(this).parent()
will point to the group and only the clicked button icon is changed.
I've made a snippet for the fix, please check:
$(document).ready(function() {
$('.collapse')
.on('shown.bs.collapse', function() {
$(this)
.parent()
.find(".fa-eye")
.removeClass("fa-eye")
.addClass("fa-eye-slash");
})
.on('hidden.bs.collapse', function() {
$(this)
.parent()
.find(".fa-eye-slash")
.removeClass("fa-eye-slash")
.addClass("fa-eye");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://use.fontawesome.com/b4f468aefc.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<div class="wrapper">
<button data-toggle="collapse" data-target="#collapse-projects" aria-expanded="false" aria-controls="collapse-projects">
<i class="fa fa-eye" aria-hidden="true"></i>
</button>
<div class="collapse" id="collapse-projects">
***SOME CONTENT***
</div>
</div>
<div class="wrapper">
<button data-toggle="collapse" data-target="#collapse-tasks" aria-expanded="false" aria-controls="collapse-tasks">
<i class="fa fa-eye" aria-hidden="true"></i>
</button>
<div class="collapse" id="collapse-tasks">
***SOME CONTENT***
</div>
</div>