Setting Bootstrap collapse to have element open by default based on condition - ruby-on-rails

I'm working on making an FAQ page and have a bootstrap collapse with the categories of questions as the collapse titles and the questions as the body.
I'm using the same collapse for both the index and question display pages and I am passing a local variable local: { display: boolean } to differentiate.
I loop through the categories collection to make each table row
<% #categories.each_with_index do |category, index| %>
I have conditionals in the class and aria-expanded of the trigger element:
class='<%= "collapsed" if !display || category != #question.category %>'
aria-expanded='<%= category == #question.category %>'
And in the class of the target
class='collapse <%= "show" if display && category == #question.category %>'
The page loads with the correct row open but it doesn't close when triggered.

Everything is described in the Bootstrap documentation
To achieve what you need, you have to:
For buttons/headers:
set data-toggle="collapse"
if the content of the target has to be hidden, then set aria-expanded="false"
if the content of the target has to be displayed, then set aria-expanded="true"
For the targets:
set class="collapse" if the target has to be hidden
set class="collapse show" if the target has to be displayed
Here is an example
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<p>
<a class="btn btn-primary" data-toggle="collapse" href="#multiCollapseExample1" role="button" aria-expanded="false" aria-controls="multiCollapseExample1">Toggle first element</a>
<button class="btn btn-primary collapsed" type="button" data-toggle="collapse" data-target="#multiCollapseExample2" aria-expanded="false" aria-controls="multiCollapseExample2">Toggle second element</button>
</p>
<div class="row">
<div class="col">
<div class="collapse show multi-collapse" id="multiCollapseExample1">
<div class="card card-body">
First element content (displayed by the default)
</div>
</div>
</div>
<div class="col">
<div class="collapse multi-collapse" id="multiCollapseExample2">
<div class="card card-body">
Second element content
</div>
</div>
</div>
</div>

Related

How to create sub menu items in left navigation menu?

