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.
Related
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>
I am trying to add a search function to a bootstrap accordion that is used for FAQ.
So far, i can't get it to search properly.
JQuery
$(document).ready(function(){
$("#searcher").on("keypress click input", function () {
var val = $(this).val();
if(val.length) {
$(".accordion .card .collapsed").hide().filter(function () {
return $('.card-body', this).text().toLowerCase().indexOf(val.toLowerCase()) > -1;
}).show();
}
else {
$(".accordion .card .collapsed").show();
}
});
});
<div class="search-container">
<input class="input-medium search-query" id="searcher" placeholder="Search">
<button class="btn">Search</button>
</div>
<br>
<div class="row">
<div class="col-sm-12">
<div class="tab-content">
<div id="tab1" class="tab-pane fade show active">
<div class="accordion" id="accordion1">
<div class="card">
<div class="card-header collapsed" id="genOne">
<a href="#collapseOne" data-toggle="collapse" data-target="#collapseOne"
aria-expanded="true" aria-controls="collapseOne">
<p class="mb-0">
Where are you located?
</p>
</a>
</div>
<div id="collapseOne" class="collapse" aria-labelledby="genOne"
data-parent="#accordion1">
<div class="card-body">
<p style="text-align:center; font-size: 16px; ">We are located in , near the downtown area. To learn about local pick
up
options please contact us
at
<br /> support#
or
by phone 616
</p>
That is all of the code im using, if someone can point me in the right direction that would be awesome!
Thank you
So I am trying to create a collapse (accordion) in Bootstrap 4 using Angular. I would love to be able to create almost the entire thing using an ngFor loop.
So far I have this:
<div class="row">
<div class="col-lg-6">
<div id="accordion" role="tablist" aria-multiselectable="true">
<div class="card" *ngFor="let environment of environments; let i = index;">
<div class="card-header" role="tab" id="headingi">
<h5 class="mb-0">
<a data-toggle="collapse" data-parent="#accordion" href="#collapsei" aria-expanded="false" aria-controls="collapsei">
Number: {{i}}
</a>
</h5>
</div>
<div id="collapseOne" class="collapse show" role="tabpanel" aria-labelledby="headingOne">
<div class="card-block">
<div *ngFor="let name of uniqueNames; let j = index" class="card infoBox">
<p>this is accordion {{i}}, section: {{j}}</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
What I am trying to do is use "let i = index" to set the id and class names needed to make the accordion know what to do when certain links are clicked. So ideally the first accordion section would have class and id of collapse0/heading0 and the next would have id and class of collapse1/heading1 etc.
However, the previous code must not be working because all the accordions and their headers show up and do nothing when clicked on. It does generate the correct number, show all the right headers, and the bodies associated with them.
Any help? thanks!
You can do it this way also
id="collapse{{i}}" class="heading{{i}}" attr.aria-controls="heading{{i}}"
and the fact that aria- attributes are being handled another way in angular you have to prefix them with attr.. In your example should that be attr.aria-controls="heading{{i}}".
You just have to databind id:
<div class="card-header" role="tab" [id]="'heading'+i">
<!-- and -->
<div [id]="'collapse' + i" class="collapse show" role="tabpanel" [aria-labelledby]="'heading' + i">
And then you can access your index via i.
*Here is working code with bootstrap 5 accordion with ngFor Angular 12 (dynamic id):
<div class="accordion" id="accordionPanelsStayOpenExample">
<div class="accordion-item">
<h2 class="accordion-header" id="panelsStayOpen-headingOne">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#panelsStayOpen-collapseOne" aria-expanded="true" aria-controls="panelsStayOpen-collapseOne">
Installed Offer Version Details
</button>
</h2>
<div id="panelsStayOpen-collapseOne" class="accordion-collapse collapse show" aria-labelledby="panelsStayOpen-headingOne">
<div class="accordion-body">
<ng-container *ngFor="let lineItem of allLineItems">
<!-- <line-item-detail [lineItem]="lineItem"></line-item-detail>-->
<div class="accordion-item my-4">
<h2 class="accordion-header" id="heading{{lineItem.id}}">
<button class="accordion-button" type="button" data-bs-toggle="collapse" attr.data-bs-target="#collapse{{lineItem.id}}" aria-expanded="true" attr.aria-controls="collapse{{lineItem.id}}">
{{lineItem.productType}} : {{lineItem?.productOffering?.name}}
</button>
</h2>
<div id="collapse{{lineItem.id}}" class="accordion-collapse collapse show" attr.aria-labelledby="heading{{lineItem.id}}">
<div class="accordion-body">
your body text
</div>
</div>
</div>
</ng-container>
</div>
</div>
</div>
</div>
Even you can create sub-component of what is in ngFor like I commented the <line-item-detail></line-item-detail> tag.
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>
I have this template that initially shows:
Sidebar1 - Content - Sidebar2
But when the user is in mobile view, I need to disappear the two sidebars and that this can be opened by a button, one at a time...
Button1 - opens sidebar1 to the right.
Button2 - opens sidebar2 to the left.
Anyone know if this is possible or has it done?
Code
<div class="container">
<div class="row row-offcanvas row-offcanvas-right">
<div class="col-xs-2 col-sm-3 sidebar-offcanvas" id="sidebar" role="navigation">
<div class="list-group">
Link
Link
Link
Link
Link
Link
</div>
</div><!--/span-->
<div class="col-xs-12 col-sm-6">
<p class="pull-left visible-xs">
<button type="button" class="btn btn-primary btn-xs" data-toggle="offcanvas1">
Filters <i class="fa fa-arrow-right"></i>
</button>
</p>
<p class="pull-right visible-xs">
<button type="button" class="btn btn-primary btn-xs" data-toggle="offcanvas">
<i class="fa fa-arrow-left"></i>
Details</button>
</p>
<div class="jumbotron">
<h1>Hello, world!</h1>
<p>This is an example to show the potential of an offcanvas layout pattern in Bootstrap. Try some responsive-range viewport sizes to see it in action.</p>
</div>
</div><!--/span-->
<div class="col-xs-3 col-sm-3 sidebar-offcanvas" id="sidebar" role="navigation">
<div class="list-group">
Link
Link
Link
Link
Link
Link
</div>
</div><!--/span-->
</div><!--/row-->
</div>
Javascript
$('[data-toggle=offcanvas]').click(function () {
$('.row-offcanvas').toggleClass('active');
});
$('[data-toggle=offcanvas1]').click(function () {
$('.row-offcanvas').toggleClass('active');
});
Let's give this a try... I added a new row at the bottom of your current HTML to represent the same exact links that are displayed on the edges but are hidden until a button is toggled. Let's take a look at the HTML first:
HTML
<div class="row">
<div class="col-xs-3 col-sm-3 sidebar-offcanvas hide trial2" id="sidebar" role="navigation">
<div class="list-group"> Link
Link
Link
Link
Link
Link
</div>
</div>
<div class="col-xs-3 col-sm-3 sidebar-offcanvas pull-right hide trial " id="sidebar" role="navigation">
<div class="list-group"> Link
Link
Link
Link
Link
Link
</div>
</div>
</div>
As you can see, I copy and pasted the exact same HTML and added the following classes: hide, trial, trial2
Class hide: This is a built in BootStrap class that hides all content within the specified tag. I toggle this class with jQuery later on.
Class trial/trial2 : This is just a random name I chose to make sure the toggle effect was going to work, you can virtually name it whatever you want, but just make sure you reference the tag.
Let's look at the new jQuery:
jQuery
$('[data-toggle=offcanvas]').click(function () {
$('.trial2').toggleClass('hide');
});
$('[data-toggle=offcanvas1]').click(function () {
$('.trial').toggleClass('hide');
});
It's virtually the same code you had but I have it now toggling the hidden content.
Conclusion:
I added a few other things as well - such as the ability to hide the two side-navigation bars as the screen shrinks to a smaller size. Just take a look at the code I will provide via a JSFiddle and you will understand it a bit better.
DEMO JSFiddle
I fixed like this:
HTML
<div class="row-fluid row-offcanvas row-offcanvas-left">
<div class="row-fluid row-offcanvas row-offcanvas-right">
<div id="filters"></div>
<div id="content">
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<ul class="nav navbar-nav nav-pills">
<li class="visible-xs"><a> <span class="glyphicon glyphicon-filter" data-toggle="offcanvas" data-target=".sidebar-nav"></span> </a></li>
<li class="visible-xs"><a> <span class="glyphicon glyphicon-list-alt" data-toggle="offcanvas1" data-target=".sidebar-nav"></span> </a></li>
</ul>
</div>
</nav>
</div>
<div id="detail"></div>
</div>
JAVASCRIPT
$('[data-toggle=offcanvas]').click(function() {
$('.row-offcanvas-left').toggleClass('active');
});
$('[data-toggle=offcanvasa]').click(function() {
$('.row-offcanvas-right').toggleClass('active');
});