Change glyphicon depending on if collapse element is opened - Bootstrap - javascript

I was wondering how can I change glyphicon depending on if collapse element is opened.
So far I've got this code:
<div class="jumbotron ref" data-toggle="collapse" data-target="#collapse">
<div class="row">
<div class="col-md-11">
<a target="_blank" href="#"><h4 align="center">Click me.</h4></a>
</div>
<div class="col-md-1">
<span class="glyphicon glyphicon-chevron-down"> <!-- part to change-->
    
<div id="collapse" class="collapse">
<p style="margin-top: 75px;" align="center"></p>
</div>
    
    

.jumbotron gets the class .collapsed when you collapse the menu. You can use that class to target the glyph.
You should also add .collapsed to the .jumbotron by default since the default state is collapsed, but the class isn't applied until you click to trigger it to be collapsed.
.jumbotron.collapsed .glyphToChange {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="jumbotron ref collapsed" data-toggle="collapse" data-target="#collapse">
<div class="row">
<div class="col-md-11">
<a target="_blank" href="#"><h4 align="center">Click me.</h4></a>
</div>
<div class="col-md-1">
<span class="glyphicon glyphToChange glyphicon-chevron-down">glyph</span>
<div id="collapse" class="collapse">
<p style="margin-top: 75px;" align="center"></p>
</div>

A jquery solution using toggleClass.
$( ".jumbotron" ).click(function() {
$( ".glyphicon" ).toggleClass( glyphicon-chevron-down, glyphicon-chevron-up );
});

Following are the collapse events.
show.bs.collapse This event fires immediately when the show
instance method is called.
shown.bs.collapse This event is fired
when a collapse element has been made visible to the user (will wait
for CSS transitions to complete).
hide.bs.collapse This event is
fired immediately when the hide method has been called.
hidden.bs.collapse This event is fired when a collapse element has
been hidden from the user (will wait for CSS transitions to
complete).
$('#collapse').on('hidden.bs.collapse', function () {
$(".glyphicon.glyphToChange").removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
}).on('shown.bs.collapse', function () {
$(".glyphicon.glyphToChange").removeClass("glyphicon-chevron-down").addClass("glyphicon-chevron-up");
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="jumbotron ref collapsed" data-toggle="collapse" data-target="#collapse">
<div class="row">
<div class="col-md-11">
<a target="_blank" href="#"><h4 align="center">Click me.</h4></a>
</div>
<div class="col-md-1">
<span class="glyphicon glyphToChange glyphicon-chevron-down">glyph</span>
<div id="collapse" class="collapse">
<p style="margin-top: 75px;" align="center"></p>
</div>

Related

Accordion with one tab always expanded. Bootstrap 5

I have an accordion made with bootstrap 5. How can i make the accordion has always one tab expanded? in other words i dont want tabs to be closed all together, i want one to be open always. How can i do that with plain javascript?
<div class="accordion" id="accordionExample">
<div class="accordion-item">
<h1 class="accordion-header" id="headingOne">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
...
</button>
</h1>
<div id="collapseOne" class="accordion-collapse collapse show" aria-labelledby="headingOne" data-bs-parent="#accordionExample">
<div class="accordion-body">
...
</div>
</div>
</div>
<div class="accordion-item">
<h1 class="accordion-header" id="headingTwo">
<button
class="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
data-bs-target="#collapseTwo"
aria-expanded="false"
aria-controls="collapseTwo"
>
...
</button>
</h1>
<div
id="collapseTwo"
class="accordion-collapse collapse"
aria-labelledby="headingTwo"
data-bs-parent="#accordionExample"
>
<div class="accordion-body">
...
</div>
</div>
</div>
I dont want this to happen....
I struggled with the same problem for a while and was finally able to write a solution for it. I'm not a js master so it's probably not the most elegant solution but it works:
<script>
const accordions = document.querySelectorAll(".accordion-collapse");
let opening = false;
accordions.forEach(function (el) {
el.addEventListener("hide.bs.collapse", (event) => {
if (!opening) {
event.preventDefault();
event.stopPropagation();
} else {
opening = false;
}
});
el.addEventListener("show.bs.collapse", (event) => {
opening = true;
});
});
</script>
Kinda late but it may be useful to others too
It seems you want to achieve the design and layout style of a bootstrap accordion but doesn't require it's functionality. The best way to achieve this is writing static html/css instead of using a bootstrap component which is there for a different cause.
According to your question you are trying to make something similar to this:
This is hard-coded using bootstrap, so it would be just opened forever. Use a png of a down chevron or use this from fontawesome. I just linked to an image from an external source from a google to be quick.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
<title>Hello, world!</title>
</head>
<body>
<div class="acordionThing" style="margin:5rem">
<div class="col d-flex" style="background-color: rgb(185, 185, 185); ">
<div class="col">
<p style=" margin:1rem">
Somekind of a text here.
</p>
</div>
<div style="width:2rem; float:right; margin-right: 2rem;">
<img src="https://img.icons8.com/ios/452/chevron-down.png" style="width: 2rem; margin-top:0.8rem;"">
</div>
</div>
<div class="col d-flex" style="background-color: rgb(218, 218, 218);">
<div class="col">
<p style=" margin:1rem">
Somekind of a text here. Somekind of a text here. Somekind of a text here. Somekind of a text here.
Somekind of a text here. Somekind of a text here. Somekind of a text here. Somekind of a text here.
</p>
</div>
</div>
</div>
<div class="acordionThing" style="margin:5rem">
<div class="col d-flex" style="background-color: rgb(185, 185, 185); ">
<div class="col">
<p style=" margin:1rem">
Somekind of a text here.
</p>
</div>
<div style="width:2rem; float:right; margin-right: 2rem;">
<img src="https://img.icons8.com/ios/452/chevron-down.png" style="width: 2rem; margin-top:0.8rem;"">
</div>
</div>
<div class="col d-flex" style="background-color: rgb(218, 218, 218);">
<div class="col">
<p style=" margin:1rem">
Somekind of a text here. Somekind of a text here. Somekind of a text here. Somekind of a text here.
Somekind of a text here. Somekind of a text here. Somekind of a text here. Somekind of a text here.
</p>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>
</body>
</html>

How do I toggle the content of the other bootstrap buttons?

I'm using bootstrap and scss to create a wordpress page but i'm having some issues trying to create a collapsable content. I have four buttons and I want that only the content of one of them is displayed while the others are collapsed. If I click the second button for example the buttons 1, 3 & 4 should display nothing.
Also I have a active class to show in a clear way which one is pressed that it's not working properly. Any help would be really nice, thanks!
var mainStarter = {
initialize: function() {
this.buttonActive();
this.toggleButton();
},
buttonActive: function() {
$(".btn.btn-bg-md").on("click", function() {
$(this).toggleClass('active');
});
},
toggleButton: function() {
$('.column button').click(function() {
$(".collapse:visible").add($(this).next()).slideToggle();
});
},
$(function() {
mainStarter.initialize();
});
.row {
display: flex;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<!-- Item 1 -->
<div class="column">
<button type="button" class="btn btn-bg-md" data-toggle="collapse" data-target="#btn1" aria-pressed="false" autocomplete="off">
<h6>Day 1</h6>
</button>
</div>
<!-- Item 2 -->
<div class="column">
<button type="button" class="btn btn-bg-md" data-toggle="collapse" data-target="#btn2" aria-pressed="false" autocomplete="off">
<h6>Day 2</h6>
</button>
</div>
<!-- Item 3 -->
<div class="column">
<button type="button" class="btn btn-bg-md" data-toggle="collapse" data-target="#btn3" aria-pressed="false" autocomplete="off">
<h6>Day 3</h6>
</button>
</div>
<!-- Item 4 -->
<div class="column">
<button type="button" class="btn btn-bg-md" data-toggle="collapse" data-target="#btn4" aria-pressed="false" autocomplete="off">
<h6>Day 4</h6>
</button>
</div>
<div class="container">
<div class="collapse" id="btn1">
<h1>Something 1</h1>
</div>
</div>
<div class="container">
<div class="collapse" id="btn2">
<h1>Something 2</h1>
</div>
</div>
<div class="container">
<div class="collapse" id="btn3">
<h1>Something 3</h1>
</div>
</div>
<div class="container">
<div class="collapse" id="btn4">
<h1>Something 4</h1>
</div>
</div>
</div>
I am not really sure what you really want (your message is not that clear). What I understood, is that you want 2 buttons. When you click the first one, it shows the 1st message and hide the second. When you click the second, it shows the second message and hides the first one. If i understood correctly, you could use jquery, using the correct ids on the divs
$("#button1").click(function() {
if ($("#collapsebutton2").is(":visible")) {
$("#collapsebutton2").toggle( "slow", function() {
});
}
$("#collapsebutton1").toggle( "slow", function() {
});
});
$("#button2").click(function() {
$("#collapsebutton2").toggle( "slow", function() {
});
if ($("#collapsebutton2").is(":visible")) {
$("#collapsebutton1").toggle( "slow", function() {
});
}
});

Plus and Minus icons on bootstrap accordion

I'm trying to toggle between plus and minus icon for bootstrap accordion. On default, plus icon is showing. When accordion collapses, it shows the minus icons and hides the plus icon. I don't know if what I'm saying makes sense but it's really basic for some of you. I'm just a beginner.
I've tried doing it with css with :after and content "+" and content "-" but this is not what I want. I need to use font awesome. I've also tried the js way.
<script>
$(document).ready(function(){
// Toggle plus minus icon on show hide of collapse element
$(".collapse").on('show.bs.collapse', function(){
$(this).prev(".card-header").find(".fa").removeClass("fa-plus").addClass("fa-minus");
}).on('hide.bs.collapse', function(){
$(this).prev(".card-header").find(".fa").removeClass("fa-minus").addClass("fa-plus");
});
});
</script>
<body>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Main content -->
<section class="content container-fluid">
<legend><?php echo $header_title; ?></legend>
<br>
<div class="row">
<div class="col-md-12 accordion-container">
<div class="accordion" id="accordionExample">
<div class="card">
<div class="card-header" id="headingTwo">
<h2 class="mb-0" style="margin: 10px !important">
<button id="btnCollapse" class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
<i class="fa fa-plus"></i>
Card Info
</button>
</h2>
</div>
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordionExample">
<div class="card-body">
<!-- SOME CONTENT -->
</div>
</div>
</div>
</div>
</div>
</div>
</section>
I don't know how to check where I went wrong. All I want is to show the plus and minus icon
$(document).ready(function() {
// Toggle plus minus icon on show hide of collapse element
$(".collapse").on('show.bs.collapse', function() {
$(this).prev(".card-header").find(".fa").removeClass("fa-plus").addClass("fa-minus");
}).on('hide.bs.collapse', function() {
$(this).prev(".card-header").find(".fa").removeClass("fa-minus").addClass("fa-plus");
});
});
/*$("#btnCollapse").on("click", function() {
$(".fa-plus").toggleClass("fa-minus");
})
*/
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<body>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Main content -->
<section class="content container-fluid">
<legend>
<?php echo $header_title; ?>
</legend>
<br>
<div class="row">
<div class="col-md-12 accordion-container">
<div class="accordion" id="accordionExample">
<div class="card">
<div class="card-header" id="headingTwo">
<h2 class="mb-0" style="margin: 10px !important">
<button id="btnCollapse" class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
Card Info
<i class="fa fa-plus"></i>
</button>
</h2>
</div>
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordionExample">
<div class="card-body">
<!-- SOME CONTENT -->
</div>
</div>
</div>
</div>
</div>
</div>
</section>
You can use alternate solution as follow:
$(document).ready(function(){
// Add minus icon for collapse element which is open by default
$(".collapse.show").each(function(){
$(this).prev(".card-header").find(".fa").addClass("fa-minus").removeClass("fa-plus");
});
// Toggle plus minus icon on show hide of collapse element
$(".collapse").on('show.bs.collapse', function(){
$(this).prev(".card-header").find(".fa").removeClass("fa-plus").addClass("fa-minus");
}).on('hide.bs.collapse', function(){
$(this).prev(".card-header").find(".fa").removeClass("fa-minus").addClass("fa-plus");
});
});
Alex, your code is working fine. Please check this fiddle.
[https://jsfiddle.net/boilerplate/bootstrap][1]
Please make sure your js code must be written after the jquery.js and bootstrap.js loaded.

JQuery's .next() doesn't seem to work when changing the object the event is bounded

I have this mark up:
<div class="list-group-item participant-main">
<i class="fa fa-chevron-down" id="chevron-for-div" aria-hidden="true"></i>
<div class="row">
<div class="col-sm-8">
<h5 class="list-group-item-heading">A title</h5>
</div>
<div class="col-sm-4 list-group-item-quick-links ">
<a href="#" />
<a href="#" />
</div>
</div>
</div>
<div class='list-group-item hidden-group-item hide'>
<div class="row">
<div class="col-sm-8">
<p class="list-group-item-text">
Some text
</p>
</div>
<div class="col-sm-4">
<p class="list-group-item-text">
More text
</p>
</div>
</div>
</div>
Previously, I was using Jquery to unhide/hide .hidden-group-item when .participant-main was clicked via this code:
$('body').on('click', '.member-main, .participant-main', function() {
if ($(this).next('.hidden-group-item').hasClass('hide')) {
$('.hidden-group-item').addClass('hide');
$(this).next('.hidden-group-item').toggleClass('hide');
}
else {
$(this).next('.hidden-group-item').toggleClass('hide');
}
$('.hidden-form-item').addClass('hide');
});
I'm adding some links to .participant-main so I can't bind a click event to the whole div anymore so the new links work in parallel. I've tried then to bind the click event to particular elements inside the div thus I moved the target class to particular elements like this.
<div class="list-group-item">
<i class="fa fa-chevron-down participant-main" id="chevron-for-div" aria-hidden="true"></i>
<div class="row">
<div class="col-sm-8 participant-main">
<h5 class="list-group-item-heading">A title</h5>
</div>
<div class="col-sm-4 list-group-item-quick-links ">
<a href="#" />
<a href="#" />
</div>
</div>
</div>
I was hoping it would work but it does not.
I don't understand why is this happening and how to solve. As far as I understand .next() grabs the next element that matches the specified selector.
Since you've nested elements you should use stopPropagation() to stop the event from bubbling :
$('body').on('click', '.member-main, .participant-main', function(e) {
e.stopPropagation();
...
});
Hope this helps.

Change icons when toggle

I've this code
jQuery(function($) {
//After it toggle the content with this button
$('.content_toggle').hide();
$('.link-toggle').before('<i class="fa fa-caret-right"></i>');
$(".link-toggle").click(function() {
$(this).toggleClass('active');
$(this).next(".project .content_toggle").slideToggle("slow");
$('.project').find('i').toggleClass('fa-caret-right fa-caret-down');
});
//Let's the magic applies <3
});
i, h4 {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet"/>
<div class="project">
<h4 class="link-toggle">Link 1</h4>
<div id="" class="content_toggle">
<p>Hello world</p>
</div>
</div>
<div class="project">
<h4 class="link-toggle">Link 2</h4>
<div id="" class="content_toggle">
<p>Hello world</p>
</div>
</div>
It almost works, but when I click on a link, all the icons change.
I want that when I click on the first link for example, only its icon change.
The same thing when I click on the second link, only its icon change.
Thanks for you help !
Grab the current element with $(this) and navigate up to the parent with closest()
$(this).closest('.project').find('i').toggleClass('fa-caret-right fa-caret-down');
jQuery(function ($) {
//After it toggle the content with this button
$('.content_toggle').hide();
$('.link-toggle').before('<i class="fa fa-caret-right"></i>');
$(".link-toggle").click(function () {
$(this).toggleClass('active');
$(this).next(".project .content_toggle").slideToggle("slow");
$(this).closest('.project').find('i').toggleClass('fa-caret-right fa-caret-down');
});
//Let's the magic applies <3
});
i, h4 {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet"/>
<div class="project">
<h4 class="link-toggle">Link 1</h4>
<div id="" class="content_toggle"><p>Hello world</p></div>
</div>
<div class="project">
<h4 class="link-toggle">Link 2</h4>
<div id="" class="content_toggle"><p>Hello world</p></div>
</div>
You are toggling the class of all i, You need to toggle the class taking current element in context. So you can use .closest() to navigate to element with project class.
Use
$(this).closest('.project').find('i').toggleClass('fa-caret-right fa-caret-down');
instead of
$('.project').find('i').toggleClass('fa-caret-right fa-caret-down');
jQuery(function($) {
//After it toggle the content with this button
$('.content_toggle').hide();
$('.link-toggle').before('<i class="fa fa-caret-right"></i>');
$(".link-toggle").click(function() {
$(this).toggleClass('active');
$(this).next(".project .content_toggle").slideToggle("slow");
$(this).closest('.project').find('i').toggleClass('fa-caret-right fa-caret-down');
});
});
i,
h4 {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" />
<div class="project">
<h4 class="link-toggle">Link 1</h4>
<div id="" class="content_toggle">
<p>Hello world</p>
</div>
</div>
<div class="project">
<h4 class="link-toggle">Link 2</h4>
<div id="" class="content_toggle">
<p>Hello world</p>
</div>
</div>

Categories