I will be creating left vertical (sidebar) navigation menu by referring "Example" in https://getbootstrap.com/docs/5.0/components/accordion/.
Below is the link where sub menu items are present as Subitem 1, Subitem 2, Subitem 3 under item 3 and item 4.
https://www.codeply.com/go/K1gXPZwV59/bootstrap-vertical-sidebar-_-accordion-menu-with-submenus
Could you please help how to create such sub menu items(Subitem 1, Subitem 2, Subitem 3) in the "Example"?
Do you want nested accordions? If so, just nest them. Snippet below uses the "Example" you referred to in your question.
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
<div class="accordion" id="accordionExample">
<div class="accordion-item">
<h2 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"> Accordion Item #1 </button>
</h2>
<div id="collapseOne" class="accordion-collapse collapse" aria-labelledby="headingOne" data-bs-parent="#accordionExample">
<div class="accordion-body">
<strong>This is the first item's accordion body.</strong> It is shown by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the <code>.accordion-body</code>, though the transition does limit overflow. </div>
<div class="accordion" id="accordionExampleTwo">
<div class="accordion-item">
<h2 class="accordion-header" id="headingOneOne">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOneOne" aria-expanded="true" aria-controls="collapseOneOne"> Accordion Item #1-1 </button>
</h2>
<div id="collapseOneOne" class="accordion-collapse collapse" aria-labelledby="headingOneOne" data-bs-parent="#accordionExampleTwo">
<div class="accordion-body">
<strong>This is the first NESTED item's accordion body.</strong> It is shown by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the <code>.accordion-body</code>, though the transition does limit overflow. </div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header" id="headingOneTwo">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOneTwo" aria-expanded="true" aria-controls="collapseOneTwo"> Accordion Item #1-2 </button>
</h2>
<div id="collapseOneTwo" class="accordion-collapse collapse" aria-labelledby="headingOneTwo" data-bs-parent="#accordionExampleTwo">
<div class="accordion-body">
<strong>This is the second NESTED item's accordion body.</strong> It is shown by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the <code>.accordion-body</code>, though the transition does limit overflow. </div>
</div>
</div>
</div>
</div>
</div>
<div class="accordion-item">
<h2 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"> Accordion Item #2 </button>
</h2>
<div id="collapseTwo" class="accordion-collapse collapse" aria-labelledby="headingTwo" data-bs-parent="#accordionExample">
<div class="accordion-body">
<strong>This is the second item's accordion body.</strong> It is hidden by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the <code>.accordion-body</code>, though the transition does limit overflow. </div>
</div>
</div>
</div>
If you want a list group menu inside the accordion:
.accordion-body {
/*padding: 0 !important;*/
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
<!--- Bootstrap Icons -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.10.2/font/bootstrap-icons.css">
<div class="accordion" id="accordionExample">
<div class="accordion-item">
<h2 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">
Accordion Item #1
</button>
</h2>
<div id="collapseOne" class="accordion-collapse collapse" aria-labelledby="headingOne" data-bs-parent="#accordionExample">
<div class="accordion-body">
<div class="list-group">
The current link item <i class="bi bi-caret-down-fill"></i>
<div class="collapse" id="listCollapseOne">
A nested first link item
A nested second link item
A nested third link item
</div>
A second link item
A third link item
A fourth link item
</div>
</div>
</div>
</div>
<div class="accordion-item">
<h2 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">
Accordion Item #2
</button>
</h2>
<div id="collapseTwo" class="accordion-collapse collapse" aria-labelledby="headingTwo" data-bs-parent="#accordionExample">
<div class="accordion-body">
<strong>This is the second item's accordion body.</strong> It is hidden by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing
and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the <code>.accordion-body</code>, though the transition does limit overflow.
</div>
</div>
</div>
</div>

Trigger all bootstrap collapses with jquery at once

Hello I am using bootstrap-5 collapses. I have multiple collapses an I need to trigger them all using jquery(not bootstrap button).Here are my collapses.Here is my code
<p>
<a class="btn btn-primary" data-bs-toggle="collapse" href="#multiCollapseExample1" role="button" aria-expanded="false" aria-controls="multiCollapseExample1">Toggle first element</a>
<button class="btn btn-primary" type="button" data-bs-toggle="collapse" data-bs-target="#multiCollapseExample2" aria-expanded="false" aria-controls="multiCollapseExample2">Toggle second element</button>
<button class="btn btn-primary" type="button" data-bs-toggle="collapse" data-bs-target=".multi-collapse" aria-expanded="false" aria-controls="multiCollapseExample1 multiCollapseExample2">Toggle both elements</button>
</p>
<div class="row">
<div class="col">
<div class="collapse multi-collapse" id="multiCollapseExample1">
<div class="card card-body">
Some placeholder content for the first collapse component of this multi-collapse example. This panel is hidden by default but revealed when the user activates the relevant trigger.
</div>
</div>
</div>
<div class="col">
<div class="collapse multi-collapse" id="multiCollapseExample2">
<div class="card card-body">
Some placeholder content for the second collapse component of this multi-collapse example. This panel is hidden by default but revealed when the user activates the relevant trigger.
</div>
</div>
</div>
</div>

Accordion dropdown selection

I am using the accordion class to display some data in tables. My code loops through all the table rows and assigns them to an accordion dropdown. My problem is when I select one accordion header they all expand/collapse instead of just the one I clicked on.
<div class="accordion" id="qc_inspection">
<div class="accordion-item">
<h1 class="accordion-header">
<button class="accordion-button d-block text-center" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="false" aria-controls="collapseOne">
<h1 class="display-6">{{table['inspection']}}</h1>
</button>
</h1>
<div id="collapseOne" class="accordion-collapse">
<div class="accordion-body">
<input type="text" placeholder="Weight" class="form-control"
value="{{ request.form['weight'] }}"></input>
{{table['min']}} to {{table['max']}} grams
</div>
</div>
</div>
</div>
Code works fine if I create each collapsible row independently and take the for loop out, but the number of rows changes depending on the table selected so that will not work.
assigning a unique value to data-bs-target and the accordion body id worked. it does not like just numeric values so I added "a" in front of the value. See working code below:
<div class="accordion">
<div class="accordion-item">
<h1 class="accordion-header">
<button class="accordion-button d-block text-center" type="button" data-bs-toggle="collapse" data-bs-target="#a{{table['id']}}" aria-expanded="false" aria-controls="collapseOne">
<h1 class="display-6">{{table['inspection']}}</h1>
</button>
</h1>
<div id="a{{table['id']}}" class="accordion-collapse">
<div class="accordion-body">
<input type="text" placeholder="Weight" class="form-control"
value="{{ request.form['weight'] }}"></input>
{{table['min']}} to {{table['max']}} grams
</div>
</div>
</div>
</div>

Material custom icon showing same for each instance

I have an app where I'm using custom svg icons using Materials 'MatIconRegistry'.
The import works fine, but a strange thing is happening when I have multiple icons on a page. For some reason, any icons that following an initial icon end up bing the same as the first, even though they are clearly labeled as another icon.
When I comment out the initial icon, the next instance changes to the one being called by that instance, but then all the following icons then change to that icon.
What could be causing this?
Here is the code:
<mat-sidenav-container>
<mat-sidenav mode="side" opened="true" class="app-sidenav">
<div class="logo-wrapper">
<img
class="menu-logo"
alt="Avocado"
src="./assets/logo.png"
/>
</div>
<div>
<div class="menu-item">
<a
class="menu-button"
routerLink="/"
mat-button
routerLinkActive="active"
[routerLinkActiveOptions]="{ exact: true }"
>
<div>
<mat-icon svgIcon="dashboard"></mat-icon>
</div>
<div class="button-label">
Dashboard
</div>
</a>
</div>
<div class="menu-item">
<a
class="menu-button"
routerLink="/sessions"
mat-button
routerLinkActive="active"
>
<div>
<mat-icon svgIcon="sessions"></mat-icon>
</div>
<div class="button-label">
Sessions
</div>
</a>
</div>
<div class="menu-item">
<a
class="menu-button"
routerLink="/users"
mat-button
routerLinkActive="active"
>
<div>
<mat-icon svgIcon="users"></mat-icon>
</div>
<div class="button-label">
Users
</div>
</a>
</div>
</div>
</mat-sidenav>
<mat-toolbar class="app-toolbar">
<h2 class="page-title">{{pageTitle}}</h2>
</mat-toolbar>
<router-outlet></router-outlet>
</mat-sidenav-container>

How to open same modal with two different links with different behaviour?

I am having a modal that have two divs in it. Now i am willing to open the same modal with two different links.
Here is my modal:
<!-- Modal -->
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<%= link_to "Back","#",class: "btn btn-default",id: "Back-Link",style: "display:none"%>
<%= link_to "Next","#",class: "btn btn-default",id: "Next-Link"%>
<div id="One">
<p>Some text in the modal.</p>
</div>
<div id="Two" style="display:none">
<p>Modal Two.</p>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Following are the links:
<%= link_to "Test","#", 'data-toggle': "modal", 'data-target': "#myModal"%>
<%= link_to "Test1","#", 'data-toggle': "modal", 'data-target': "#myModal"%>
When I click on "Test" Link the modal should open with div id "One". And when i click on "Test1" the modal should open with div id "Two".
can anyone help me? Thank you in advance
Here is a working fiddle.
I made use of the data attributes to store id of div to show inside the modal. Then on click of it, I changed its style from display:none to block.
<div class="modal-body">
<div id="one" class="hide_first">
<p>Some text in the modal.</p>
</div>
<div id="two" class="hide_first">
<p>Modal Two.</p>
</div>
</div>
Open #One
Open #Two
<!-- Storing the id of divs in data-modal-show -->
And write some javascript like this
//classes given to our links
$(".modal-open-links").on("click", function(e){
//First set display:none for all divs
$(".hide_first").css("display", "none");
//hide_first class is on both our divs inside modal body that we want to alternatively show
content_to_show = $(this).attr("data-modal-show");
//the div id we want to show on modal open
//Show the one we clicked
$("#" + content_to_show).css("display", "block");
});

Resources