I want to have an accordion inside my dropdown menu. However, when clicking on the accordion to open/close it, the entire dropdown collapses. Instead, I want the dropdown to remain open and the accordion to open/close freely.
Check out a demo here
<div class="btn-group dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu2" data-toggle="dropdown">
Dropdown
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenu2">
<button class="dropdown-item" type="button">Action</button>
<button class="dropdown-item" type="button">Another action</button>
<button class="dropdown-item" type="button">Something else here</button>
<div id="accordion">
<div class="card">
<div class="card-header" id="headingOne">
<h5 class="mb-0">
<button type="button" class="btn btn-link" data-toggle="collapse" data-target="#collapseOne">
Collapsible Test
</button>
</h5>
</div>
<div id="collapseOne" class="collapse" aria-labelledby="headingOne" data-parent="#accordion">
<div class="card-body">
<button class="dropdown-item" type="button">Test</button>
</div>
</div>
</div>
</div>
</div>
</div>
There seem to be many similar questions out there but I cannot find the right solution. A lot of answers suggest using jQuery to solve this issue. Is there a way to do it without?
I believe using data-boundary or data-parent may be the way to do this but I can't figure out how.
You can achieve this by adding an onclick event to the button that prevents the click from propagating down to the dropdown. Then you need to manually handle adding the relevant collapse or collapse.show classes to the accordion content in the onclick function like so:
function toggleAccordion(event) {
event.stopPropagation();
var collapsable = document.getElementById('collapseOne');
var classList = collapsable.classList;
if(classList.contains('collapse')) {
classList.replace('collapse', 'collapse.show');
} else if (classList.contains('collapse.show')) {
classList.replace('collapse.show', 'collapse');
}
}
and the HTML with the click event added:
<div class="btn-group dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu2" data-toggle="dropdown">
Dropdown
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenu2">
<button class="dropdown-item" type="button">Action</button>
<button class="dropdown-item" type="button">Another action</button>
<button class="dropdown-item" type="button">Something else here</button>
<div id="accordion">
<div class="card">
<div class="card-header" id="headingOne">
<h5 class="mb-0">
<button type="button" class="btn btn-link" onclick="toggleAccordion(event)">
Collapsible Test
</button>
</h5>
</div>
<div id="collapseOne" class="collapse" aria-labelledby="headingOne" data-parent="#accordion">
<div class="card-body">
<button class="dropdown-item" type="button">Test</button>
</div>
</div>
</div>
</div>
</div>
</div>
I altered your JSFiddle to show a working solution and you can find it here. Another note, I had to change the JS load type to No wrap - bottom of <head/body> to make this work.
Whilst #Jake has given a valid answer, I found a "hack" of some sorts that lets this work without writing any additional JS.
Simply replace the accordion div with a form tag.
<div class="btn-group dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu2" data-toggle="dropdown">
Dropdown
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenu2">
<button class="dropdown-item" type="button">Action</button>
<button class="dropdown-item" type="button">Another action</button>
<button class="dropdown-item" type="button">Something else here</button>
<form id="accordion">
<div id="headingOne">
<h5 class="mb-0">
<button type="button" class="btn btn-link" data-toggle="collapse" data-target="#collapseOne">
Collapsible Test
</button>
</h5>
</div>
<div id="collapseOne" class="collapse" data-parent="#accordion">
<div class="card-body">
<button class="dropdown-item" type="button">Test</button>
</div>
</div>
</form>
</div>
</div>
Unfortunately, I don't know why this works so I am unable to put the reason in the answer.
Related
I'm very new to angular as i'm leaning it right now in a intnership.
However, i would like to learn how to correctly set a dynamic dropdown in ngBootstap as i'm getting the following error: Error
Here's my HTML:
parent:
<div class="container" id="container">
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" ngbDropdownToggle>
Dropdown button
</button>
<div app-city-details-component *ngFor="let city of cityArray" [city]="city" ngbDropdownMenu>
</div>
</div>
Child:
<div class="container" id="container" ngbDropdownItem>
<button class="button" type="button" (click)="handleClick()">
<p>{{city.name}}</p>
<p>Latitudine: {{latitudine}}</p>
<p>Longitudine: {{longitudine}}</p>
<p>Timezone: {{timezone}}</p>
<div app-show-weather-conditions [weather]="currentRealWeather"></div>
</button>
My app.module.ts:
app.module.ts
What i'm doing wrog?
Try closing your code inside a div with ngbDropdown and wrapping the child inside another div with ngbDropdownMenu.
<div class="container" id="container">
<!-- Add this -->
<div ngbDropdown>
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" ngbDropdownToggle>
Dropdown button
</button>
<!-- Change this -->
<div ngbDropdownMenu>
<app-city-details-component
*ngFor="let city of cityArray" [city]="city">
</app-city-details-component>
</div>
</div>
</div>
I have multiple dropdown buttons with the same class as they were dynamically added to the page. I want to toggle the dropdown on the clicked button and not all.
I am using closest() and find() to do that, but this works only alternatively and not for every button.
For example if I click button 1 it works and not for button 2 and it again works for button 3 and not button 4 and it goes on with dynamic buttons.
$('.btn').click(function() {
$(this).closest('div').find('.dropdown-content').toggleClass('show');
});
.dropdown-content { display: none; }
.dropdown-content.show { display: block; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="dropdown pull-right">
<button class="btn" type="button" data-toggle="dropdown"> <i class="fa fa-ellipsis-v"></i> </button>
<div class="dropdown-content">
// content
</div>
</div>
<div class="dropdown pull-right">
<button class="btn" type="button" data-toggle="dropdown"> <i class="fa fa-ellipsis-v"></i> </button>
<div class="dropdown-content">
// content
</div>
</div>
<div class="dropdown pull-right">
<button class="btn" type="button" data-toggle="dropdown"> <i class="fa fa-ellipsis-v"></i> </button>
<div class="dropdown-content">
// content
</div>
</div>
<div class="dropdown pull-right">
<button class="btn" type="button" data-toggle="dropdown"> <i class="fa fa-ellipsis-v"></i> </button>
<div class="dropdown-content">
// content
</div>
</div>
I have a button called Update which I would like to be disabled until an option is selected from the drop-down menu.
So far I have the button disabled:
$('.btn-update').prop('disabled', true);
This is my markup for the buttons and drop-down menu:
<div class="col-md-12 tableContainer">
<div class="panel-heading import-song-panel text-center">
<div class="panel-title">
<ul class="list-inline">
<li class="pull-right">
<div class="dropdownContainer btn-group text-right">
<button type="button" class="btn btn-primary br2 btn-md fs12 dropdown-toggle table-btn" id="table-actionbtn" data-toggle="dropdown" aria-expanded="false">
Select Status
<span class="caret ml5"></span>
</button>
<ul class="dropdown-menu dropdown-menu-right" role="menu">
<li>
Accept & Send
Accept
Reject
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="col-md-12 text-right">
<div class="panel-heading import-song-panel text-right">
<input type="button" class="btn btn-primary" id="js_CancelForm" value="Cancel" />
<input type="submit" class="btn btn-success btn-update" id="js_SubmitForm" value="Update" />
</div>
</div>
Would anyone be able to show me how I can enable the button only when a status is selcted from the drop-down menu.
You can add a class to the dropdown options and add a click event as well.
like:
$('.optclick').click(function(){
$('.btn-update').prop('disabled', false);
e.preventDefault();
});
https://jsfiddle.net/Lz8sxmqm/10/
You can add an onclick event on options of dropdown.
Accept & Send
and call an function on click event
function enableButton(){
$('.btn-update').prop('disabled', false);
}
I have tries to position the items like:
so the markup after my change is here
<div class="container">
<div class="row">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header page-scroll col-4">
<button type="button" class="navbar-toggle" (click)="isCollapsed = !isCollapsed">
<span class="sr-only">Toggle navigation</span> Menu <i class="fa fa-bars"></i>
</button>
<a class="navbar-brand" href="#/">Home</a>
<a class="navbar-brand" href="#/report">Report</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="searchBox col-4" [collapse]="isCollapsed">
<form class="navbar-form search">
<div class="form-group">
<!--</typeahead>-->
<input [(ngModel)]="country"
[typeahead]="countries"
autocomplete="off"
(typeaheadOnSelect)="countrySelected($event)"
class="form-control searchInput" [ngModelOptions]="{standalone: true}"/>
<div class="btn-group" dropdown>
<button dropdownToggle type="button" class="btn btn-primary dropdown-toggle">
{{selectedSearchType.name}} <span class="caret"></span>
</button>
<ul dropdownMenu class="dropdown-menu" role="menu">
<li *ngFor="let type of searchType; let i = index;" role="menuitem">
<a (click)="onTypeChange(type)" class="dropdown-item cursor-pointer">{{type.name}}</a>
</li>
</ul>
</div>
</div>
</form>
</div>
<div class="col-4">
<button type="button" class="btn btn-primary" (click)="loadFromSheet()">
<span class="glyphicon glyphicon-paste"></span>
Load from sheet
</button>
</div>
</div>
</div>
But it seems like this:
How can I fix this so the "load" button is to the right most?
You can try changing the col-md-4 to col-md-3 or less and manipulate the spacing between the buttons with margin-left property on the Load button. You are probably pushing the button to the next row, so check the paddings and margins on the CSS properties surrounding the other elements if not finding success.
Hope this helps.
I am loading html using javascript call, this html has Bootstrap Collapse.
<li class="dd-item" data-id="home">
<div id="panel1" class="panel panel-default panel-collapsed">
<div class="panel-heading">
<div class="panel-actions">
<a role="button" data-collapse="#panel1" class="btn btn-sm btn-icon">
<i class="icon ion-chevron-down"></i>
</a>
</div>
<h3 class="panel-title">Home</h3>
</div>
<div class="panel-body" style="display: none;">
<p>some text</p>
</div>
</div>
</li>
data-toggle="collapse" and data-target="#id" are what you need to be able your bootstrap will work, data-toggle="collapse" will tell bootstrap for a collapse function while data-target="#text" point to the id of html tag
that will perform toggle collapse.
In you code, replace this line,
<a role="button" data-collapse="#panel1" class="btn btn-sm btn-icon">
with
<a role="button" data-collapse="#panel1" class="btn btn-sm btn-icon" data-toggle="collapse" data-target="#text">
where #text is the div ID. In your
<div class="panel-body" style="display: none;">
remove this inline css style style="display: none;" and put an id attribute id="#text" for example. Look like this,
<div id="text" class="collapse panel-body">
And there you go.